diff options
Diffstat (limited to 'drivers')
214 files changed, 2082 insertions, 1551 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 5207f9e4b44..cbb6f0814ce 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -322,10 +322,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) if (result) return result; - result = acpi_processor_get_platform_limit(pr); - if (result) - return result; - return 0; } diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 36b37d755db..3d54680d033 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1677,8 +1677,6 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) struct acpi_video_device *video_device = data; struct acpi_device *device = NULL; - - printk("video device notify\n"); if (!video_device) return; diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index da21552d2b1..1c94b43d2c9 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -19,6 +19,10 @@ config ATA if ATA +config ATA_NONSTANDARD + bool + default n + config SATA_AHCI tristate "AHCI SATA support" depends on PCI diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b517d249355..48616c6fee9 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -75,6 +75,7 @@ enum { AHCI_CMD_CLR_BUSY = (1 << 10), RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ + RX_FIS_SDB = 0x58, /* offset of SDB FIS data */ RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ board_ahci = 0, @@ -202,6 +203,10 @@ struct ahci_port_priv { dma_addr_t cmd_tbl_dma; void *rx_fis; dma_addr_t rx_fis_dma; + /* for NCQ spurious interrupt analysis */ + int ncq_saw_spurious_sdb_cnt; + unsigned int ncq_saw_d2h:1; + unsigned int ncq_saw_dmas:1; }; static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); @@ -361,7 +366,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */ { PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */ { PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */ - { PCI_VDEVICE(AL, 0x5288), board_ahci }, /* ULi M5288 */ + { PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr }, /* ULi M5288 */ { PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */ { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */ { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ @@ -586,35 +591,18 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap) { u32 cmd, scontrol; - cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; - - if (cap & HOST_CAP_SSC) { - /* enable transitions to slumber mode */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - if ((scontrol & 0x0f00) > 0x100) { - scontrol &= ~0xf00; - writel(scontrol, port_mmio + PORT_SCR_CTL); - } - - /* put device into slumber mode */ - writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD); - - /* wait for the transition to complete */ - ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER, - PORT_CMD_ICC_SLUMBER, 1, 50); - } + if (!(cap & HOST_CAP_SSS)) + return; - /* put device into listen mode */ - if (cap & HOST_CAP_SSS) { - /* first set PxSCTL.DET to 0 */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - scontrol &= ~0xf; - writel(scontrol, port_mmio + PORT_SCR_CTL); + /* put device into listen mode, first set PxSCTL.DET to 0 */ + scontrol = readl(port_mmio + PORT_SCR_CTL); + scontrol &= ~0xf; + writel(scontrol, port_mmio + PORT_SCR_CTL); - /* then set PxCMD.SUD to 0 */ - cmd &= ~PORT_CMD_SPIN_UP; - writel(cmd, port_mmio + PORT_CMD); - } + /* then set PxCMD.SUD to 0 */ + cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; + cmd &= ~PORT_CMD_SPIN_UP; + writel(cmd, port_mmio + PORT_CMD); } static void ahci_init_port(void __iomem *port_mmio, u32 cap, @@ -915,7 +903,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(ap->device, &tf); - tf.command = 0xff; + tf.command = 0x80; ata_tf_to_fis(&tf, d2h_fis, 0); rc = sata_std_hardreset(ap, class); @@ -1126,8 +1114,9 @@ static void ahci_host_intr(struct ata_port *ap) void __iomem *mmio = ap->host->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); struct ata_eh_info *ehi = &ap->eh_info; + struct ahci_port_priv *pp = ap->private_data; u32 status, qc_active; - int rc; + int rc, known_irq = 0; status = readl(port_mmio + PORT_IRQ_STAT); writel(status, port_mmio + PORT_IRQ_STAT); @@ -1154,17 +1143,53 @@ static void ahci_host_intr(struct ata_port *ap) /* hmmm... a spurious interupt */ - /* some devices send D2H reg with I bit set during NCQ command phase */ - if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS)) + /* if !NCQ, ignore. No modern ATA device has broken HSM + * implementation for non-NCQ commands. + */ + if (!ap->sactive) return; - /* ignore interim PIO setup fis interrupts */ - if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS)) - return; + if (status & PORT_IRQ_D2H_REG_FIS) { + if (!pp->ncq_saw_d2h) + ata_port_printk(ap, KERN_INFO, + "D2H reg with I during NCQ, " + "this message won't be printed again\n"); + pp->ncq_saw_d2h = 1; + known_irq = 1; + } + + if (status & PORT_IRQ_DMAS_FIS) { + if (!pp->ncq_saw_dmas) + ata_port_printk(ap, KERN_INFO, + "DMAS FIS during NCQ, " + "this message won't be printed again\n"); + pp->ncq_saw_dmas = 1; + known_irq = 1; + } + + if (status & PORT_IRQ_SDB_FIS && + pp->ncq_saw_spurious_sdb_cnt < 10) { + /* SDB FIS containing spurious completions might be + * dangerous, we need to know more about them. Print + * more of it. + */ + const u32 *f = pp->rx_fis + RX_FIS_SDB; + + ata_port_printk(ap, KERN_INFO, "Spurious SDB FIS during NCQ " + "issue=0x%x SAct=0x%x FIS=%08x:%08x%s\n", + readl(port_mmio + PORT_CMD_ISSUE), + readl(port_mmio + PORT_SCR_ACT), + le32_to_cpu(f[0]), le32_to_cpu(f[1]), + pp->ncq_saw_spurious_sdb_cnt < 10 ? + "" : ", shutting up"); + + pp->ncq_saw_spurious_sdb_cnt++; + known_irq = 1; + } - if (ata_ratelimit()) + if (!known_irq) ata_port_printk(ap, KERN_INFO, "spurious interrupt " - "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", + "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n", status, ap->active_tag, ap->sactive); } @@ -1257,7 +1282,7 @@ static void ahci_thaw(struct ata_port *ap) /* clear IRQ */ tmp = readl(port_mmio + PORT_IRQ_STAT); writel(tmp, port_mmio + PORT_IRQ_STAT); - writel(1 << ap->id, mmio + HOST_IRQ_STAT); + writel(1 << ap->port_no, mmio + HOST_IRQ_STAT); /* turn IRQ back on */ writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 908751d27e7..24af56081b5 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -64,6 +64,7 @@ static void generic_error_handler(struct ata_port *ap) /** * generic_set_mode - mode setting * @ap: interface to set up + * @unused: returned device on error * * Use a non standard set_mode function. We don't want to be tuned. * The BIOS configured everything. Our job is not to fiddle. We @@ -71,7 +72,7 @@ static void generic_error_handler(struct ata_port *ap) * and respect them. */ -static void generic_set_mode(struct ata_port *ap) +static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) { int dma_enabled = 0; int i; @@ -82,7 +83,7 @@ static void generic_set_mode(struct ata_port *ap) for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_enabled(dev)) { + if (ata_dev_ready(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->dma_mode = XFER_MW_DMA_0; @@ -99,6 +100,7 @@ static void generic_set_mode(struct ata_port *ap) } } } + return 0; } static struct scsi_host_template generic_sht = { diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0d51d13b16b..667acd28336 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1037,7 +1037,7 @@ static unsigned int ata_id_xfermask(const u16 *id) * the PIO timing number for the maximum. Turn it into * a mask. */ - u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF; + u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF; if (mode < 5) /* Valid PIO range */ pio_mask = (2 << mode) - 1; else @@ -1250,6 +1250,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, ata_sg_init(qc, sg, n_elem); qc->nsect = buflen / ATA_SECT_SIZE; + qc->nbytes = buflen; } qc->private_data = &wait; @@ -2431,18 +2432,8 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) int i, rc = 0, used_dma = 0, found = 0; /* has private set_mode? */ - if (ap->ops->set_mode) { - /* FIXME: make ->set_mode handle no device case and - * return error code and failing device on failure. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - if (ata_dev_ready(&ap->device[i])) { - ap->ops->set_mode(ap); - break; - } - } - return 0; - } + if (ap->ops->set_mode) + return ap->ops->set_mode(ap, r_failed_dev); /* step 1: calculate xfer_mask */ for (i = 0; i < ATA_MAX_DEVICES; i++) { diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 08ad44b3e48..748435807d6 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1796,7 +1796,7 @@ static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev) *r_failed_dev = dev; DPRINTK("EXIT\n"); - return 0; + return rc; } /** @@ -1979,6 +1979,10 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, ehc->tries[dev->devno] = ATA_EH_DEV_TRIES; + /* collect port action mask recorded in dev actions */ + ehc->i.action |= ehc->i.dev_action[i] & ~ATA_EH_PERDEV_MASK; + ehc->i.dev_action[i] &= ATA_EH_PERDEV_MASK; + /* process hotplug request */ if (dev->flags & ATA_DFLAG_DETACH) ata_eh_detach_dev(dev); diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 836947da5b1..73902d33576 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -273,8 +273,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) { int rc = 0; u8 scsi_cmd[MAX_COMMAND_SIZE]; - u8 args[7]; - struct scsi_sense_hdr sshdr; + u8 args[7], *sensebuf = NULL; + int cmd_result; if (arg == NULL) return -EINVAL; @@ -282,10 +282,14 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) if (copy_from_user(args, arg, sizeof(args))) return -EFAULT; + sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); + if (!sensebuf) + return -ENOMEM; + memset(scsi_cmd, 0, sizeof(scsi_cmd)); scsi_cmd[0] = ATA_16; scsi_cmd[1] = (3 << 1); /* Non-data */ - /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ + scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */ scsi_cmd[4] = args[1]; scsi_cmd[6] = args[2]; scsi_cmd[8] = args[3]; @@ -295,11 +299,46 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) /* Good values for timeout and retries? Values below from scsi_ioctl_send_command() for default case... */ - if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, - (10*HZ), 5)) + cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0, + sensebuf, (10*HZ), 5, 0); + + if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ + u8 *desc = sensebuf + 8; + cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */ + + /* If we set cc then ATA pass-through will cause a + * check condition even if no error. Filter that. */ + if (cmd_result & SAM_STAT_CHECK_CONDITION) { + struct scsi_sense_hdr sshdr; + scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, + &sshdr); + if (sshdr.sense_key==0 && + sshdr.asc==0 && sshdr.ascq==0) + cmd_result &= ~SAM_STAT_CHECK_CONDITION; + } + + /* Send userspace ATA registers */ + if (sensebuf[0] == 0x72 && /* format is "descriptor" */ + desc[0] == 0x09) {/* code is "ATA Descriptor" */ + args[0] = desc[13]; /* status */ + args[1] = desc[3]; /* error */ + args[2] = desc[5]; /* sector count (0:7) */ + args[3] = desc[7]; /* lbal */ + args[4] = desc[9]; /* lbam */ + args[5] = desc[11]; /* lbah */ + args[6] = desc[12]; /* select */ + if (copy_to_user(arg, args, sizeof(args))) + rc = -EFAULT; + } + } + + if (cmd_result) { rc = -EIO; + goto error; + } - /* Need code to retrieve data from check condition? */ + error: + kfree(sensebuf); return rc; } @@ -372,7 +411,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, if (cmd->use_sg) { qc->__sg = (struct scatterlist *) cmd->request_buffer; qc->n_elem = cmd->use_sg; - } else { + } else if (cmd->request_bufflen) { qc->__sg = &qc->sgent; qc->n_elem = 1; } @@ -983,11 +1022,10 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) } tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ - } else { - tf->nsect = 0; /* time period value (0 implies now) */ - tf->command = ATA_CMD_STANDBY; - /* Consider: ATA STANDBY IMMEDIATE command */ - } + } else + /* Issue ATA STANDBY IMMEDIATE command */ + tf->command = ATA_CMD_STANDBYNOW1; + /* * Standby and Idle condition timers could be implemented but that * would require libata to implement the Power condition mode page diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 623cec914c9..12c88c58803 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -827,7 +827,8 @@ void ata_bmdma_error_handler(struct ata_port *ap) */ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) { - ata_bmdma_stop(qc); + if (qc->ap->ioaddr.bmdma_addr) + ata_bmdma_stop(qc); } #ifdef CONFIG_PCI @@ -870,7 +871,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; bmdma = pci_resource_start(pdev, 4); if (bmdma) { - if (inb(bmdma + 2) & 0x80) + if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } @@ -886,7 +888,8 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int bmdma = pci_resource_start(pdev, 4); if (bmdma) { bmdma += 8; - if(inb(bmdma + 2) & 0x80) + if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } @@ -914,13 +917,14 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->irq_flags = IRQF_SHARED; if (port_mask & ATA_PORT_PRIMARY) { - probe_ent->irq = ATA_PRIMARY_IRQ; + probe_ent->irq = ATA_PRIMARY_IRQ(pdev); probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; probe_ent->port[0].altstatus_addr = probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; if (bmdma) { probe_ent->port[0].bmdma_addr = bmdma; - if (inb(bmdma + 2) & 0x80) + if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 2) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[0]); @@ -929,15 +933,16 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, if (port_mask & ATA_PORT_SECONDARY) { if (probe_ent->irq) - probe_ent->irq2 = ATA_SECONDARY_IRQ; + probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev); else - probe_ent->irq = ATA_SECONDARY_IRQ; + probe_ent->irq = ATA_SECONDARY_IRQ(pdev); probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; probe_ent->port[1].altstatus_addr = probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; if (bmdma) { probe_ent->port[1].bmdma_addr = bmdma + 8; - if (inb(bmdma + 10) & 0x80) + if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) && + (inb(bmdma + 10) & 0x80)) probe_ent->_host_flags |= ATA_HOST_SIMPLEX; } ata_std_ports(&probe_ent->port[1]); diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 6f6672c5513..504e1dbfffd 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -36,15 +36,22 @@ enum { static int atiixp_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - static struct pci_bits atiixp_enable_bits[] = { + static const struct pci_bits atiixp_enable_bits[] = { { 0x48, 1, 0x01, 0x00 }, { 0x48, 1, 0x08, 0x00 } }; + u8 udma; if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) return -ENOENT; - ap->cbl = ATA_CBL_PATA80; + /* Hack from drivers/ide/pci. Really we want to know how to do the + raw detection not play follow the bios mode guess */ + pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); + if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40) + ap->cbl = ATA_CBL_PATA80; + else + ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 15841a56369..449162cbf93 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -197,7 +197,7 @@ static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev) static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) { static const u8 udma_data[] = { - 0x31, 0x21, 0x11, 0x25, 0x15, 0x05 + 0x30, 0x20, 0x10, 0x20, 0x10, 0x00 }; static const u8 mwdma_data[] = { 0x30, 0x20, 0x10 @@ -213,12 +213,21 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev) pci_read_config_byte(pdev, pciD, ®D); pci_read_config_byte(pdev, pciU, ®U); - regD &= ~(0x20 << shift); - regU &= ~(0x35 << shift); + /* DMA bits off */ + regD &= ~(0x20 << adev->devno); + /* DMA control bits */ + regU &= ~(0x30 << shift); + /* DMA timing bits */ + regU &= ~(0x05 << adev->devno); - if (adev->dma_mode >= XFER_UDMA_0) + if (adev->dma_mode >= XFER_UDMA_0) { + /* Merge thge timing value */ regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift; - else + /* Merge the control bits */ + regU |= 1 << adev->devno; /* UDMA on */ + if (adev->dma_mode > 2) /* 15nS timing */ + regU |= 4 << adev->devno; + } else regD |= mwdma_data[adev->dma_mode - XFER_MW_DMA_0] << shift; regD |= 0x20 << adev->devno; @@ -239,8 +248,8 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 dma_intr; - int dma_reg = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; - int dma_mask = ap->port_no ? ARTTIM2 : CFR; + int dma_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0; + int dma_reg = ap->port_no ? ARTTIM2 : CFR; ata_bmdma_stop(qc); diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index f6817b4093a..886fab9aa62 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -25,7 +25,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.3.2" enum { HPT_PCI_FAST = (1 << 31), @@ -297,11 +297,11 @@ static int hpt3x2n_pair_idle(struct ata_port *ap) return 0; } -static int hpt3x2n_use_dpll(struct ata_port *ap, int reading) +static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) { long flags = (long)ap->host->private_data; /* See if we should use the DPLL */ - if (reading == 0) + if (writing) return USE_DPLL; /* Needed for write */ if (flags & PCI66) return USE_DPLL; /* Needed at 66Mhz */ diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 0b56ff3d1cf..e8afd486434 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -476,6 +476,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) /** * it821x_smart_set_mode - mode setting * @ap: interface to set up + * @unused: device that failed (error only) * * Use a non standard set_mode function. We don't want to be tuned. * The BIOS configured everything. Our job is not to fiddle. We @@ -483,7 +484,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc) * and respect them. */ -static void it821x_smart_set_mode(struct ata_port *ap) +static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused) { int dma_enabled = 0; int i; @@ -512,6 +513,7 @@ static void it821x_smart_set_mode(struct ata_port *ap) } } } + return 0; } /** diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index cb8924109f5..23b8aab3ebd 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -23,9 +23,9 @@ #include <scsi/scsi_host.h> #define DRV_NAME "pata_ixp4xx_cf" -#define DRV_VERSION "0.1.1" +#define DRV_VERSION "0.1.1ac1" -static void ixp4xx_set_mode(struct ata_port *ap) +static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev) { int i; @@ -38,6 +38,7 @@ static void ixp4xx_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static void ixp4xx_phy_reset(struct ata_port *ap) diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 2d661cb4df3..d50264af284 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -204,20 +204,12 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i u32 reg; - if (id->driver_data != 368) { - /* Put the controller into AHCI mode in case the AHCI driver - has not yet been loaded. This can be done with either - function present */ + /* PATA controller is fn 1, AHCI is fn 0 */ + if (id->driver_data != 368 && PCI_FUNC(pdev->devfn) != 1) + return -ENODEV; - /* FIXME: We may want a way to override this in future */ - pci_write_config_byte(pdev, 0x41, 0xa1); - - /* PATA controller is fn 1, AHCI is fn 0 */ - if (PCI_FUNC(pdev->devfn) != 1) - return -ENODEV; - } - if ( id->driver_data == 365 || id->driver_data == 366) { - /* The 365/66 have two PATA channels, redirect the second */ + /* The 365/66 have two PATA channels, redirect the second */ + if (id->driver_data == 365 || id->driver_data == 366) { pci_read_config_dword(pdev, 0x80, ®); reg |= (1 << 24); /* IDE1 to PATA IDE secondary */ pci_write_config_dword(pdev, 0x80, reg); diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index e7bf9d89c8e..581cb33c6f4 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -96,6 +96,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ /** * legacy_set_mode - mode setting * @ap: IDE interface + * @unused: Device that failed when error is returned * * Use a non standard set_mode function. We don't want to be tuned. * @@ -105,7 +106,7 @@ static int pio_mask = 0x1F; /* PIO range for autospeed devices */ * expand on this as per hdparm in the base kernel. */ -static void legacy_set_mode(struct ata_port *ap) +static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; @@ -118,6 +119,7 @@ static void legacy_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static struct scsi_host_template legacy_sht = { diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 443b1d85c6c..40ae11cbfda 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -30,7 +30,7 @@ static int pio_mask = 1; * Provide our own set_mode() as we don't want to change anything that has * already been configured.. */ -static void pata_platform_set_mode(struct ata_port *ap) +static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; @@ -44,6 +44,7 @@ static void pata_platform_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } static void pata_platform_host_stop(struct ata_host *host) diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c index adf4cc134f2..cec0729225e 100644 --- a/drivers/ata/pata_rz1000.c +++ b/drivers/ata/pata_rz1000.c @@ -52,19 +52,20 @@ static void rz1000_error_handler(struct ata_port *ap) /** * rz1000_set_mode - mode setting function * @ap: ATA interface + * @unused: returned device on set_mode failure * * Use a non standard set_mode function. We don't want to be tuned. We * would prefer to be BIOS generic but for the fact our hardware is * whacked out. */ -static void rz1000_set_mode(struct ata_port *ap) +static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused) { int i; for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_enabled(dev)) { + if (ata_dev_ready(dev)) { /* We don't really care */ dev->pio_mode = XFER_PIO_0; dev->xfer_mode = XFER_PIO_0; @@ -72,6 +73,7 @@ static void rz1000_set_mode(struct ata_port *ap) dev->flags |= ATA_DFLAG_PIO; } } + return 0; } diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index 32cf0bfa892..e8dfd8fc3ff 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -135,7 +135,7 @@ static void sil680_error_handler(struct ata_port *ap) static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev) { static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 }; - static u16 speed_t[5] = { 0x328A, 0x1281, 0x1281, 0x10C3, 0x10C1 }; + static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 }; unsigned long tfaddr = sil680_selreg(ap, 0x02); unsigned long addr = sil680_seldev(ap, adev, 0x04); diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index f0d4f7e9ed3..f0b6c3b7142 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -23,6 +23,7 @@ * VIA VT8233c - UDMA100 * VIA VT8235 - UDMA133 * VIA VT8237 - UDMA133 + * VIA VT8237S - UDMA133 * VIA VT8251 - UDMA133 * * Most registers remain compatible across chips. Others start reserved @@ -61,7 +62,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_via" -#define DRV_VERSION "0.2.0" +#define DRV_VERSION "0.2.1" /* * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx @@ -95,6 +96,7 @@ static const struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES}, diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 1b8e0eb9e03..aae0b5201c1 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -523,8 +523,7 @@ static const struct ata_port_info mv_port_info[] = { }, { /* chip_7042 */ .sht = &mv_sht, - .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | - MV_FLAG_DUAL_HC), + .flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &mv_iie_ops, @@ -545,6 +544,8 @@ static const struct pci_device_id mv_pci_tbl[] = { { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, + { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, + { } /* terminate list */ }; diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index f6d498e1cf8..f7a963eb1f0 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -700,7 +700,6 @@ static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) static int nv_host_intr(struct ata_port *ap, u8 irq_stat) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); - int handled; /* freeze if hotplugged */ if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) { @@ -719,13 +718,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat) } /* handle interrupt */ - handled = ata_host_intr(ap, qc); - if (unlikely(!handled)) { - /* spurious, clear it */ - ata_check_status(ap); - } - - return 1; + return ata_host_intr(ap, qc); } static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) @@ -752,6 +745,11 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) { u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804) >> (NV_INT_PORT_SHIFT * i); + if(ata_tag_valid(ap->active_tag)) + /** NV_INT_DEV indication seems unreliable at times + at least in ADMA mode. Force it on always when a + command is active, to prevent losing interrupts. */ + irq_stat |= NV_INT_DEV; handled += nv_host_intr(ap, irq_stat); continue; } diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index 5c603ca3a50..a43aec62d50 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -128,7 +128,8 @@ static const struct ata_port_operations uli_ops = { static struct ata_port_info uli_port_info = { .sht = &uli_sht, - .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_IGN_SIMPLEX, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &uli_ops, diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 1c7f19aecc2..d3d5c0d5703 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -74,9 +74,11 @@ enum { static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static void svia_noop_freeze(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { + { PCI_VDEVICE(VIA, 0x5337), vt6420 }, { PCI_VDEVICE(VIA, 0x0591), vt6420 }, { PCI_VDEVICE(VIA, 0x3149), vt6420 }, { PCI_VDEVICE(VIA, 0x3249), vt6421 }, @@ -127,7 +129,7 @@ static const struct ata_port_operations vt6420_sata_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - .freeze = ata_bmdma_freeze, + .freeze = svia_noop_freeze, .thaw = ata_bmdma_thaw, .error_handler = vt6420_error_handler, .post_internal_cmd = ata_bmdma_post_internal_cmd, @@ -203,6 +205,15 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); } +static void svia_noop_freeze(struct ata_port *ap) +{ + /* Some VIA controllers choke if ATA_NIEN is manipulated in + * certain way. Leave it alone and just clear pending IRQ. + */ + ata_chk_status(ap); + ata_bmdma_irq_clear(ap); +} + /** * vt6420_prereset - prereset for vt6420 * @ap: target ATA port diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 4dc10105d61..f96446c358b 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -1845,7 +1845,7 @@ static u16 __devinit read_bia (const hrz_dev * dev, u16 addr) /********** initialise a card **********/ -static int __init hrz_init (hrz_dev * dev) { +static int __devinit hrz_init (hrz_dev * dev) { int onefivefive; u16 chan; diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index 51d0d562d01..c85c8cadb6d 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -101,6 +101,11 @@ static int amd_create_gatt_pages(int nr_tables) for (i = 0; i < nr_tables; i++) { entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL); if (entry == NULL) { + while (i > 0) { + kfree(tables[i-1]); + i--; + } + kfree(tables); retval = -ENOMEM; break; } diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 979300405c0..93d2209fee4 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -655,7 +655,7 @@ static struct pci_device_id agp_amd64_pci_table[] = { .class = (PCI_CLASS_BRIDGE_HOST << 8), .class_mask = ~0, .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_DEVICE_ID_VIA_K8M890CE, + .device = PCI_DEVICE_ID_VIA_VT3336, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index f244c668273..9987dc2e0c3 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -41,18 +41,18 @@ static struct gatt_mask ati_generic_masks[] = }; -typedef struct _ati_page_map { +struct ati_page_map { unsigned long *real; unsigned long __iomem *remapped; -} ati_page_map; +}; static struct _ati_generic_private { volatile u8 __iomem *registers; - ati_page_map **gatt_pages; + struct ati_page_map **gatt_pages; int num_tables; } ati_generic_private; -static int ati_create_page_map(ati_page_map *page_map) +static int ati_create_page_map(struct ati_page_map *page_map) { int i, err = 0; @@ -82,7 +82,7 @@ static int ati_create_page_map(ati_page_map *page_map) } -static void ati_free_page_map(ati_page_map *page_map) +static void ati_free_page_map(struct ati_page_map *page_map) { unmap_page_from_agp(virt_to_page(page_map->real)); iounmap(page_map->remapped); @@ -94,8 +94,8 @@ static void ati_free_page_map(ati_page_map *page_map) static void ati_free_gatt_pages(void) { int i; - ati_page_map **tables; - ati_page_map *entry; + struct ati_page_map **tables; + struct ati_page_map *entry; tables = ati_generic_private.gatt_pages; for (i = 0; i < ati_generic_private.num_tables; i++) { @@ -112,30 +112,30 @@ static void ati_free_gatt_pages(void) static int ati_create_gatt_pages(int nr_tables) { - ati_page_map **tables; - ati_page_map *entry; + struct ati_page_map **tables; + struct ati_page_map *entry; int retval = 0; int i; - tables = kzalloc((nr_tables + 1) * sizeof(ati_page_map *),GFP_KERNEL); + tables = kzalloc((nr_tables + 1) * sizeof(struct ati_page_map *),GFP_KERNEL); if (tables == NULL) return -ENOMEM; for (i = 0; i < nr_tables; i++) { - entry = kzalloc(sizeof(ati_page_map), GFP_KERNEL); + entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL); if (entry == NULL) { - while (i>0) { - kfree (tables[i-1]); + while (i > 0) { + kfree(tables[i-1]); i--; } - kfree (tables); - tables = NULL; + kfree(tables); retval = -ENOMEM; break; } tables[i] = entry; retval = ati_create_page_map(entry); - if (retval != 0) break; + if (retval != 0) + break; } ati_generic_private.num_tables = nr_tables; ati_generic_private.gatt_pages = tables; @@ -340,7 +340,7 @@ static int ati_remove_memory(struct agp_memory * mem, off_t pg_start, static int ati_create_gatt_table(struct agp_bridge_data *bridge) { struct aper_size_info_lvl2 *value; - ati_page_map page_dir; + struct ati_page_map page_dir; unsigned long addr; int retval; u32 temp; @@ -400,7 +400,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) static int ati_free_gatt_table(struct agp_bridge_data *bridge) { - ati_page_map page_dir; + struct ati_page_map page_dir; page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table; diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index ab0a9c0ad7c..a3011de51f7 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1955,6 +1955,15 @@ static int agp_intel_resume(struct pci_dev *pdev) pci_restore_state(pdev); + /* We should restore our graphics device's config space, + * as host bridge (00:00) resumes before graphics device (02:00), + * then our access to its pci space can work right. + */ + if (intel_i810_private.i810_dev) + pci_restore_state(intel_i810_private.i810_dev); + if (intel_i830_private.i830_dev) + pci_restore_state(intel_i830_private.i830_dev); + if (bridge->driver == &intel_generic_driver) intel_configure(); else if (bridge->driver == &intel_850_driver) diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index c149ac9ce9a..2ded7a280d7 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -380,9 +380,23 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata = /* P4M800CE */ { .device_id = PCI_DEVICE_ID_VIA_P4M800CE, - .chipset_name = "P4M800CE", + .chipset_name = "VT3314", + }, + /* CX700 */ + { + .device_id = PCI_DEVICE_ID_VIA_CX700, + .chipset_name = "CX700", + }, + /* VT3336 */ + { + .device_id = PCI_DEVICE_ID_VIA_VT3336, + .chipset_name = "VT3336", + }, + /* P4M890 */ + { + .device_id = PCI_DEVICE_ID_VIA_P4M890, + .chipset_name = "P4M890", }, - { }, /* dummy final entry, always present */ }; @@ -524,6 +538,9 @@ static const struct pci_device_id agp_via_pci_table[] = { ID(PCI_DEVICE_ID_VIA_83_87XX_1), ID(PCI_DEVICE_ID_VIA_3296_0), ID(PCI_DEVICE_ID_VIA_P4M800CE), + ID(PCI_DEVICE_ID_VIA_CX700), + ID(PCI_DEVICE_ID_VIA_VT3336), + ID(PCI_DEVICE_ID_VIA_P4M890), { } }; diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 4e4691a5389..53582b53da9 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -3649,8 +3649,6 @@ static void ipmi_timeout_handler(long timeout_period) unsigned long flags; int i; - INIT_LIST_HEAD(&timeouts); - rcu_read_lock(); list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { /* See if any waiting messages need to be processed. */ @@ -3671,6 +3669,7 @@ static void ipmi_timeout_handler(long timeout_period) /* Go through the seq table and find any messages that have timed out, putting them in the timeouts list. */ + INIT_LIST_HEAD(&timeouts); spin_lock_irqsave(&intf->seq_lock, flags); for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) check_msg_timeout(intf, &(intf->seq_table[i]), diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 4f1813e0475..f5c160caf9f 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -293,8 +293,8 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma) { unsigned long pfn; - /* Turn a pfn offset into an absolute pfn */ - pfn = PFN_DOWN(virt_to_phys((void *)PAGE_OFFSET)) + vma->vm_pgoff; + /* Turn a kernel-virtual address into a physical page frame */ + pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT; /* * RED-PEN: on some architectures there is more mapped memory diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 13935235e06..7fd3cd5ddf2 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -215,7 +215,7 @@ static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty) } static struct sysrq_key_op sysrq_showstate_blocked_op = { .handler = sysrq_handle_showstate_blocked, - .help_msg = "showBlockedTasks", + .help_msg = "shoW-blocked-tasks", .action_msg = "Show Blocked State", .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -315,15 +315,16 @@ static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_loglevel_op, /* 9 */ /* - * Don't use for system provided sysrqs, it is handled specially on - * sparc and will never arrive + * a: Don't use for system provided sysrqs, it is handled specially on + * sparc and will never arrive. */ NULL, /* a */ &sysrq_reboot_op, /* b */ - &sysrq_crashdump_op, /* c */ + &sysrq_crashdump_op, /* c & ibm_emac driver debug */ &sysrq_showlocks_op, /* d */ &sysrq_term_op, /* e */ &sysrq_moom_op, /* f */ + /* g: May be registered by ppc for kgdb */ NULL, /* g */ NULL, /* h */ &sysrq_kill_op, /* i */ @@ -332,18 +333,19 @@ static struct sysrq_key_op *sysrq_key_table[36] = { NULL, /* l */ &sysrq_showmem_op, /* m */ &sysrq_unrt_op, /* n */ - /* This will often be registered as 'Off' at init time */ + /* o: This will often be registered as 'Off' at init time */ NULL, /* o */ &sysrq_showregs_op, /* p */ NULL, /* q */ - &sysrq_unraw_op, /* r */ + &sysrq_unraw_op, /* r */ &sysrq_sync_op, /* s */ &sysrq_showstate_op, /* t */ &sysrq_mountro_op, /* u */ - /* May be assigned at init time by SMP VOYAGER */ + /* v: May be registered at init time by SMP VOYAGER */ NULL, /* v */ - NULL, /* w */ - &sysrq_showstate_blocked_op, /* x */ + &sysrq_showstate_blocked_op, /* w */ + /* x: May be registered on ppc/powerpc for xmon */ + NULL, /* x */ NULL, /* y */ NULL /* z */ }; diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 448d5083c38..4fac2bdf621 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -186,6 +186,7 @@ static int got_event; /* if events processing have been done */ static void switchover_timeout(unsigned long data); static struct timer_list switchover_timer = TIMER_INITIALIZER(switchover_timeout , 0, 0); +static unsigned long tlclk_timer_data; static struct tlclk_alarms *alarm_events; @@ -197,10 +198,19 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id); static DECLARE_WAIT_QUEUE_HEAD(wq); +static unsigned long useflags; +static DEFINE_MUTEX(tlclk_mutex); + static int tlclk_open(struct inode *inode, struct file *filp) { int result; + if (test_and_set_bit(0, &useflags)) + return -EBUSY; + /* this legacy device is always one per system and it doesn't + * know how to handle multiple concurrent clients. + */ + /* Make sure there is no interrupt pending while * initialising interrupt handler */ inb(TLCLK_REG6); @@ -221,6 +231,7 @@ static int tlclk_open(struct inode *inode, struct file *filp) static int tlclk_release(struct inode *inode, struct file *filp) { free_irq(telclk_interrupt, tlclk_interrupt); + clear_bit(0, &useflags); return 0; } @@ -230,26 +241,25 @@ static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count, { if (count < sizeof(struct tlclk_alarms)) return -EIO; + if (mutex_lock_interruptible(&tlclk_mutex)) + return -EINTR; + wait_event_interruptible(wq, got_event); - if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) + if (copy_to_user(buf, alarm_events, sizeof(struct tlclk_alarms))) { + mutex_unlock(&tlclk_mutex); return -EFAULT; + } memset(alarm_events, 0, sizeof(struct tlclk_alarms)); got_event = 0; + mutex_unlock(&tlclk_mutex); return sizeof(struct tlclk_alarms); } -static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count, - loff_t *f_pos) -{ - return 0; -} - static const struct file_operations tlclk_fops = { .read = tlclk_read, - .write = tlclk_write, .open = tlclk_open, .release = tlclk_release, @@ -540,7 +550,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d, SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7); switch (val) { case CLK_8_592MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); + SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); break; case CLK_11_184MHz: SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); @@ -549,7 +559,7 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d, SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); break; case CLK_44_736MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); + SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); break; } } else @@ -839,11 +849,13 @@ static void __exit tlclk_cleanup(void) static void switchover_timeout(unsigned long data) { - if ((data & 1)) { - if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) + unsigned long flags = *(unsigned long *) data; + + if ((flags & 1)) { + if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) alarm_events->switchover_primary++; } else { - if ((inb(TLCLK_REG1) & 0x08) != (data & 0x08)) + if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) alarm_events->switchover_secondary++; } @@ -901,8 +913,9 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id) /* TIMEOUT in ~10ms */ switchover_timer.expires = jiffies + msecs_to_jiffies(10); - switchover_timer.data = inb(TLCLK_REG1); - add_timer(&switchover_timer); + tlclk_timer_data = inb(TLCLK_REG1); + switchover_timer.data = (unsigned long) &tlclk_timer_data; + mod_timer(&switchover_timer, switchover_timer.expires); } else { got_event = 1; wake_up(&wq); diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index a744dad9cf4..0cea8d4907d 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c @@ -3,7 +3,7 @@ * * Copyright (C) 2002 MontaVista Software Inc. * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> - * Copyright (C) 2003-2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> + * Copyright (C) 2003-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> * * 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 @@ -125,30 +125,17 @@ static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) return data; } -static unsigned int startup_giuint_low_irq(unsigned int irq) +static void ack_giuint_low(unsigned int irq) { - unsigned int pin; - - pin = GPIO_PIN_OF_IRQ(irq); - giu_write(GIUINTSTATL, 1 << pin); - giu_set(GIUINTENL, 1 << pin); - - return 0; + giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(irq)); } -static void shutdown_giuint_low_irq(unsigned int irq) +static void mask_giuint_low(unsigned int irq) { giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); } -static void enable_giuint_low_irq(unsigned int irq) -{ - giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); -} - -#define disable_giuint_low_irq shutdown_giuint_low_irq - -static void ack_giuint_low_irq(unsigned int irq) +static void mask_ack_giuint_low(unsigned int irq) { unsigned int pin; @@ -157,46 +144,30 @@ static void ack_giuint_low_irq(unsigned int irq) giu_write(GIUINTSTATL, 1 << pin); } -static void end_giuint_low_irq(unsigned int irq) +static void unmask_giuint_low(unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); + giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); } -static struct hw_interrupt_type giuint_low_irq_type = { - .typename = "GIUINTL", - .startup = startup_giuint_low_irq, - .shutdown = shutdown_giuint_low_irq, - .enable = enable_giuint_low_irq, - .disable = disable_giuint_low_irq, - .ack = ack_giuint_low_irq, - .end = end_giuint_low_irq, +static struct irq_chip giuint_low_irq_chip = { + .name = "GIUINTL", + .ack = ack_giuint_low, + .mask = mask_giuint_low, + .mask_ack = mask_ack_giuint_low, + .unmask = unmask_giuint_low, }; -static unsigned int startup_giuint_high_irq(unsigned int irq) +static void ack_giuint_high(unsigned int irq) { - unsigned int pin; - - pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; - giu_write(GIUINTSTATH, 1 << pin); - giu_set(GIUINTENH, 1 << pin); - - return 0; + giu_write(GIUINTSTATH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); } -static void shutdown_giuint_high_irq(unsigned int irq) +static void mask_giuint_high(unsigned int irq) { giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); } -static void enable_giuint_high_irq(unsigned int irq) -{ - giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); -} - -#define disable_giuint_high_irq shutdown_giuint_high_irq - -static void ack_giuint_high_irq(unsigned int irq) +static void mask_ack_giuint_high(unsigned int irq) { unsigned int pin; @@ -205,20 +176,17 @@ static void ack_giuint_high_irq(unsigned int irq) giu_write(GIUINTSTATH, 1 << pin); } -static void end_giuint_high_irq(unsigned int irq) +static void unmask_giuint_high(unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); + giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); } -static struct hw_interrupt_type giuint_high_irq_type = { - .typename = "GIUINTH", - .startup = startup_giuint_high_irq, - .shutdown = shutdown_giuint_high_irq, - .enable = enable_giuint_high_irq, - .disable = disable_giuint_high_irq, - .ack = ack_giuint_high_irq, - .end = end_giuint_high_irq, +static struct irq_chip giuint_high_irq_chip = { + .name = "GIUINTH", + .ack = ack_giuint_high, + .mask = mask_giuint_high, + .mask_ack = mask_ack_giuint_high, + .unmask = unmask_giuint_high, }; static int giu_get_irq(unsigned int irq) @@ -282,9 +250,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ break; } } + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_low_irq_chip, + handle_edge_irq); } else { giu_clear(GIUINTTYPL, mask); giu_clear(GIUINTHTSELL, mask); + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_low_irq_chip, + handle_level_irq); } giu_write(GIUINTSTATL, mask); } else if (pin < GIUINT_HIGH_MAX) { @@ -311,9 +285,15 @@ void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_ break; } } + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_high_irq_chip, + handle_edge_irq); } else { giu_clear(GIUINTTYPH, mask); giu_clear(GIUINTHTSELH, mask); + set_irq_chip_and_handler(GIU_IRQ(pin), + &giuint_high_irq_chip, + handle_level_irq); } giu_write(GIUINTSTATH, mask); } @@ -617,10 +597,11 @@ static const struct file_operations gpio_fops = { static int __devinit giu_probe(struct platform_device *dev) { unsigned long start, size, flags = 0; - unsigned int nr_pins = 0; + unsigned int nr_pins = 0, trigger, i, pin; struct resource *res1, *res2 = NULL; void *base; - int retval, i; + struct irq_chip *chip; + int retval; switch (current_cpu_data.cputype) { case CPU_VR4111: @@ -688,11 +669,20 @@ static int __devinit giu_probe(struct platform_device *dev) giu_write(GIUINTENL, 0); giu_write(GIUINTENH, 0); + trigger = giu_read(GIUINTTYPH) << 16; + trigger |= giu_read(GIUINTTYPL); for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { - if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) - irq_desc[i].chip = &giuint_low_irq_type; + pin = GPIO_PIN_OF_IRQ(i); + if (pin < GIUINT_HIGH_OFFSET) + chip = &giuint_low_irq_chip; else - irq_desc[i].chip = &giuint_high_irq_type; + chip = &giuint_high_irq_chip; + + if (trigger & (1 << pin)) + set_irq_chip_and_handler(i, chip, handle_edge_irq); + else + set_irq_chip_and_handler(i, chip, handle_level_irq); + } return cascade_irq(GIUINT_IRQ, giu_get_irq); diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index d91330432ba..a45cc89e387 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -722,8 +722,13 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) spin_unlock_irqrestore(&cpufreq_driver_lock, flags); dprintk("CPU already managed, adding link\n"); - sysfs_create_link(&sys_dev->kobj, - &managed_policy->kobj, "cpufreq"); + ret = sysfs_create_link(&sys_dev->kobj, + &managed_policy->kobj, + "cpufreq"); + if (ret) { + mutex_unlock(&policy->lock); + goto err_out_driver_exit; + } cpufreq_debug_enable_ratelimit(); mutex_unlock(&policy->lock); @@ -770,8 +775,12 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) dprintk("CPU %u already managed, adding link\n", j); cpufreq_cpu_get(cpu); cpu_sys_dev = get_cpu_sysdev(j); - sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, - "cpufreq"); + ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, + "cpufreq"); + if (ret) { + mutex_unlock(&policy->lock); + goto err_out_unregister; + } } policy->governor = NULL; /* to assure that the starting sequence is diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 5ab5e393b88..c6281ccd4fe 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -122,8 +122,6 @@ struct efivar_entry { struct kobject kobj; }; -#define get_efivar_entry(n) list_entry(n, struct efivar_entry, list) - struct efivar_attribute { struct attribute attr; ssize_t (*show) (struct efivar_entry *entry, char *buf); @@ -386,9 +384,6 @@ static struct sysfs_ops efivar_attr_ops = { static void efivar_release(struct kobject *kobj) { struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); - spin_lock(&efivars_lock); - list_del(&var->list); - spin_unlock(&efivars_lock); kfree(var); } @@ -430,9 +425,8 @@ static ssize_t efivar_create(struct subsystem *sub, const char *buf, size_t count) { struct efi_variable *new_var = (struct efi_variable *)buf; - struct efivar_entry *search_efivar = NULL; + struct efivar_entry *search_efivar, *n; unsigned long strsize1, strsize2; - struct list_head *pos, *n; efi_status_t status = EFI_NOT_FOUND; int found = 0; @@ -444,8 +438,7 @@ efivar_create(struct subsystem *sub, const char *buf, size_t count) /* * Does this variable already exist? */ - list_for_each_safe(pos, n, &efivar_list) { - search_efivar = get_efivar_entry(pos); + list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); strsize2 = utf8_strsize(new_var->VariableName, 1024); if (strsize1 == strsize2 && @@ -490,9 +483,8 @@ static ssize_t efivar_delete(struct subsystem *sub, const char *buf, size_t count) { struct efi_variable *del_var = (struct efi_variable *)buf; - struct efivar_entry *search_efivar = NULL; + struct efivar_entry *search_efivar, *n; unsigned long strsize1, strsize2; - struct list_head *pos, *n; efi_status_t status = EFI_NOT_FOUND; int found = 0; @@ -504,8 +496,7 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count) /* * Does this variable already exist? */ - list_for_each_safe(pos, n, &efivar_list) { - search_efivar = get_efivar_entry(pos); + list_for_each_entry_safe(search_efivar, n, &efivar_list, list) { strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024); strsize2 = utf8_strsize(del_var->VariableName, 1024); if (strsize1 == strsize2 && @@ -537,9 +528,9 @@ efivar_delete(struct subsystem *sub, const char *buf, size_t count) spin_unlock(&efivars_lock); return -EIO; } + list_del(&search_efivar->list); /* We need to release this lock before unregistering. */ spin_unlock(&efivars_lock); - efivar_unregister(search_efivar); /* It's dead Jim.... */ @@ -768,10 +759,14 @@ out_free: static void __exit efivars_exit(void) { - struct list_head *pos, *n; + struct efivar_entry *entry, *n; - list_for_each_safe(pos, n, &efivar_list) - efivar_unregister(get_efivar_entry(pos)); + list_for_each_entry_safe(entry, n, &efivar_list, list) { + spin_lock(&efivars_lock); + list_del(&entry->list); + spin_unlock(&efivars_lock); + efivar_unregister(entry); + } subsystem_unregister(&vars_subsys); firmware_unregister(&efi_subsys); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1e1a7770a6b..49f18f5b251 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -543,6 +543,7 @@ void hid_free_device(struct hid_device *device) } kfree(device->rdesc); + kfree(device->collection); kfree(device); } EXPORT_SYMBOL_GPL(hid_free_device); @@ -880,6 +881,10 @@ static void hid_output_field(struct hid_field *field, __u8 *data) unsigned size = field->report_size; unsigned n; + /* make sure the unused bits in the last byte are zeros */ + if (count > 0 && size > 0) + data[(count*size-1)/8] = 0; + for (n = 0; n < count; n++) { if (field->logical_minimum < 0) /* signed values */ implement(data, offset + n * size, size, s32ton(field->value[n], size)); @@ -947,7 +952,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i } #ifdef DEBUG_DATA - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); + printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); #endif n = 0; /* Normally report number is 0 */ diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 28689e3eb55..c7a6833f682 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -30,12 +30,16 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/kernel.h> -#include <linux/usb/input.h> #undef DEBUG #include <linux/hid.h> +static int hid_pb_fnmode = 1; +module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644); +MODULE_PARM_DESC(pb_fnmode, + "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); + #define unk KEY_UNKNOWN static const unsigned char hid_keyboard[256] = { @@ -155,7 +159,7 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, return 1; } - if (hid->pb_fnmode) { + if (hid_pb_fnmode) { int do_translate; trans = find_translation(powerbook_fn_keys, usage->code); @@ -164,8 +168,8 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, do_translate = 1; else if (trans->flags & POWERBOOK_FLAG_FKEY) do_translate = - (hid->pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || - (hid->pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); + (hid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || + (hid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); else do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); @@ -364,9 +368,22 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel break; case HID_UP_LED: - if (((usage->hid - 1) & 0xffff) >= LED_MAX) - goto ignore; - map_led((usage->hid - 1) & 0xffff); + + switch (usage->hid & 0xffff) { /* HID-Value: */ + case 0x01: map_led (LED_NUML); break; /* "Num Lock" */ + case 0x02: map_led (LED_CAPSL); break; /* "Caps Lock" */ + case 0x03: map_led (LED_SCROLLL); break; /* "Scroll Lock" */ + case 0x04: map_led (LED_COMPOSE); break; /* "Compose" */ + case 0x05: map_led (LED_KANA); break; /* "Kana" */ + case 0x27: map_led (LED_SLEEP); break; /* "Stand-By" */ + case 0x4c: map_led (LED_SUSPEND); break; /* "System Suspend" */ + case 0x09: map_led (LED_MUTE); break; /* "Mute" */ + case 0x4b: map_led (LED_MISC); break; /* "Generic Indicator" */ + case 0x19: map_led (LED_MAIL); break; /* "Message Waiting" */ + case 0x4d: map_led (LED_CHARGING); break; /* "External Power Connected" */ + + default: goto ignore; + } break; case HID_UP_DIGITIZER: @@ -419,6 +436,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x040: map_key_clear(KEY_MENU); break; case 0x045: map_key_clear(KEY_RADIO); break; + case 0x083: map_key_clear(KEY_LAST); break; case 0x088: map_key_clear(KEY_PC); break; case 0x089: map_key_clear(KEY_TV); break; case 0x08a: map_key_clear(KEY_WWW); break; @@ -436,6 +454,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x096: map_key_clear(KEY_TAPE); break; case 0x097: map_key_clear(KEY_TV2); break; case 0x098: map_key_clear(KEY_SAT); break; + case 0x09a: map_key_clear(KEY_PVR); break; case 0x09c: map_key_clear(KEY_CHANNELUP); break; case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 31c42002708..b80f6ed5acf 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c @@ -93,7 +93,7 @@ int vid_from_reg(int val, u8 vrm) case 110: /* Intel Conroe */ /* compute in uV, round to mV */ val &= 0xff; - if(((val & 0x7e) == 0xfe) || (!(val & 0x7e))) + if (val < 0x02 || val > 0xb2) return 0; return((1600000 - (val - 2) * 6250 + 500) / 1000); case 24: /* Opteron processor */ diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index c12ac5abc2b..253ffaf1568 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -117,6 +117,7 @@ static const u16 W83793_REG_IN[][3] = { /* Low Bits of Vcore A/B Vtt Read/High/Low */ static const u16 W83793_REG_IN_LOW_BITS[] = { 0x1b, 0x68, 0x69 }; static u8 scale_in[] = { 2, 2, 2, 16, 16, 16, 8, 24, 24, 16 }; +static u8 scale_in_add[] = { 0, 0, 0, 0, 0, 0, 0, 150, 150, 0 }; #define W83793_REG_FAN(index) (0x23 + 2 * (index)) /* High byte */ #define W83793_REG_FAN_MIN(index) (0x90 + 2 * (index)) /* High byte */ @@ -203,6 +204,8 @@ struct w83793_data { u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ u8 has_pwm; + u8 has_temp; + u8 has_vid; u8 pwm_enable; /* Register value, each Temp has 1 bit */ u8 pwm_uptime; /* Register value */ u8 pwm_downtime; /* Register value */ @@ -500,7 +503,7 @@ store_temp(struct device *dev, struct device_attribute *attr, each has 4 mode:(2 bits) 0: Stop monitor 1: Use internal temp sensor(default) - 2: Use sensor in AMD CPU and get result by AMDSI + 2: Reserved 3: Use sensor in Intel CPU and get result by PECI TR1-TR2 @@ -509,8 +512,8 @@ store_temp(struct device *dev, struct device_attribute *attr, 1: To enable temp sensors monitor */ -/* 0 disable, 5 AMDSI, 6 PECI */ -static u8 TO_TEMP_MODE[] = { 0, 0, 5, 6 }; +/* 0 disable, 6 PECI */ +static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 }; static ssize_t show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) @@ -550,11 +553,10 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, u8 val = simple_strtoul(buf, NULL, 10); /* transform the sysfs interface values into table above */ - if ((val == 5 || val == 6) && (index < 4)) { + if ((val == 6) && (index < 4)) { val -= 3; } else if ((val == 3 && index < 4) - || (val == 4 && index >= 4) - || val == 0) { + || (val == 4 && index >= 4)) { /* transform diode or thermistor into internal enable */ val = !!val; } else { @@ -839,7 +841,9 @@ show_in(struct device *dev, struct device_attribute *attr, char *buf) val <<= 2; val += (data->in_low_bits[nr] >> (index * 2)) & 0x3; } - return sprintf(buf, "%d\n", val * scale_in[index]); + /* voltage inputs 5VDD and 5VSB needs 150mV offset */ + val = val * scale_in[index] + scale_in_add[index]; + return sprintf(buf, "%d\n", val); } static ssize_t @@ -859,6 +863,10 @@ store_in(struct device *dev, struct device_attribute *attr, scale_in[index] / 2) / scale_in[index]; mutex_lock(&data->update_lock); if (index > 2) { + /* fix the limit values of 5VDD and 5VSB to ALARM mechanism */ + if (1 == nr || 2 == nr) { + val -= scale_in_add[index] / scale_in[index]; + } val = SENSORS_LIMIT(val, 0, 255); } else { val = SENSORS_LIMIT(val, 0, 0x3FF); @@ -979,12 +987,6 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { SENSOR_ATTR_IN(7), SENSOR_ATTR_IN(8), SENSOR_ATTR_IN(9), - SENSOR_ATTR_TEMP(1), - SENSOR_ATTR_TEMP(2), - SENSOR_ATTR_TEMP(3), - SENSOR_ATTR_TEMP(4), - SENSOR_ATTR_TEMP(5), - SENSOR_ATTR_TEMP(6), SENSOR_ATTR_FAN(1), SENSOR_ATTR_FAN(2), SENSOR_ATTR_FAN(3), @@ -995,6 +997,15 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { SENSOR_ATTR_PWM(3), }; +static struct sensor_device_attribute_2 w83793_temp[] = { + SENSOR_ATTR_TEMP(1), + SENSOR_ATTR_TEMP(2), + SENSOR_ATTR_TEMP(3), + SENSOR_ATTR_TEMP(4), + SENSOR_ATTR_TEMP(5), + SENSOR_ATTR_TEMP(6), +}; + /* Fan6-Fan12 */ static struct sensor_device_attribute_2 w83793_left_fan[] = { SENSOR_ATTR_FAN(6), @@ -1015,9 +1026,12 @@ static struct sensor_device_attribute_2 w83793_left_pwm[] = { SENSOR_ATTR_PWM(8), }; -static struct sensor_device_attribute_2 sda_single_files[] = { +static struct sensor_device_attribute_2 w83793_vid[] = { SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0), SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1), +}; + +static struct sensor_device_attribute_2 sda_single_files[] = { SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm, NOT_USED, NOT_USED), SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, @@ -1070,11 +1084,17 @@ static int w83793_detach_client(struct i2c_client *client) for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) device_remove_file(dev, &sda_single_files[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) + device_remove_file(dev, &w83793_vid[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) device_remove_file(dev, &w83793_left_fan[i].dev_attr); for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); } if ((err = i2c_detach_client(client))) @@ -1187,6 +1207,7 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) struct w83793_data *data; int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; + int files_temp = ARRAY_SIZE(w83793_temp) / 6; int err = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { @@ -1313,6 +1334,44 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) data->has_pwm |= 0x80; } + tmp = w83793_read_value(client, W83793_REG_FANIN_SEL); + if ((tmp & 0x01) && (val & 0x08)) { /* fan 9, second location */ + data->has_fan |= 0x100; + } + if ((tmp & 0x02) && (val & 0x10)) { /* fan 10, second location */ + data->has_fan |= 0x200; + } + if ((tmp & 0x04) && (val & 0x20)) { /* fan 11, second location */ + data->has_fan |= 0x400; + } + if ((tmp & 0x08) && (val & 0x40)) { /* fan 12, second location */ + data->has_fan |= 0x800; + } + + /* check the temp1-6 mode, ignore former AMDSI selected inputs */ + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]); + if (tmp & 0x01) + data->has_temp |= 0x01; + if (tmp & 0x04) + data->has_temp |= 0x02; + if (tmp & 0x10) + data->has_temp |= 0x04; + if (tmp & 0x40) + data->has_temp |= 0x08; + + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]); + if (tmp & 0x01) + data->has_temp |= 0x10; + if (tmp & 0x02) + data->has_temp |= 0x20; + + /* Detect the VID usage and ignore unused input */ + tmp = w83793_read_value(client, W83793_REG_MFC); + if (!(tmp & 0x29)) + data->has_vid |= 0x1; /* has VIDA */ + if (tmp & 0x80) + data->has_vid |= 0x2; /* has VIDB */ + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { err = device_create_file(dev, @@ -1321,6 +1380,14 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) goto exit_remove; } + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) { + if (!(data->has_vid & (1 << i))) + continue; + err = device_create_file(dev, &w83793_vid[i].dev_attr); + if (err) + goto exit_remove; + } + for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { err = device_create_file(dev, &sda_single_files[i].dev_attr); if (err) @@ -1328,6 +1395,19 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) } + for (i = 0; i < 6; i++) { + int j; + if (!(data->has_temp & (1 << i))) + continue; + for (j = 0; j < files_temp; j++) { + err = device_create_file(dev, + &w83793_temp[(i) * files_temp + + j].dev_attr); + if (err) + goto exit_remove; + } + } + for (i = 5; i < 12; i++) { int j; if (!(data->has_fan & (1 << i))) @@ -1371,12 +1451,18 @@ exit_remove: for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) device_remove_file(dev, &sda_single_files[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) + device_remove_file(dev, &w83793_vid[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) device_remove_file(dev, &w83793_left_fan[i].dev_attr); for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); + if (data->lm75[0] != NULL) { i2c_detach_client(data->lm75[0]); kfree(data->lm75[0]); @@ -1428,6 +1514,8 @@ static void w83793_update_nonvolatile(struct device *dev) } for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp_fan_map[i] = w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i)); for (j = 1; j < 5; j++) { @@ -1510,9 +1598,12 @@ static struct w83793_data *w83793_update_device(struct device *dev) w83793_read_value(client, W83793_REG_FAN(i) + 1); } - for (i = 0; i < ARRAY_SIZE(data->temp); i++) + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp[i][TEMP_READ] = w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]); + } data->temp_low_bits = w83793_read_value(client, W83793_REG_TEMP_LOW_BITS); @@ -1527,8 +1618,10 @@ static struct w83793_data *w83793_update_device(struct device *dev) for (i = 0; i < ARRAY_SIZE(data->alarms); i++) data->alarms[i] = w83793_read_value(client, W83793_REG_ALARM(i)); - data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); - data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); + if (data->has_vid & 0x01) + data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); + if (data->has_vid & 0x02) + data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); w83793_update_nonvolatile(dev); data->last_updated = jiffies; data->valid = 1; diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index df7d1504f84..98410ca044c 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c @@ -73,3 +73,8 @@ void __init pnpide_init(void) { pnp_register_driver(&idepnp_driver); } + +void __exit pnpide_exit(void) +{ + pnp_unregister_driver(&idepnp_driver); +} diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 16890769dca..6c9bd5165bd 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1781,8 +1781,9 @@ done: return 1; } -extern void pnpide_init(void); -extern void h8300_ide_init(void); +extern void __init pnpide_init(void); +extern void __exit pnpide_exit(void); +extern void __init h8300_ide_init(void); /* * probe_for_hwifs() finds/initializes "known" IDE interfaces @@ -2087,13 +2088,17 @@ int __init init_module (void) return ide_init(); } -void cleanup_module (void) +void __exit cleanup_module (void) { int index; for (index = 0; index < MAX_HWIFS; ++index) ide_unregister(index); +#ifdef CONFIG_BLK_DEV_IDEPNP + pnpide_exit(); +#endif + #ifdef CONFIG_PROC_FS proc_ide_destroy(); #endif diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index f286079d233..d261bfbad22 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -441,7 +441,7 @@ static struct pci_driver driver = { .probe = aec62xx_init_one, }; -static int aec62xx_ide_init(void) +static int __init aec62xx_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 89109be5162..68df77ec502 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -907,7 +907,7 @@ static struct pci_driver driver = { .probe = alim15x3_init_one, }; -static int ali15x3_ide_init(void) +static int __init ali15x3_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 753fe0e2145..a4336995a41 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -544,7 +544,7 @@ static struct pci_driver driver = { .probe = amd74xx_probe, }; -static int amd74xx_ide_init(void) +static int __init amd74xx_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 524e65de439..982ac31fa99 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -291,8 +291,12 @@ fast_ata_pio: static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) { + u8 udma_mode = 0; + u8 ch = hwif->channel; + struct pci_dev *pdev = hwif->pci_dev; + if (!hwif->irq) - hwif->irq = hwif->channel ? 15 : 14; + hwif->irq = ch ? 15 : 14; hwif->autodma = 0; hwif->tuneproc = &atiixp_tuneproc; @@ -308,8 +312,12 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) hwif->mwdma_mask = 0x06; hwif->swdma_mask = 0x04; - /* FIXME: proper cable detection needed */ - hwif->udma_four = 1; + pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode); + if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40) + hwif->udma_four = 1; + else + hwif->udma_four = 0; + hwif->ide_dma_host_on = &atiixp_ide_dma_host_on; hwif->ide_dma_host_off = &atiixp_ide_dma_host_off; hwif->ide_dma_check = &atiixp_dma_check; @@ -320,19 +328,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) hwif->drives[0].autodma = hwif->autodma; } -static void __devinit init_hwif_sb600_legacy(ide_hwif_t *hwif) -{ - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} static ide_pci_device_t atiixp_pci_info[] __devinitdata = { { /* 0 */ @@ -343,12 +338,13 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = { .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, .bootable = ON_BOARD, },{ /* 1 */ - .name = "ATI SB600 SATA Legacy IDE", - .init_hwif = init_hwif_sb600_legacy, - .channels = 2, + .name = "SB600_PATA", + .init_hwif = init_hwif_atiixp, + .channels = 1, .autodma = AUTODMA, - .bootable = ON_BOARD, - } + .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, + .bootable = ON_BOARD, + }, }; /** @@ -369,7 +365,7 @@ static struct pci_device_id atiixp_pci_tbl[] = { { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 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, 0}, + { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { 0, }, }; MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); @@ -380,7 +376,7 @@ static struct pci_driver driver = { .probe = atiixp_init_one, }; -static int atiixp_ide_init(void) +static int __init atiixp_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index 20c32716bbc..aee947e8fc3 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -793,7 +793,7 @@ static struct pci_driver driver = { .probe = cmd64x_init_one, }; -static int cmd64x_ide_init(void) +static int __init cmd64x_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 079f7c86726..ba6786aabf3 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -260,7 +260,7 @@ static struct pci_driver driver = { .probe = cs5520_init_one, }; -static int cs5520_ide_init(void) +static int __init cs5520_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index ae405fa3223..9bf5fdfc5b1 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -374,7 +374,7 @@ static struct pci_driver driver = { .probe = cs5530_init_one, }; -static int cs5530_ide_init(void) +static int __init cs5530_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 64330c459bd..9eafcbf444f 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -519,7 +519,7 @@ static struct pci_driver driver = { .probe = cy82c693_init_one, }; -static int cy82c693_ide_init(void) +static int __init cy82c693_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 9f306880491..b408c6c517e 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -185,36 +185,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, - },{ /* 15 */ - .name = "JMB361", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 16 */ - .name = "JMB363", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 17 */ - .name = "JMB365", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 18 */ - .name = "JMB366", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 19 */ - .name = "JMB368", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, } }; @@ -281,11 +251,6 @@ static struct pci_device_id generic_pci_tbl[] = { { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12}, { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13}, { PCI_VENDOR_ID_NETCELL,PCI_DEVICE_ID_REVOLUTION, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19}, /* Must come last. If you add entries adjust this table appropriately and the init_one code */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 0}, { 0, }, @@ -298,7 +263,7 @@ static struct pci_driver driver = { .probe = generic_init_one, }; -static int generic_ide_init(void) +static int __init generic_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index b46cb042290..ce7b08f08a0 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -265,7 +265,7 @@ static struct pci_driver driver = { .probe = hpt34x_init_one, }; -static int hpt34x_ide_init(void) +static int __init hpt34x_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 08119da06d5..b486442dd5d 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1613,7 +1613,7 @@ static struct pci_driver driver = { .probe = hpt366_init_one, }; -static int hpt366_ide_init(void) +static int __init hpt366_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index c1cec236ecf..f07bbbed177 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -86,15 +86,16 @@ static int __devinit ata66_jmicron(ide_hwif_t *hwif) { case PORT_PATA0: if (control & (1 << 3)) /* 40/80 pin primary */ - return 1; - return 0; + return 0; + return 1; case PORT_PATA1: if (control5 & (1 << 19)) /* 40/80 pin secondary */ return 0; return 1; case PORT_SATA: - return 1; + break; } + return 1; /* Avoid bogus "control reaches end of non-void function" */ } static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted) @@ -240,11 +241,11 @@ static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_devi } static struct pci_device_id jmicron_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 0}, - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 1}, - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365), 2}, - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366), 3}, - { PCI_DEVICE(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368), 4}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, { 0, }, }; diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index d95714bcee4..8aaea4ea554 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -302,7 +302,7 @@ static struct pci_driver driver = { .probe = ns87415_init_one, }; -static int ns87415_ide_init(void) +static int __init ns87415_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index 7a7c2ef78ac..22bbf613f94 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c @@ -382,7 +382,7 @@ static struct pci_driver driver = { .probe = opti621_init_one, }; -static int opti621_ide_init(void) +static int __init opti621_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 7cb48576e47..77a9aaa7dab 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -756,7 +756,7 @@ static struct pci_driver driver = { .probe = pdc202new_init_one, }; -static int pdc202new_ide_init(void) +static int __init pdc202new_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 184cdacddeb..143239c093d 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -719,7 +719,7 @@ static struct pci_driver driver = { .probe = pdc202xx_init_one, }; -static int pdc202xx_ide_init(void) +static int __init pdc202xx_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c index 5f6950c2d1d..c1855311052 100644 --- a/drivers/ide/pci/rz1000.c +++ b/drivers/ide/pci/rz1000.c @@ -77,7 +77,7 @@ static struct pci_driver driver = { .probe = rz1000_init_one, }; -static int rz1000_ide_init(void) +static int __init rz1000_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index ff80937d94d..8d762d323f8 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -507,7 +507,7 @@ static struct pci_driver driver = { #endif }; -static int sc1200_ide_init(void) +static int __init sc1200_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 057548d0720..ea9a28a4585 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -666,7 +666,7 @@ static struct pci_driver driver = { .probe = svwks_init_one, }; -static int svwks_ide_init(void) +static int __init svwks_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index cfad09accf5..b0bf0180927 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -762,8 +762,7 @@ static struct ioc4_submodule ioc4_ide_submodule = { /* .is_remove = ioc4_ide_remove_one, */ }; -static int __devinit -ioc4_ide_init(void) +static int __init ioc4_ide_init(void) { return ioc4_register_submodule(&ioc4_ide_submodule); } diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 697f566fb90..4ff89c7d990 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -1096,7 +1096,7 @@ static struct pci_driver driver = { .probe = siimage_init_one, }; -static int siimage_ide_init(void) +static int __init siimage_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 6b313139b5e..1afff659ab5 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -968,7 +968,7 @@ static struct pci_driver driver = { .probe = sis5513_init_one, }; -static int sis5513_ide_init(void) +static int __init sis5513_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 5afefe8692f..170a2619905 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -492,7 +492,7 @@ static struct pci_driver driver = { .probe = sl82c105_init_one, }; -static int sl82c105_ide_init(void) +static int __init sl82c105_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 9be7e49cba0..90e79c0844d 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -253,7 +253,7 @@ static struct pci_driver driver = { .probe = slc90e66_init_one, }; -static int slc90e66_ide_init(void) +static int __init slc90e66_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index 56d84931d6d..b13cce1fd1a 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -173,7 +173,7 @@ static struct pci_driver driver = { .probe = triflex_init_one, }; -static int triflex_ide_init(void) +static int __init triflex_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index 2a282529bfc..174b88c4780 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/pci/trm290.c @@ -355,7 +355,7 @@ static struct pci_driver driver = { .probe = trm290_init_one, }; -static int trm290_ide_init(void) +static int __init trm290_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 381cc6f101c..6fb6e50b823 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -78,6 +78,8 @@ static struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, @@ -504,6 +506,7 @@ static struct pci_device_id via_pci_tbl[] = { { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_SATA_EIDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { 0, }, }; MODULE_DEVICE_TABLE(pci, via_pci_tbl); @@ -514,7 +517,7 @@ static struct pci_driver driver = { .probe = via_init_one, }; -static int via_ide_init(void) +static int __init via_ide_init(void) { return ide_pci_register_driver(&driver); } diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 93995b658d9..6074c897f51 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c @@ -344,8 +344,11 @@ int ehca_destroy_cq(struct ib_cq *cq) unsigned long flags; spin_lock_irqsave(&ehca_cq_idr_lock, flags); - while (my_cq->nr_callbacks) + while (my_cq->nr_callbacks) { + spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); yield(); + spin_lock_irqsave(&ehca_cq_idr_lock, flags); + } idr_remove(&ehca_cq_idr, my_cq->token); spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index e7209afb425..c069be8cbcb 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -440,7 +440,8 @@ void ehca_tasklet_eq(unsigned long data) cq = idr_find(&ehca_cq_idr, token); if (cq == NULL) { - spin_unlock(&ehca_cq_idr_lock); + spin_unlock_irqrestore(&ehca_cq_idr_lock, + flags); break; } diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index cdecbf5911c..72611fd1510 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1621,18 +1621,30 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) switch (token) { case SRP_OPT_ID_EXT: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } target->id_ext = cpu_to_be64(simple_strtoull(p, NULL, 16)); kfree(p); break; case SRP_OPT_IOC_GUID: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } target->ioc_guid = cpu_to_be64(simple_strtoull(p, NULL, 16)); kfree(p); break; case SRP_OPT_DGID: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } if (strlen(p) != 32) { printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p); kfree(p); @@ -1656,6 +1668,10 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) case SRP_OPT_SERVICE_ID: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } target->service_id = cpu_to_be64(simple_strtoull(p, NULL, 16)); kfree(p); break; @@ -1693,6 +1709,10 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) case SRP_OPT_INITIATOR_EXT: p = match_strdup(args); + if (!p) { + ret = -ENOMEM; + goto out; + } target->initiator_ext = cpu_to_be64(simple_strtoull(p, NULL, 16)); kfree(p); break; diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 95eff3b2917..4f75cce6fdf 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -356,16 +356,17 @@ static struct cardstate *alloc_cs(struct gigaset_driver *drv) { unsigned long flags; unsigned i; - static struct cardstate *ret = NULL; + struct cardstate *ret = NULL; spin_lock_irqsave(&drv->lock, flags); for (i = 0; i < drv->minors; ++i) { if (!(drv->flags[i] & VALID_MINOR)) { - drv->flags[i] = VALID_MINOR; - ret = drv->cs + i; - } - if (ret) + if (try_module_get(drv->owner)) { + drv->flags[i] = VALID_MINOR; + ret = drv->cs + i; + } break; + } } spin_unlock_irqrestore(&drv->lock, flags); return ret; @@ -376,6 +377,8 @@ static void free_cs(struct cardstate *cs) unsigned long flags; struct gigaset_driver *drv = cs->driver; spin_lock_irqsave(&drv->lock, flags); + if (drv->flags[cs->minor_index] & VALID_MINOR) + module_put(drv->owner); drv->flags[cs->minor_index] = 0; spin_unlock_irqrestore(&drv->lock, flags); } @@ -579,7 +582,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) skb_reserve(bcs->skb, HW_HDR_LEN); else { - warn("could not allocate skb\n"); + warn("could not allocate skb"); bcs->inputstate |= INS_skip_frame; } @@ -632,17 +635,25 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, int i; gig_dbg(DEBUG_INIT, "allocating cs"); - cs = alloc_cs(drv); - if (!cs) - goto error; + if (!(cs = alloc_cs(drv))) { + err("maximum number of devices exceeded"); + return NULL; + } + mutex_init(&cs->mutex); + mutex_lock(&cs->mutex); + gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); - if (!cs->bcs) + if (!cs->bcs) { + err("out of memory"); goto error; + } gig_dbg(DEBUG_INIT, "allocating inbuf"); cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); - if (!cs->inbuf) + if (!cs->inbuf) { + err("out of memory"); goto error; + } cs->cs_init = 0; cs->channels = channels; @@ -654,8 +665,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, spin_lock_init(&cs->ev_lock); cs->ev_tail = 0; cs->ev_head = 0; - mutex_init(&cs->mutex); - mutex_lock(&cs->mutex); tasklet_init(&cs->event_tasklet, &gigaset_handle_event, (unsigned long) cs); @@ -684,8 +693,10 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, for (i = 0; i < channels; ++i) { gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); - if (!gigaset_initbcs(cs->bcs + i, cs, i)) + if (!gigaset_initbcs(cs->bcs + i, cs, i)) { + err("could not allocate channel %d data", i); goto error; + } } ++cs->cs_init; @@ -720,8 +731,10 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, make_valid(cs, VALID_ID); ++cs->cs_init; gig_dbg(DEBUG_INIT, "setting up hw"); - if (!cs->ops->initcshw(cs)) + if (!cs->ops->initcshw(cs)) { + err("could not allocate device specific data"); goto error; + } ++cs->cs_init; @@ -743,8 +756,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, mutex_unlock(&cs->mutex); return cs; -error: if (cs) - mutex_unlock(&cs->mutex); +error: + mutex_unlock(&cs->mutex); gig_dbg(DEBUG_INIT, "failed"); gigaset_freecs(cs); return NULL; @@ -1040,7 +1053,6 @@ void gigaset_freedriver(struct gigaset_driver *drv) spin_unlock_irqrestore(&driver_lock, flags); gigaset_if_freedriver(drv); - module_put(drv->owner); kfree(drv->cs); kfree(drv->flags); @@ -1072,10 +1084,6 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, if (!drv) return NULL; - if (!try_module_get(owner)) - goto out1; - - drv->cs = NULL; drv->have_tty = 0; drv->minor = minor; drv->minors = minors; @@ -1087,11 +1095,11 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, drv->cs = kmalloc(minors * sizeof *drv->cs, GFP_KERNEL); if (!drv->cs) - goto out2; + goto error; drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); if (!drv->flags) - goto out3; + goto error; for (i = 0; i < minors; ++i) { drv->flags[i] = 0; @@ -1108,11 +1116,8 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, return drv; -out3: +error: kfree(drv->cs); -out2: - module_put(owner); -out1: kfree(drv); return NULL; } diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 91e0c75aca8..2db1ca4c680 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -242,6 +242,7 @@ struct kvm_vcpu { u64 pdptrs[4]; /* pae */ u64 shadow_efer; u64 apic_base; + u64 ia32_misc_enable_msr; int nmsrs; struct vmx_msr_entry *guest_msrs; struct vmx_msr_entry *host_msrs; diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 67c1154960f..b10972ed0c9 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -272,7 +272,9 @@ static void kvm_free_physmem(struct kvm *kvm) static void kvm_free_vcpu(struct kvm_vcpu *vcpu) { + vcpu_load(vcpu->kvm, vcpu_slot(vcpu)); kvm_mmu_destroy(vcpu); + vcpu_put(vcpu); kvm_arch_ops->vcpu_free(vcpu); } @@ -1224,6 +1226,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_IA32_APICBASE: data = vcpu->apic_base; break; + case MSR_IA32_MISC_ENABLE: + data = vcpu->ia32_misc_enable_msr; + break; #ifdef CONFIG_X86_64 case MSR_EFER: data = vcpu->shadow_efer; @@ -1295,6 +1300,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) case MSR_IA32_APICBASE: vcpu->apic_base = data; break; + case MSR_IA32_MISC_ENABLE: + vcpu->ia32_misc_enable_msr = data; + break; default: printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr); return 1; @@ -1598,6 +1606,10 @@ static u32 msrs_to_save[] = { static unsigned num_msrs_to_save; +static u32 emulated_msrs[] = { + MSR_IA32_MISC_ENABLE, +}; + static __init void kvm_init_msr_list(void) { u32 dummy[2]; @@ -1923,7 +1935,7 @@ static long kvm_dev_ioctl(struct file *filp, if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) goto out; n = msr_list.nmsrs; - msr_list.nmsrs = num_msrs_to_save; + msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs); if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) goto out; r = -E2BIG; @@ -1933,6 +1945,11 @@ static long kvm_dev_ioctl(struct file *filp, if (copy_to_user(user_msr_list->indices, &msrs_to_save, num_msrs_to_save * sizeof(u32))) goto out; + if (copy_to_user(user_msr_list->indices + + num_msrs_to_save * sizeof(u32), + &emulated_msrs, + ARRAY_SIZE(emulated_msrs) * sizeof(u32))) + goto out; r = 0; break; } diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index c6f972914f0..22c426cd8cb 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c @@ -143,6 +143,7 @@ static int dbg = 1; #define PFERR_PRESENT_MASK (1U << 0) #define PFERR_WRITE_MASK (1U << 1) #define PFERR_USER_MASK (1U << 2) +#define PFERR_FETCH_MASK (1U << 4) #define PT64_ROOT_LEVEL 4 #define PT32_ROOT_LEVEL 2 @@ -168,6 +169,11 @@ static int is_cpuid_PSE36(void) return 1; } +static int is_nx(struct kvm_vcpu *vcpu) +{ + return vcpu->shadow_efer & EFER_NX; +} + static int is_present_pte(unsigned long pte) { return pte & PT_PRESENT_MASK; @@ -992,16 +998,6 @@ static inline int fix_read_pf(u64 *shadow_ent) return 0; } -static int may_access(u64 pte, int write, int user) -{ - - if (user && !(pte & PT_USER_MASK)) - return 0; - if (write && !(pte & PT_WRITABLE_MASK)) - return 0; - return 1; -} - static void paging_free(struct kvm_vcpu *vcpu) { nonpaging_free(vcpu); diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index 2dbf4307ed9..149fa45fd9a 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h @@ -63,13 +63,15 @@ struct guest_walker { pt_element_t *ptep; pt_element_t inherited_ar; gfn_t gfn; + u32 error_code; }; /* * Fetch a guest pte for a guest virtual address */ -static void FNAME(walk_addr)(struct guest_walker *walker, - struct kvm_vcpu *vcpu, gva_t addr) +static int FNAME(walk_addr)(struct guest_walker *walker, + struct kvm_vcpu *vcpu, gva_t addr, + int write_fault, int user_fault, int fetch_fault) { hpa_t hpa; struct kvm_memory_slot *slot; @@ -86,7 +88,7 @@ static void FNAME(walk_addr)(struct guest_walker *walker, walker->ptep = &vcpu->pdptrs[(addr >> 30) & 3]; root = *walker->ptep; if (!(root & PT_PRESENT_MASK)) - return; + goto not_present; --walker->level; } #endif @@ -111,11 +113,23 @@ static void FNAME(walk_addr)(struct guest_walker *walker, ASSERT(((unsigned long)walker->table & PAGE_MASK) == ((unsigned long)ptep & PAGE_MASK)); - if (is_present_pte(*ptep) && !(*ptep & PT_ACCESSED_MASK)) - *ptep |= PT_ACCESSED_MASK; - if (!is_present_pte(*ptep)) - break; + goto not_present; + + if (write_fault && !is_writeble_pte(*ptep)) + if (user_fault || is_write_protection(vcpu)) + goto access_error; + + if (user_fault && !(*ptep & PT_USER_MASK)) + goto access_error; + +#if PTTYPE == 64 + if (fetch_fault && is_nx(vcpu) && (*ptep & PT64_NX_MASK)) + goto access_error; +#endif + + if (!(*ptep & PT_ACCESSED_MASK)) + *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ if (walker->level == PT_PAGE_TABLE_LEVEL) { walker->gfn = (*ptep & PT_BASE_ADDR_MASK) @@ -146,6 +160,23 @@ static void FNAME(walk_addr)(struct guest_walker *walker, } walker->ptep = ptep; pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)*ptep); + return 1; + +not_present: + walker->error_code = 0; + goto err; + +access_error: + walker->error_code = PFERR_PRESENT_MASK; + +err: + if (write_fault) + walker->error_code |= PFERR_WRITE_MASK; + if (user_fault) + walker->error_code |= PFERR_USER_MASK; + if (fetch_fault) + walker->error_code |= PFERR_FETCH_MASK; + return 0; } static void FNAME(release_walker)(struct guest_walker *walker) @@ -274,7 +305,7 @@ static int FNAME(fix_write_pf)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page; if (is_writeble_pte(*shadow_ent)) - return 0; + return !user || (*shadow_ent & PT_USER_MASK); writable_shadow = *shadow_ent & PT_SHADOW_WRITABLE_MASK; if (user) { @@ -347,8 +378,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code) { int write_fault = error_code & PFERR_WRITE_MASK; - int pte_present = error_code & PFERR_PRESENT_MASK; int user_fault = error_code & PFERR_USER_MASK; + int fetch_fault = error_code & PFERR_FETCH_MASK; struct guest_walker walker; u64 *shadow_pte; int fixed; @@ -365,19 +396,20 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, /* * Look up the shadow pte for the faulting address. */ - FNAME(walk_addr)(&walker, vcpu, addr); - shadow_pte = FNAME(fetch)(vcpu, addr, &walker); + r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault, + fetch_fault); /* * The page is not mapped by the guest. Let the guest handle it. */ - if (!shadow_pte) { - pgprintk("%s: not mapped\n", __FUNCTION__); - inject_page_fault(vcpu, addr, error_code); + if (!r) { + pgprintk("%s: guest page fault\n", __FUNCTION__); + inject_page_fault(vcpu, addr, walker.error_code); FNAME(release_walker)(&walker); return 0; } + shadow_pte = FNAME(fetch)(vcpu, addr, &walker); pgprintk("%s: shadow pte %p %llx\n", __FUNCTION__, shadow_pte, *shadow_pte); @@ -399,22 +431,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, * mmio: emulate if accessible, otherwise its a guest fault. */ if (is_io_pte(*shadow_pte)) { - if (may_access(*shadow_pte, write_fault, user_fault)) - return 1; - pgprintk("%s: io work, no access\n", __FUNCTION__); - inject_page_fault(vcpu, addr, - error_code | PFERR_PRESENT_MASK); - kvm_mmu_audit(vcpu, "post page fault (io)"); - return 0; - } - - /* - * pte not present, guest page fault. - */ - if (pte_present && !fixed && !write_pt) { - inject_page_fault(vcpu, addr, error_code); - kvm_mmu_audit(vcpu, "post page fault (guest)"); - return 0; + return 1; } ++kvm_stat.pf_fixed; @@ -429,7 +446,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) pt_element_t guest_pte; gpa_t gpa; - FNAME(walk_addr)(&walker, vcpu, vaddr); + FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0); guest_pte = *walker.ptep; FNAME(release_walker)(&walker); diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 714f6a7841c..c79df79307e 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -502,6 +502,7 @@ static void init_vmcb(struct vmcb *vmcb) (1ULL << INTERCEPT_IOIO_PROT) | (1ULL << INTERCEPT_MSR_PROT) | (1ULL << INTERCEPT_TASK_SWITCH) | + (1ULL << INTERCEPT_SHUTDOWN) | (1ULL << INTERCEPT_VMRUN) | (1ULL << INTERCEPT_VMMCALL) | (1ULL << INTERCEPT_VMLOAD) | @@ -680,14 +681,14 @@ static void svm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) { - dt->limit = vcpu->svm->vmcb->save.ldtr.limit; - dt->base = vcpu->svm->vmcb->save.ldtr.base; + dt->limit = vcpu->svm->vmcb->save.idtr.limit; + dt->base = vcpu->svm->vmcb->save.idtr.base; } static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) { - vcpu->svm->vmcb->save.ldtr.limit = dt->limit; - vcpu->svm->vmcb->save.ldtr.base = dt->base ; + vcpu->svm->vmcb->save.idtr.limit = dt->limit; + vcpu->svm->vmcb->save.idtr.base = dt->base ; } static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) @@ -892,6 +893,19 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 0; } +static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + /* + * VMCB is undefined after a SHUTDOWN intercept + * so reinitialize it. + */ + memset(vcpu->svm->vmcb, 0, PAGE_SIZE); + init_vmcb(vcpu->svm->vmcb); + + kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; + return 0; +} + static int io_get_override(struct kvm_vcpu *vcpu, struct vmcb_seg **seg, int *addr_override) @@ -1149,7 +1163,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) case MSR_K6_STAR: vcpu->svm->vmcb->save.star = data; break; -#ifdef CONFIG_X86_64_ +#ifdef CONFIG_X86_64 case MSR_LSTAR: vcpu->svm->vmcb->save.lstar = data; break; @@ -1249,6 +1263,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu, [SVM_EXIT_IOIO] = io_interception, [SVM_EXIT_MSR] = msr_interception, [SVM_EXIT_TASK_SWITCH] = task_switch_interception, + [SVM_EXIT_SHUTDOWN] = shutdown_interception, [SVM_EXIT_VMRUN] = invalid_op_interception, [SVM_EXIT_VMMCALL] = invalid_op_interception, [SVM_EXIT_VMLOAD] = invalid_op_interception, @@ -1407,7 +1422,8 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) int r; again: - do_interrupt_requests(vcpu, kvm_run); + if (!vcpu->mmio_read_completed) + do_interrupt_requests(vcpu, kvm_run); clgi(); diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index ce219e3f557..54c35c0b318 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -1116,6 +1116,8 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) if (rdmsr_safe(index, &data_low, &data_high) < 0) continue; + if (wrmsr_safe(index, data_low, data_high) < 0) + continue; data = data_low | ((u64)data_high << 32); vcpu->host_msrs[j].index = index; vcpu->host_msrs[j].reserved = 0; @@ -1717,7 +1719,8 @@ again: vmcs_writel(HOST_GS_BASE, segment_base(gs_sel)); #endif - do_interrupt_requests(vcpu, kvm_run); + if (!vcpu->mmio_read_completed) + do_interrupt_requests(vcpu, kvm_run); if (vcpu->guest_debug.enabled) kvm_guest_debug_pre(vcpu); @@ -1824,7 +1827,7 @@ again: #endif "setbe %0 \n\t" "popf \n\t" - : "=g" (fail) + : "=q" (fail) : "r"(vcpu->launched), "d"((unsigned long)HOST_RSP), "c"(vcpu), [rax]"i"(offsetof(struct kvm_vcpu, regs[VCPU_REGS_RAX])), diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index be70795b482..7513cddb929 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c @@ -61,6 +61,7 @@ #define ModRM (1<<6) /* Destination is only written; never read. */ #define Mov (1<<7) +#define BitOp (1<<8) static u8 opcode_table[256] = { /* 0x00 - 0x07 */ @@ -148,7 +149,7 @@ static u8 opcode_table[256] = { 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM }; -static u8 twobyte_table[256] = { +static u16 twobyte_table[256] = { /* 0x00 - 0x0F */ 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, @@ -180,16 +181,16 @@ static u8 twobyte_table[256] = { /* 0x90 - 0x9F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xA7 */ - 0, 0, 0, DstMem | SrcReg | ModRM, 0, 0, 0, 0, + 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, /* 0xA8 - 0xAF */ - 0, 0, 0, DstMem | SrcReg | ModRM, 0, 0, 0, 0, + 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, /* 0xB0 - 0xB7 */ ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, - DstMem | SrcReg | ModRM, + DstMem | SrcReg | ModRM | BitOp, 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem16 | ModRM | Mov, /* 0xB8 - 0xBF */ - 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM, + 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp, 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem16 | ModRM | Mov, /* 0xC0 - 0xCF */ @@ -469,7 +470,8 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, int x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { - u8 b, d, sib, twobyte = 0, rex_prefix = 0; + unsigned d; + u8 b, sib, twobyte = 0, rex_prefix = 0; u8 modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; unsigned long *override_base = NULL; unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; @@ -726,46 +728,6 @@ done_prefixes: ; } - /* Decode and fetch the destination operand: register or memory. */ - switch (d & DstMask) { - case ImplicitOps: - /* Special instructions do their own operand decoding. */ - goto special_insn; - case DstReg: - dst.type = OP_REG; - if ((d & ByteOp) - && !(twobyte_table && (b == 0xb6 || b == 0xb7))) { - dst.ptr = decode_register(modrm_reg, _regs, - (rex_prefix == 0)); - dst.val = *(u8 *) dst.ptr; - dst.bytes = 1; - } else { - dst.ptr = decode_register(modrm_reg, _regs, 0); - switch ((dst.bytes = op_bytes)) { - case 2: - dst.val = *(u16 *)dst.ptr; - break; - case 4: - dst.val = *(u32 *)dst.ptr; - break; - case 8: - dst.val = *(u64 *)dst.ptr; - break; - } - } - break; - case DstMem: - dst.type = OP_MEM; - dst.ptr = (unsigned long *)cr2; - dst.bytes = (d & ByteOp) ? 1 : op_bytes; - if (!(d & Mov) && /* optimisation - avoid slow emulated read */ - ((rc = ops->read_emulated((unsigned long)dst.ptr, - &dst.val, dst.bytes, ctxt)) != 0)) - goto done; - break; - } - dst.orig_val = dst.val; - /* * Decode and fetch the source operand: register, memory * or immediate. @@ -838,6 +800,50 @@ done_prefixes: break; } + /* Decode and fetch the destination operand: register or memory. */ + switch (d & DstMask) { + case ImplicitOps: + /* Special instructions do their own operand decoding. */ + goto special_insn; + case DstReg: + dst.type = OP_REG; + if ((d & ByteOp) + && !(twobyte_table && (b == 0xb6 || b == 0xb7))) { + dst.ptr = decode_register(modrm_reg, _regs, + (rex_prefix == 0)); + dst.val = *(u8 *) dst.ptr; + dst.bytes = 1; + } else { + dst.ptr = decode_register(modrm_reg, _regs, 0); + switch ((dst.bytes = op_bytes)) { + case 2: + dst.val = *(u16 *)dst.ptr; + break; + case 4: + dst.val = *(u32 *)dst.ptr; + break; + case 8: + dst.val = *(u64 *)dst.ptr; + break; + } + } + break; + case DstMem: + dst.type = OP_MEM; + dst.ptr = (unsigned long *)cr2; + dst.bytes = (d & ByteOp) ? 1 : op_bytes; + if (d & BitOp) { + dst.ptr += src.val / BITS_PER_LONG; + dst.bytes = sizeof(long); + } + if (!(d & Mov) && /* optimisation - avoid slow emulated read */ + ((rc = ops->read_emulated((unsigned long)dst.ptr, + &dst.val, dst.bytes, ctxt)) != 0)) + goto done; + break; + } + dst.orig_val = dst.val; + if (twobyte) goto twobyte_insn; diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 5432d07c074..11108165e26 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -479,9 +479,12 @@ static int bitmap_read_sb(struct bitmap *bitmap) int err = -EINVAL; /* page 0 is the superblock, read it... */ - if (bitmap->file) - bitmap->sb_page = read_page(bitmap->file, 0, bitmap, PAGE_SIZE); - else { + if (bitmap->file) { + loff_t isize = i_size_read(bitmap->file->f_mapping->host); + int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize; + + bitmap->sb_page = read_page(bitmap->file, 0, bitmap, bytes); + } else { bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0); } if (IS_ERR(bitmap->sb_page)) { @@ -877,7 +880,8 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) int count; /* unmap the old page, we're done with it */ if (index == num_pages-1) - count = bytes - index * PAGE_SIZE; + count = bytes + sizeof(bitmap_super_t) + - index * PAGE_SIZE; else count = PAGE_SIZE; if (index == 0) { diff --git a/drivers/md/dm.c b/drivers/md/dm.c index fe7c56e1043..3668b170ea6 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1116,7 +1116,8 @@ static int __bind(struct mapped_device *md, struct dm_table *t) if (size != get_capacity(md->disk)) memset(&md->geometry, 0, sizeof(md->geometry)); - __set_size(md, size); + if (md->suspended_bdev) + __set_size(md, size); if (size == 0) return 0; @@ -1264,6 +1265,11 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) if (!dm_suspended(md)) goto out; + /* without bdev, the device size cannot be changed */ + if (!md->suspended_bdev) + if (get_capacity(md->disk) != dm_table_get_size(table)) + goto out; + __unbind(md); r = __bind(md, table); @@ -1341,11 +1347,14 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) /* This does not get reverted if there's an error later. */ dm_table_presuspend_targets(map); - md->suspended_bdev = bdget_disk(md->disk, 0); - if (!md->suspended_bdev) { - DMWARN("bdget failed in dm_suspend"); - r = -ENOMEM; - goto flush_and_out; + /* bdget() can stall if the pending I/Os are not flushed */ + if (!noflush) { + md->suspended_bdev = bdget_disk(md->disk, 0); + if (!md->suspended_bdev) { + DMWARN("bdget failed in dm_suspend"); + r = -ENOMEM; + goto flush_and_out; + } } /* @@ -1473,8 +1482,10 @@ int dm_resume(struct mapped_device *md) unlock_fs(md); - bdput(md->suspended_bdev); - md->suspended_bdev = NULL; + if (md->suspended_bdev) { + bdput(md->suspended_bdev); + md->suspended_bdev = NULL; + } clear_bit(DMF_SUSPENDED, &md->flags); diff --git a/drivers/md/md.c b/drivers/md/md.c index d1cb45f6d6a..e8807ea5377 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1633,7 +1633,8 @@ repeat: * and 'events' is odd, we can roll back to the previous clean state */ if (nospares && (mddev->in_sync && mddev->recovery_cp == MaxSector) - && (mddev->events & 1)) + && (mddev->events & 1) + && mddev->events != 1) mddev->events--; else { /* otherwise we have to go forward and ... */ @@ -3563,6 +3564,8 @@ static int get_bitmap_file(mddev_t * mddev, void __user * arg) char *ptr, *buf = NULL; int err = -ENOMEM; + md_allow_write(mddev); + file = kmalloc(sizeof(*file), GFP_KERNEL); if (!file) goto out; @@ -5031,6 +5034,33 @@ void md_write_end(mddev_t *mddev) } } +/* md_allow_write(mddev) + * Calling this ensures that the array is marked 'active' so that writes + * may proceed without blocking. It is important to call this before + * attempting a GFP_KERNEL allocation while holding the mddev lock. + * Must be called with mddev_lock held. + */ +void md_allow_write(mddev_t *mddev) +{ + if (!mddev->pers) + return; + if (mddev->ro) + return; + + spin_lock_irq(&mddev->write_lock); + if (mddev->in_sync) { + mddev->in_sync = 0; + set_bit(MD_CHANGE_CLEAN, &mddev->flags); + if (mddev->safemode_delay && + mddev->safemode == 0) + mddev->safemode = 1; + spin_unlock_irq(&mddev->write_lock); + md_update_sb(mddev, 0); + } else + spin_unlock_irq(&mddev->write_lock); +} +EXPORT_SYMBOL_GPL(md_allow_write); + static DECLARE_WAIT_QUEUE_HEAD(resync_wait); #define SYNC_MARKS 10 diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 164b25dca10..97ee870b265 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1266,6 +1266,11 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio) sbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; sbio->bi_bdev = conf->mirrors[i].rdev->bdev; + for (j = 0; j < vcnt ; j++) + memcpy(page_address(sbio->bi_io_vec[j].bv_page), + page_address(pbio->bi_io_vec[j].bv_page), + PAGE_SIZE); + } } } @@ -2099,6 +2104,8 @@ static int raid1_reshape(mddev_t *mddev) return -EINVAL; } + md_allow_write(mddev); + raid_disks = mddev->raid_disks + mddev->delta_disks; if (raid_disks < conf->raid_disks) { diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index be008f034ad..467c16982d0 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -405,6 +405,8 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) if (newsize <= conf->pool_size) return 0; /* never bother to shrink */ + md_allow_write(conf->mddev); + /* Step 1 */ sc = kmem_cache_create(conf->cache_name[1-conf->active_name], sizeof(struct stripe_head)+(newsize-1)*sizeof(struct r5dev), @@ -2678,7 +2680,7 @@ static int chunk_aligned_read(request_queue_t *q, struct bio * raid_bio) mdk_rdev_t *rdev; if (!in_chunk_boundary(mddev, raid_bio)) { - printk("chunk_aligned_read : non aligned\n"); + PRINTK("chunk_aligned_read : non aligned\n"); return 0; } /* @@ -3250,6 +3252,7 @@ raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) else break; } + md_allow_write(mddev); while (new > conf->max_nr_stripes) { if (grow_one_stripe(conf)) conf->max_nr_stripes++; diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 3482e0114d4..2bd84d351a1 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -38,6 +38,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/errno.h> +#include <linux/freezer.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/mm.h> @@ -961,6 +962,7 @@ int cx88_audio_thread(void *data) msleep_interruptible(1000); if (kthread_should_stop()) break; + try_to_freeze(); /* just monitor the audio status for now ... */ memset(&t, 0, sizeof(t)); diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index c1a377f797d..b6cd21e6dab 100644 --- a/drivers/media/video/ks0127.c +++ b/drivers/media/video/ks0127.c @@ -712,13 +712,13 @@ static int ks0127_command(struct i2c_client *client, *iarg = 0; status = ks0127_read(ks, KS_STAT); if (!(status & 0x20)) /* NOVID not set */ - *iarg = (*iarg & DECODER_STATUS_GOOD); + *iarg = (*iarg | DECODER_STATUS_GOOD); if ((status & 0x01)) /* CLOCK set */ - *iarg = (*iarg & DECODER_STATUS_COLOR); + *iarg = (*iarg | DECODER_STATUS_COLOR); if ((status & 0x08)) /* PALDET set */ - *iarg = (*iarg & DECODER_STATUS_PAL); + *iarg = (*iarg | DECODER_STATUS_PAL); else - *iarg = (*iarg & DECODER_STATUS_NTSC); + *iarg = (*iarg | DECODER_STATUS_NTSC); break; //Catch any unknown command diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 4dead84aff4..ae984bbe36b 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -2570,6 +2570,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + .gpiomask = 1 << 21, .inputs = {{ .name = name_tv, .vmux = 1, @@ -2578,15 +2579,20 @@ struct saa7134_board saa7134_boards[] = { },{ .name = name_comp1, .vmux = 3, - .amux = LINE1, + .amux = LINE2, /* unconfirmed, taken from Philips driver */ + },{ + .name = name_comp2, + .vmux = 0, /* untested, Composite over S-Video */ + .amux = LINE2, },{ .name = name_svideo, - .vmux = 0, - .amux = LINE1, + .vmux = 8, + .amux = LINE2, }}, .radio = { .name = name_radio, - .amux = LINE1, + .amux = TV, + .gpio = 0x0200000, }, }, [SAA7134_BOARD_CINERGY250PCI] = { diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 2624e3f7dd2..4e7c1fa668d 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -184,7 +184,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "Thompson DTT757"}, /* 80-89 */ { TUNER_ABSENT, "Philips FQ1216LME MK3"}, - { TUNER_ABSENT, "LG TAPC G701D"}, + { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, diff --git a/drivers/media/video/usbvideo/quickcam_messenger.h b/drivers/media/video/usbvideo/quickcam_messenger.h index baab9c081b5..17ace394d98 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.h +++ b/drivers/media/video/usbvideo/quickcam_messenger.h @@ -35,27 +35,13 @@ struct rgb { }; struct bayL0 { -#ifdef __BIG_ENDIAN - u8 r; - u8 g; -#elif __LITTLE_ENDIAN u8 g; u8 r; -#else -#error not byte order defined -#endif }; struct bayL1 { -#ifdef __BIG_ENDIAN - u8 g; - u8 b; -#elif __LITTLE_ENDIAN u8 b; u8 g; -#else -#error not byte order defined -#endif }; struct cam_size { diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 8c7eba2a728..7243337b771 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1080,7 +1080,6 @@ static ssize_t usbvision_v4l2_read(struct file *file, char *buf, int noblock = file->f_flags & O_NONBLOCK; unsigned long lock_flags; - int frmx = -1; int ret,i; struct usbvision_frame *frame; @@ -1155,7 +1154,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char *buf, frame->bytes_read = 0; /* Mark it as available to be used again. */ - usbvision->frame[frmx].grabstate = FrameState_Unused; + frame->grabstate = FrameState_Unused; /* } */ return count; diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 752c82c37f5..b87d571e046 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -90,8 +90,15 @@ MODULE_LICENSE("GPL"); char *v4l2_norm_to_name(v4l2_std_id id) { char *name; + u32 myid = id; - switch (id) { + /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle + 64 bit comparations. So, on that architecture, with some gcc variants, + compilation fails. Currently, the max value is 30bit wide. + */ + BUG_ON(myid != id); + + switch (myid) { case V4L2_STD_PAL: name="PAL"; break; case V4L2_STD_PAL_BG: diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index f429f49901b..6504a586684 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c @@ -700,6 +700,7 @@ videobuf_qbuf(struct videobuf_queue *q, goto done; } if (buf->state == STATE_QUEUED || + buf->state == STATE_PREPARED || buf->state == STATE_ACTIVE) { dprintk(1,"qbuf: buffer is already queued or active.\n"); goto done; @@ -1229,7 +1230,7 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr, vaddr,vma->vm_start,vma->vm_end); if (vaddr > vma->vm_end) return NOPAGE_SIGBUS; - page = alloc_page(GFP_USER); + page = alloc_page(GFP_USER | __GFP_DMA32); if (!page) return NOPAGE_OOM; clear_user_page(page_address(page), vaddr, page); diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index bacb311b4f2..d4cf5566673 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -270,10 +270,15 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, char *p,*s,*basep; struct page *pg; u8 chr,r,g,b,color; + unsigned long flags; + spinlock_t spinlock; + + spin_lock_init(&spinlock); /* Get first addr pointed to pixel position */ oldpg=get_addr_pos(pos,pages,to_addr); pg=pfn_to_page(sg_dma_address(to_addr[oldpg].sg) >> PAGE_SHIFT); + spin_lock_irqsave(&spinlock,flags); basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset; /* We will just duplicate the second pixel at the packet */ @@ -376,6 +381,8 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, end: kunmap_atomic(basep, KM_BOUNCE_READ); + spin_unlock_irqrestore(&spinlock,flags); + } static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) { diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 6e068cf1049..b3f28a03b6a 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -5,7 +5,7 @@ * For use with LSI Logic PCI chip/adapter(s) * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) * */ @@ -73,6 +73,7 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); +MODULE_VERSION(my_VERSION); /* * cmd line parameters diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index a4afad4ecab..e316708f76b 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -5,7 +5,7 @@ * LSIFC9xx/LSI409xx Fibre Channel * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) * */ @@ -72,11 +72,11 @@ #endif #ifndef COPYRIGHT -#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR +#define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.04.02" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.02" +#define MPT_LINUX_VERSION_COMMON "3.04.03" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.03" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -1059,7 +1059,7 @@ extern int mpt_stm_index; /* needed by mptstm.c */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* } __KERNEL__ */ -#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__) +#if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__) || defined(__powerpc__) #define CAST_U32_TO_PTR(x) ((void *)(u64)x) #define CAST_PTR_TO_U32(x) ((u32)(u64)x) #else diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 30975ccd994..504632da434 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -4,7 +4,7 @@ * For use with LSI Logic PCI chip/adapters * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) * */ @@ -66,7 +66,7 @@ #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> -#define COPYRIGHT "Copyright (c) 1999-2005 LSI Logic Corporation" +#define COPYRIGHT "Copyright (c) 1999-2007 LSI Logic Corporation" #define MODULEAUTHOR "LSI Logic Corporation" #include "mptbase.h" #include "mptctl.h" @@ -79,6 +79,7 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); +MODULE_VERSION(my_VERSION); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index 043941882c6..e65a1cf5eb0 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h @@ -5,7 +5,7 @@ * LSIFC9xx/LSI409xx Fibre Channel * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) * */ diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index ca2f9107f14..c819c23b55b 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -3,7 +3,7 @@ * For use with LSI Logic PCI chip/adapter(s) * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) * */ @@ -75,6 +75,7 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); +MODULE_VERSION(my_VERSION); /* Command line args */ #define MPTFC_DEV_LOSS_TMO (60) diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index b7c4407c5e3..2936204d8ad 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -4,7 +4,7 @@ * For use with LSI Logic Fibre Channel PCI chip/adapters * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 2000-2005 LSI Logic Corporation + * Copyright (c) 2000-2007 LSI Logic Corporation * */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -56,9 +56,11 @@ #include <linux/module.h> #include <linux/fs.h> +#define my_VERSION MPT_LINUX_VERSION_COMMON #define MYNAM "mptlan" MODULE_LICENSE("GPL"); +MODULE_VERSION(my_VERSION); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h index 3726ecba570..70ab75e7c26 100644 --- a/drivers/message/fusion/mptlan.h +++ b/drivers/message/fusion/mptlan.h @@ -4,7 +4,7 @@ * For use with LSI Logic Fibre Channel PCI chip/adapters * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 2000-2005 LSI Logic Corporation + * Copyright (c) 2000-2007 LSI Logic Corporation * */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 4f0c530e47b..09e9a9d9641 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -3,9 +3,9 @@ * For use with LSI Logic PCI chip/adapter(s) * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) - * Copyright (c) 2005-2006 Dell + * Copyright (c) 2005-2007 Dell */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -75,6 +75,7 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); +MODULE_VERSION(my_VERSION); static int mpt_pt_clear; module_param(mpt_pt_clear, int, 0); @@ -245,7 +246,8 @@ static void mptsas_print_device_pg0(SasDevicePage0_t *pg0) printk("Parent Handle=0x%X\n" ,le16_to_cpu(pg0->ParentDevHandle)); printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)); printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot)); - printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address)); + printk("SAS Address=0x%llX\n", (unsigned long long) + le64_to_cpu(sas_address)); printk("Target ID=0x%X\n", pg0->TargetID); printk("Bus=0x%X\n", pg0->Bus); /* The PhyNum field specifies the PHY number of the parent @@ -349,9 +351,9 @@ mptsas_port_delete(struct mptsas_portinfo_details * port_details) phy_info = port_info->phy_info; dsaswideprintk((KERN_DEBUG "%s: [%p]: num_phys=%02d " - "bitmask=0x%016llX\n", - __FUNCTION__, port_details, port_details->num_phys, - port_details->phy_bitmask)); + "bitmask=0x%016llX\n", __FUNCTION__, port_details, + port_details->num_phys, (unsigned long long) + port_details->phy_bitmask)); for (i = 0; i < port_info->num_phys; i++, phy_info++) { if(phy_info->port_details != port_details) @@ -476,7 +478,7 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) { sas_address = phy_info->attached.sas_address; dsaswideprintk((KERN_DEBUG "phy_id=%d sas_address=0x%018llX\n", - i, sas_address)); + i, (unsigned long long)sas_address)); if (!sas_address) continue; port_details = phy_info->port_details; @@ -495,8 +497,8 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) (1 << phy_info->phy_id); phy_info->sas_port_add_phy=1; dsaswideprintk((KERN_DEBUG "\t\tForming port\n\t\t" - "phy_id=%d sas_address=0x%018llX\n", - i, sas_address)); + "phy_id=%d sas_address=0x%018llX\n", + i, (unsigned long long)sas_address)); phy_info->port_details = port_details; } @@ -512,8 +514,9 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) if (phy_info_cmp->port_details == port_details ) continue; dsaswideprintk((KERN_DEBUG - "\t\tphy_id=%d sas_address=0x%018llX\n", - j, phy_info_cmp->attached.sas_address)); + "\t\tphy_id=%d sas_address=0x%018llX\n", + j, (unsigned long long) + phy_info_cmp->attached.sas_address)); if (phy_info_cmp->port_details) { port_details->rphy = mptsas_get_rphy(phy_info_cmp); @@ -546,11 +549,10 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) if (!port_details) continue; dsaswideprintk((KERN_DEBUG - "%s: [%p]: phy_id=%02d num_phys=%02d " - "bitmask=0x%016llX\n", - __FUNCTION__, - port_details, i, port_details->num_phys, - port_details->phy_bitmask)); + "%s: [%p]: phy_id=%02d num_phys=%02d " + "bitmask=0x%016llX\n", __FUNCTION__, + port_details, i, port_details->num_phys, + (unsigned long long)port_details->phy_bitmask)); dsaswideprintk((KERN_DEBUG"\t\tport = %p rphy=%p\n", port_details->port, port_details->rphy)); } @@ -2079,8 +2081,10 @@ mptsas_persist_clear_table(struct work_struct *work) static void mptsas_reprobe_lun(struct scsi_device *sdev, void *data) { + int rc; + sdev->no_uld_attach = data ? 1 : 0; - scsi_device_reprobe(sdev); + rc = scsi_device_reprobe(sdev); } static void diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 2c72c36b817..f0cca3ea93b 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -3,7 +3,7 @@ * For use with LSI Logic PCI chip/adapter(s) * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) * */ @@ -76,6 +76,7 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); +MODULE_VERSION(my_VERSION); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -701,6 +702,17 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) break; } } + } else if (ioc->bus_type == FC) { + /* + * The FC IOC may kill a request for variety of + * reasons, some of which may be recovered by a + * retry, some which are unlikely to be + * recovered. Return DID_ERROR instead of + * DID_RESET to permit retry of the command, + * just not an infinite number of them + */ + sc->result = DID_ERROR << 16; + break; } /* @@ -2688,7 +2700,8 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev) { dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", - hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd)); + hd->ioc->name, vtarget->bus_id, vtarget->target_id, + sdev->lun, hd)); /* Is LUN supported? If so, upper 2 bits will be 0 * in first byte of inquiry data. @@ -2770,7 +2783,7 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, else { factor = MPT_ULTRA320; if (scsi_device_qas(sdev)) { - ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id)); + ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id)); noQas = 0; } if (sdev->type == TYPE_TAPE && diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index 14a5b6c2e2b..187c8af0890 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -5,7 +5,7 @@ * LSIFC9xx/LSI409xx Fibre Channel * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) * */ diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 36641da5928..203c661d2c7 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -3,7 +3,7 @@ * For use with LSI Logic PCI chip/adapter(s) * running LSI Logic Fusion MPT (Message Passing Technology) firmware. * - * Copyright (c) 1999-2005 LSI Logic Corporation + * Copyright (c) 1999-2007 LSI Logic Corporation * (mailto:mpt_linux_developer@lsil.com) * */ @@ -77,6 +77,7 @@ MODULE_AUTHOR(MODULEAUTHOR); MODULE_DESCRIPTION(my_NAME); MODULE_LICENSE("GPL"); +MODULE_VERSION(my_VERSION); /* Command line args */ static int mpt_saf_te = MPTSCSIH_SAF_TE; diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c index 06e7fcd1922..bfb9ff69320 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/imxmmc.c @@ -351,9 +351,6 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, case MMC_RSP_R3: /* short */ cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3; break; - case MMC_RSP_R6: /* short CRC */ - cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R6; - break; default: break; } diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c index 9488408308f..d30540b2761 100644 --- a/drivers/mmc/omap.c +++ b/drivers/mmc/omap.c @@ -91,7 +91,6 @@ #define DRIVER_NAME "mmci-omap" -#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) /* Specifies how often in millisecs to poll for card status changes * when the cover switch is open */ @@ -204,18 +203,22 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd) cmdtype = 0; /* Our hardware needs to know exact type */ - switch (RSP_TYPE(mmc_resp_type(cmd))) { - case RSP_TYPE(MMC_RSP_R1): - /* resp 1, resp 1b */ + switch (mmc_resp_type(cmd)) { + case MMC_RSP_NONE: + break; + case MMC_RSP_R1: + case MMC_RSP_R1B: + /* resp 1, 1b, 6, 7 */ resptype = 1; break; - case RSP_TYPE(MMC_RSP_R2): + case MMC_RSP_R2: resptype = 2; break; - case RSP_TYPE(MMC_RSP_R3): + case MMC_RSP_R3: resptype = 3; break; default: + dev_err(mmc_dev(host->mmc), "Invalid response type: %04x\n", mmc_resp_type(cmd)); break; } diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index 45a9283ce49..6073d998b11 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -171,7 +171,7 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, #define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) switch (RSP_TYPE(mmc_resp_type(cmd))) { - case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */ + case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6, r7 */ cmdat |= CMDAT_RESP_SHORT; break; case RSP_TYPE(MMC_RSP_R3): diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c index f18ad998b3c..fa4a52886b9 100644 --- a/drivers/mmc/tifm_sd.c +++ b/drivers/mmc/tifm_sd.c @@ -173,9 +173,6 @@ static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) case MMC_RSP_R3: rc |= TIFM_MMCSD_RSP_R3; break; - case MMC_RSP_R6: - rc |= TIFM_MMCSD_RSP_R6; - break; default: BUG(); } diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index f457315579d..bbf0553bdb2 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -204,7 +204,7 @@ config MTD_ESB2ROM config MTD_CK804XROM tristate "BIOS flash chip on Nvidia CK804" - depends on X86 && MTD_JEDECPROBE + depends on X86 && MTD_JEDECPROBE && PCI help Support for treating the BIOS flash chip on nvidia motherboards as an MTD device - with this you can reprogram your BIOS. diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 238d42e88ec..68ed02ecb2e 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c @@ -327,7 +327,7 @@ static int __init init_ck804xrom(void) pdev = NULL; for(id = ck804xrom_pci_tbl; id->vendor; id++) { - pdev = pci_find_device(id->vendor, id->device, NULL); + pdev = pci_get_device(id->vendor, id->device, NULL); if (pdev) break; } diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 358f55a82db..9326a56f0fb 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -223,7 +223,7 @@ config MTD_NAND_SHARPSL config MTD_NAND_CAFE tristate "NAND support for OLPC CAFÉ chip" - depends on PCI + depends on MTD_NAND && PCI help Use NAND flash attached to the CAFÉ chip designed for the $100 laptop. diff --git a/drivers/mtd/nand/cafe.c b/drivers/mtd/nand/cafe.c index b8d9b64cccc..1e877cbe775 100644 --- a/drivers/mtd/nand/cafe.c +++ b/drivers/mtd/nand/cafe.c @@ -14,6 +14,7 @@ #include <linux/pci.h> #include <linux/delay.h> #include <linux/interrupt.h> +#include <linux/dma-mapping.h> #include <asm/io.h> #define CAFE_NAND_CTRL1 0x00 @@ -77,8 +78,9 @@ module_param(regdebug, int, 0644); static int checkecc = 1; module_param(checkecc, int, 0644); -static int slowtiming = 0; -module_param(slowtiming, int, 0644); +static int numtimings; +static int timing[3]; +module_param_array(timing, int, &numtimings, 0644); /* Hrm. Why isn't this already conditional on something in the struct device? */ #define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0) @@ -528,6 +530,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, { struct mtd_info *mtd; struct cafe_priv *cafe; + uint32_t timing1, timing2, timing3; uint32_t ctrl; int err = 0; @@ -579,30 +582,44 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, cafe->nand.block_bad = cafe_nand_block_bad; } + if (numtimings && numtimings != 3) { + dev_warn(&cafe->pdev->dev, "%d timing register values ignored; precisely three are required\n", numtimings); + } + + if (numtimings == 3) { + timing1 = timing[0]; + timing2 = timing[1]; + timing3 = timing[2]; + cafe_dev_dbg(&cafe->pdev->dev, "Using provided timings (%08x %08x %08x)\n", + timing1, timing2, timing3); + } else { + timing1 = cafe_readl(cafe, NAND_TIMING1); + timing2 = cafe_readl(cafe, NAND_TIMING2); + timing3 = cafe_readl(cafe, NAND_TIMING3); + + if (timing1 | timing2 | timing3) { + cafe_dev_dbg(&cafe->pdev->dev, "Timing registers already set (%08x %08x %08x)\n", timing1, timing2, timing3); + } else { + dev_warn(&cafe->pdev->dev, "Timing registers unset; using most conservative defaults\n"); + timing1 = timing2 = timing3 = 0xffffffff; + } + } + /* Start off by resetting the NAND controller completely */ cafe_writel(cafe, 1, NAND_RESET); cafe_writel(cafe, 0, NAND_RESET); - cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); + cafe_writel(cafe, timing1, NAND_TIMING1); + cafe_writel(cafe, timing2, NAND_TIMING2); + cafe_writel(cafe, timing3, NAND_TIMING3); - /* Timings from Marvell's test code (not verified or calculated by us) */ - if (!slowtiming) { - cafe_writel(cafe, 0x01010a0a, NAND_TIMING1); - cafe_writel(cafe, 0x24121212, NAND_TIMING2); - cafe_writel(cafe, 0x11000000, NAND_TIMING3); - } else { - cafe_writel(cafe, 0xffffffff, NAND_TIMING1); - cafe_writel(cafe, 0xffffffff, NAND_TIMING2); - cafe_writel(cafe, 0xffffffff, NAND_TIMING3); - } cafe_writel(cafe, 0xffffffff, NAND_IRQ_MASK); err = request_irq(pdev->irq, &cafe_nand_interrupt, SA_SHIRQ, "CAFE NAND", mtd); if (err) { dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); - goto out_free_dma; } -#if 1 + /* Disable master reset, enable NAND clock */ ctrl = cafe_readl(cafe, GLOBAL_CTRL); ctrl &= 0xffffeff0; @@ -629,32 +646,8 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, cafe_writel(cafe, 0x80000007, GLOBAL_IRQ_MASK); cafe_dev_dbg(&cafe->pdev->dev, "Control %x, IRQ mask %x\n", cafe_readl(cafe, GLOBAL_CTRL), cafe_readl(cafe, GLOBAL_IRQ_MASK)); -#endif -#if 1 - mtd->writesize=2048; - mtd->oobsize = 0x40; - memset(cafe->dmabuf, 0x5a, 2112); - cafe->nand.cmdfunc(mtd, NAND_CMD_READID, 0, -1); - cafe->nand.read_byte(mtd); - cafe->nand.read_byte(mtd); - cafe->nand.read_byte(mtd); - cafe->nand.read_byte(mtd); - cafe->nand.read_byte(mtd); -#endif -#if 0 - cafe->nand.cmdfunc(mtd, NAND_CMD_READ0, 0, 0); - // nand_wait_ready(mtd); - cafe->nand.read_byte(mtd); - cafe->nand.read_byte(mtd); - cafe->nand.read_byte(mtd); - cafe->nand.read_byte(mtd); -#endif -#if 0 - writel(0x84600070, cafe->mmio); - udelay(10); - cafe_dev_dbg(&cafe->pdev->dev, "Status %x\n", cafe_readl(cafe, NAND_NONMEM)); -#endif - /* Scan to find existance of the device */ + + /* Scan to find existence of the device */ if (nand_scan_ident(mtd, 1)) { err = -ENXIO; goto out_irq; @@ -758,13 +751,4 @@ module_exit(cafe_nand_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); -MODULE_DESCRIPTION("NAND flash driver for OLPC CAFE chip"); - -/* Correct ECC for 2048 bytes of 0xff: - 41 a0 71 65 54 27 f3 93 ec a9 be ed 0b a1 */ - -/* dwmw2's B-test board, in case of completely screwing it: -Bad eraseblock 2394 at 0x12b40000 -Bad eraseblock 2627 at 0x14860000 -Bad eraseblock 3349 at 0x1a2a0000 -*/ +MODULE_DESCRIPTION("NAND flash driver for OLPC CAFÉ chip"); diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index e2cb19b582a..6f93a765e56 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -765,17 +765,18 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) struct cp_private *cp = netdev_priv(dev); unsigned entry; u32 eor, flags; + unsigned long intr_flags; #if CP_VLAN_TAG_USED u32 vlan_tag = 0; #endif int mss = 0; - spin_lock_irq(&cp->lock); + spin_lock_irqsave(&cp->lock, intr_flags); /* This is a hard error, log it. */ if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) { netif_stop_queue(dev); - spin_unlock_irq(&cp->lock); + spin_unlock_irqrestore(&cp->lock, intr_flags); printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", dev->name); return 1; @@ -908,7 +909,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1)) netif_stop_queue(dev); - spin_unlock_irq(&cp->lock); + spin_unlock_irqrestore(&cp->lock, intr_flags); cpw8(TxPoll, NormalTxPoll); dev->trans_start = jiffies; diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 8236f26ffd4..640d7ca2ebc 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -1066,8 +1066,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) short length = skb->len; dev->trans_start = jiffies; - DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%x) called\n", dev->name, - skb->len, (unsigned int)skb->data)); + DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%p) called\n", + dev->name, skb->len, skb->data)); if (skb->len < ETH_ZLEN) { if (skb_padto(skb, ETH_ZLEN)) @@ -1246,7 +1246,8 @@ struct net_device * __init i82596_probe(int unit) dev->priv = (void *)(dev->mem_start); lp = dev->priv; - DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n", + DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%zd bytes), " + "lp->scb at 0x%08lx\n", dev->name, (unsigned long)lp, sizeof(struct i596_private), (unsigned long)&lp->scb)); memset((void *) lp, 0, sizeof(struct i596_private)); diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 5eb2ec68393..303a8d94ad4 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -110,6 +110,11 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl); static void b44_halt(struct b44 *); static void b44_init_rings(struct b44 *); + +#define B44_FULL_RESET 1 +#define B44_FULL_RESET_SKIP_PHY 2 +#define B44_PARTIAL_RESET 3 + static void b44_init_hw(struct b44 *, int); static int dma_desc_align_mask; @@ -752,7 +757,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) dest_idx * sizeof(dest_desc), DMA_BIDIRECTIONAL); - pci_dma_sync_single_for_device(bp->pdev, src_desc->addr, + pci_dma_sync_single_for_device(bp->pdev, le32_to_cpu(src_desc->addr), RX_PKT_BUF_SZ, PCI_DMA_FROMDEVICE); } @@ -884,7 +889,7 @@ static int b44_poll(struct net_device *netdev, int *budget) spin_lock_irqsave(&bp->lock, flags); b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY); netif_wake_queue(bp->dev); spin_unlock_irqrestore(&bp->lock, flags); done = 1; @@ -954,7 +959,7 @@ static void b44_tx_timeout(struct net_device *dev) b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); spin_unlock_irq(&bp->lock); @@ -1071,7 +1076,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu) b44_halt(bp); dev->mtu = new_mtu; b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); spin_unlock_irq(&bp->lock); b44_enable_ints(bp); @@ -1368,12 +1373,12 @@ static int b44_set_mac_addr(struct net_device *dev, void *p) * packet processing. Invoked with bp->lock held. */ static void __b44_set_rx_mode(struct net_device *); -static void b44_init_hw(struct b44 *bp, int full_reset) +static void b44_init_hw(struct b44 *bp, int reset_kind) { u32 val; b44_chip_reset(bp); - if (full_reset) { + if (reset_kind == B44_FULL_RESET) { b44_phy_reset(bp); b44_setup_phy(bp); } @@ -1390,7 +1395,10 @@ static void b44_init_hw(struct b44 *bp, int full_reset) bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ - if (full_reset) { + if (reset_kind == B44_PARTIAL_RESET) { + bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | + (bp->rx_offset << DMARX_CTRL_ROSHIFT))); + } else { bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | @@ -1401,9 +1409,6 @@ static void b44_init_hw(struct b44 *bp, int full_reset) bp->rx_prod = bp->rx_pending; bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); - } else { - bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | - (bp->rx_offset << DMARX_CTRL_ROSHIFT))); } val = br32(bp, B44_ENET_CTRL); @@ -1420,7 +1425,7 @@ static int b44_open(struct net_device *dev) goto out; b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); b44_check_phy(bp); @@ -1629,7 +1634,7 @@ static int b44_close(struct net_device *dev) netif_poll_enable(dev); if (bp->flags & B44_FLAG_WOL_ENABLE) { - b44_init_hw(bp, 0); + b44_init_hw(bp, B44_PARTIAL_RESET); b44_setup_wol(bp); } @@ -1905,7 +1910,7 @@ static int b44_set_ringparam(struct net_device *dev, b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); netif_wake_queue(bp->dev); spin_unlock_irq(&bp->lock); @@ -1948,7 +1953,7 @@ static int b44_set_pauseparam(struct net_device *dev, if (bp->flags & B44_FLAG_PAUSE_AUTO) { b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); } else { __b44_set_flow_ctrl(bp, bp->flags); } @@ -2304,7 +2309,7 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state) free_irq(dev->irq, dev); if (bp->flags & B44_FLAG_WOL_ENABLE) { - b44_init_hw(bp, 0); + b44_init_hw(bp, B44_PARTIAL_RESET); b44_setup_wol(bp); } pci_disable_device(pdev); @@ -2315,21 +2320,32 @@ static int b44_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct b44 *bp = netdev_priv(dev); + int rc = 0; pci_restore_state(pdev); - pci_enable_device(pdev); + rc = pci_enable_device(pdev); + if (rc) { + printk(KERN_ERR PFX "%s: pci_enable_device failed\n", + dev->name); + return rc; + } + pci_set_master(pdev); if (!netif_running(dev)) return 0; - if (request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev)) + rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); + if (rc) { printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name); + pci_disable_device(pdev); + return rc; + } spin_lock_irq(&bp->lock); b44_init_rings(bp); - b44_init_hw(bp, 1); + b44_init_hw(bp, B44_FULL_RESET); netif_device_attach(bp->dev); spin_unlock_irq(&bp->lock); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ca5acc4736d..ee7b75b976b 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -57,8 +57,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.5.3" -#define DRV_MODULE_RELDATE "January 8, 2007" +#define DRV_MODULE_VERSION "1.5.5" +#define DRV_MODULE_RELDATE "February 1, 2007" #define RUN_AT(x) (jiffies + (x)) @@ -1356,6 +1356,14 @@ bnx2_init_copper_phy(struct bnx2 *bp) bnx2_write_phy(bp, 0x18, 0x0400); } + if (bp->phy_flags & PHY_DIS_EARLY_DAC_FLAG) { + bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, + MII_BNX2_DSP_EXPAND_REG | 0x8); + bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &val); + val &= ~(1 << 8); + bnx2_write_phy(bp, MII_BNX2_DSP_RW_PORT, val); + } + if (bp->dev->mtu > 1500) { /* Set extended packet length bit */ bnx2_write_phy(bp, 0x18, 0x7); @@ -5845,9 +5853,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE); if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == - BNX2_SHM_HDR_SIGNATURE_SIG) - bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0); - else + BNX2_SHM_HDR_SIGNATURE_SIG) { + u32 off = PCI_FUNC(pdev->devfn) << 2; + + bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0 + off); + } else bp->shmem_base = HOST_VIEW_SHMEM_BASE; /* Get the permanent MAC address. First we need to make sure the @@ -5916,6 +5926,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) } else if (CHIP_NUM(bp) == CHIP_NUM_5706 || CHIP_NUM(bp) == CHIP_NUM_5708) bp->phy_flags |= PHY_CRC_FIX_FLAG; + else if (CHIP_ID(bp) == CHIP_ID_5709_A0) + bp->phy_flags |= PHY_DIS_EARLY_DAC_FLAG; if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || (CHIP_ID(bp) == CHIP_ID_5708_B0) || diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 13b6f9b11e0..ccbdf81c659 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6288,6 +6288,10 @@ struct l2_fhdr { #define BCM5708S_TX_ACTL3 0x17 +#define MII_BNX2_DSP_RW_PORT 0x15 +#define MII_BNX2_DSP_ADDRESS 0x17 +#define MII_BNX2_DSP_EXPAND_REG 0x0f00 + #define MIN_ETHERNET_PACKET_SIZE 60 #define MAX_ETHERNET_PACKET_SIZE 1514 #define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014 @@ -6489,6 +6493,7 @@ struct bnx2 { #define PHY_INT_MODE_MASK_FLAG 0x300 #define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100 #define PHY_INT_MODE_LINK_READY_FLAG 0x200 +#define PHY_DIS_EARLY_DAC_FLAG 0x400 u32 chip_id; /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ @@ -6512,6 +6517,7 @@ struct bnx2 { #define CHIP_ID_5708_A0 0x57080000 #define CHIP_ID_5708_B0 0x57081000 #define CHIP_ID_5708_B1 0x57081010 +#define CHIP_ID_5709_A0 0x57090000 #define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf) diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index dc434fb6da8..0978c9ac6d2 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -151,8 +151,8 @@ struct slave { struct slave *next; struct slave *prev; int delay; - u32 jiffies; - u32 last_arp_rx; + unsigned long jiffies; + unsigned long last_arp_rx; s8 link; /* one of BOND_LINK_XXXX */ s8 state; /* one of BOND_STATE_XXXX */ u32 original_flags; @@ -242,7 +242,8 @@ extern inline int slave_do_arp_validate(struct bonding *bond, struct slave *slav return bond->params.arp_validate & (1 << slave->state); } -extern inline u32 slave_last_rx(struct bonding *bond, struct slave *slave) +extern inline unsigned long slave_last_rx(struct bonding *bond, + struct slave *slave) { if (slave_do_arp_validate(bond, slave)) return slave->last_arp_rx; diff --git a/drivers/net/e100.c b/drivers/net/e100.c index c2ae2a24629..0cefef5e3f0 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2718,12 +2718,11 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); -#ifdef CONFIG_E100_NAPI if (netif_running(netdev)) netif_poll_disable(nic->netdev); -#endif del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); + netif_device_detach(netdev); pci_save_state(pdev); @@ -2736,6 +2735,7 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) } pci_disable_device(pdev); + free_irq(pdev->irq, netdev); pci_set_power_state(pdev, PCI_D3hot); return 0; @@ -2759,16 +2759,13 @@ static int e100_resume(struct pci_dev *pdev) } #endif /* CONFIG_PM */ - static void e100_shutdown(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); -#ifdef CONFIG_E100_NAPI if (netif_running(netdev)) netif_poll_disable(nic->netdev); -#endif del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 39ad9f73d1e..272e1ec51aa 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -39,7 +39,7 @@ #include <asm/io.h> #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0043" +#define DRV_VERSION "EHEA_0045" #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 83fa32f7239..9de2d38a532 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -558,12 +558,12 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) u32 qp_token; eqe = ehea_poll_eq(port->qp_eq); - ehea_debug("eqe=%p", eqe); + while (eqe) { - ehea_debug("*eqe=%lx", *(u64*)eqe); - eqe = ehea_poll_eq(port->qp_eq); qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); - ehea_debug("next eqe=%p", eqe); + ehea_error("QP aff_err: entry=0x%lx, token=0x%x", + eqe->entry, qp_token); + eqe = ehea_poll_eq(port->qp_eq); } return IRQ_HANDLED; @@ -575,8 +575,9 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter, int i; for (i = 0; i < adapter->num_ports; i++) - if (adapter->port[i]->logical_port_id == logical_port) - return adapter->port[i]; + if (adapter->port[i]) + if (adapter->port[i]->logical_port_id == logical_port) + return adapter->port[i]; return NULL; } @@ -642,6 +643,8 @@ int ehea_sense_port_attr(struct ehea_port *port) break; } + port->autoneg = 1; + /* Number of default QPs */ port->num_def_qps = cb0->num_default_qps; @@ -728,10 +731,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed) } } else { if (hret == H_AUTHORITY) { - ehea_info("Hypervisor denied setting port speed. Either" - " this partition is not authorized to set " - "port speed or another partition has modified" - " port speed first."); + ehea_info("Hypervisor denied setting port speed"); ret = -EPERM; } else { ret = -EIO; @@ -998,7 +998,7 @@ static int ehea_configure_port(struct ehea_port *port) | EHEA_BMASK_SET(PXLY_RC_JUMBO_FRAME, 1); for (i = 0; i < port->num_def_qps; i++) - cb0->default_qpn_arr[i] = port->port_res[i].qp->init_attr.qp_nr; + cb0->default_qpn_arr[i] = port->port_res[0].qp->init_attr.qp_nr; if (netif_msg_ifup(port)) ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port"); @@ -1485,11 +1485,12 @@ out: static void ehea_promiscuous_error(u64 hret, int enable) { - ehea_info("Hypervisor denied %sabling promiscuous mode.%s", - enable == 1 ? "en" : "dis", - hret != H_AUTHORITY ? "" : " Another partition owning a " - "logical port on the same physical port might have altered " - "promiscuous mode first."); + if (hret == H_AUTHORITY) + ehea_info("Hypervisor denied %sabling promiscuous mode", + enable == 1 ? "en" : "dis"); + else + ehea_error("failed %sabling promiscuous mode", + enable == 1 ? "en" : "dis"); } static void ehea_promiscuous(struct net_device *dev, int enable) @@ -2267,6 +2268,8 @@ static void ehea_tx_watchdog(struct net_device *dev) int ehea_sense_adapter_attr(struct ehea_adapter *adapter) { struct hcp_query_ehea *cb; + struct device_node *lhea_dn = NULL; + struct device_node *eth_dn = NULL; u64 hret; int ret; @@ -2283,7 +2286,18 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter) goto out_herr; } - adapter->num_ports = cb->num_ports; + /* Determine the number of available logical ports + * by counting the child nodes of the lhea OFDT entry + */ + adapter->num_ports = 0; + lhea_dn = of_find_node_by_name(lhea_dn, "lhea"); + do { + eth_dn = of_get_next_child(lhea_dn, eth_dn); + if (eth_dn) + adapter->num_ports++; + } while ( eth_dn ); + of_node_put(lhea_dn); + adapter->max_mc_mac = cb->max_mc_mac - 1; ret = 0; @@ -2302,6 +2316,7 @@ static int ehea_setup_single_port(struct ehea_port *port, struct ehea_adapter *adapter = port->adapter; struct hcp_ehea_port_cb4 *cb4; u32 *dn_log_port_id; + int jumbo = 0; sema_init(&port->port_lock, 1); port->state = EHEA_PORT_DOWN; @@ -2334,8 +2349,6 @@ static int ehea_setup_single_port(struct ehea_port *port, INIT_LIST_HEAD(&port->mc_list->list); - ehea_set_portspeed(port, EHEA_SPEED_AUTONEG); - ret = ehea_sense_port_attr(port); if (ret) goto out; @@ -2345,13 +2358,25 @@ static int ehea_setup_single_port(struct ehea_port *port, if (!cb4) { ehea_error("no mem for cb4"); } else { - cb4->jumbo_frame = 1; - hret = ehea_h_modify_ehea_port(adapter->handle, - port->logical_port_id, - H_PORT_CB4, H_PORT_CB4_JUMBO, - cb4); - if (hret != H_SUCCESS) { - ehea_info("Jumbo frames not activated"); + hret = ehea_h_query_ehea_port(adapter->handle, + port->logical_port_id, + H_PORT_CB4, + H_PORT_CB4_JUMBO, cb4); + + if (hret == H_SUCCESS) { + if (cb4->jumbo_frame) + jumbo = 1; + else { + cb4->jumbo_frame = 1; + hret = ehea_h_modify_ehea_port(adapter->handle, + port-> + logical_port_id, + H_PORT_CB4, + H_PORT_CB4_JUMBO, + cb4); + if (hret == H_SUCCESS) + jumbo = 1; + } } kfree(cb4); } @@ -2390,6 +2415,9 @@ static int ehea_setup_single_port(struct ehea_port *port, goto out_free; } + ehea_info("%s: Jumbo frames are %sabled", dev->name, + jumbo == 1 ? "en" : "dis"); + port->netdev = dev; ret = 0; goto out; @@ -2471,14 +2499,16 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev, adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle", NULL); - if (!adapter_handle) { + if (adapter_handle) + adapter->handle = *adapter_handle; + + if (!adapter->handle) { dev_err(&dev->ofdev.dev, "failed getting handle for adapter" " '%s'\n", dev->ofdev.node->full_name); ret = -ENODEV; goto out_free_ad; } - adapter->handle = *adapter_handle; adapter->pd = EHEA_PD_ID; dev->ofdev.dev.driver_data = adapter; @@ -2568,6 +2598,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev) destroy_workqueue(adapter->ehea_wq); ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); + tasklet_kill(&adapter->neq_tasklet); ehea_destroy_eq(adapter->neq); diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 0cfc2bc1a27..37716e05e80 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c @@ -94,6 +94,7 @@ static long ehea_plpar_hcall9(unsigned long opcode, { long ret; int i, sleep_msecs; + u8 cb_cat; for (i = 0; i < 5; i++) { ret = plpar_hcall9(opcode, outs, @@ -106,7 +107,13 @@ static long ehea_plpar_hcall9(unsigned long opcode, continue; } - if (ret < H_SUCCESS) + cb_cat = EHEA_BMASK_GET(H_MEHEAPORT_CAT, arg2); + + if ((ret < H_SUCCESS) && !(((ret == H_AUTHORITY) + && (opcode == H_MODIFY_HEA_PORT)) + && (((cb_cat == H_PORT_CB4) && ((arg3 == H_PORT_CB4_JUMBO) + || (arg3 == H_PORT_CB4_SPEED))) || ((cb_cat == H_PORT_CB7) + && (arg3 == H_PORT_CB7_DUCQPN))))) ehea_error("opcode=%lx ret=%lx" " arg1=%lx arg2=%lx arg3=%lx arg4=%lx" " arg5=%lx arg6=%lx arg7=%lx arg8=%lx" @@ -120,7 +127,6 @@ static long ehea_plpar_hcall9(unsigned long opcode, outs[0], outs[1], outs[2], outs[3], outs[4], outs[5], outs[6], outs[7], outs[8]); - return ret; } diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index c2c5fd419bd..ff683947730 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -104,9 +104,9 @@ static int do_pd_setup(struct fs_enet_private *fep) fep->interrupt = platform_get_irq_byname(pdev,"interrupt"); if (fep->interrupt < 0) return -EINVAL; - + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); - fep->fec.fecp =(void*)r->start; + fep->fec.fecp = ioremap(r->start, r->end - r->start + 1); if(fep->fec.fecp == NULL) return -EINVAL; @@ -319,11 +319,14 @@ static void restart(struct net_device *dev) * Clear any outstanding interrupt. */ FW(fecp, ievent, 0xffc0); +#ifndef CONFIG_PPC_MERGE FW(fecp, ivec, (fep->interrupt / 2) << 29); - +#else + FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29); +#endif /* - * adjust to speed (only for DUET & RMII) + * adjust to speed (only for DUET & RMII) */ #ifdef CONFIG_DUET if (fpi->use_rmii) { @@ -418,6 +421,7 @@ static void stop(struct net_device *dev) static void pre_request_irq(struct net_device *dev, int irq) { +#ifndef CONFIG_PPC_MERGE immap_t *immap = fs_enet_immap; u32 siel; @@ -431,6 +435,7 @@ static void pre_request_irq(struct net_device *dev, int irq) siel &= ~(0x80000000 >> (irq & ~1)); out_be32(&immap->im_siu_conf.sc_siel, siel); } +#endif } static void post_free_irq(struct net_device *dev, int irq) diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 95ec5872c50..afd7fca7c6c 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -121,13 +121,13 @@ static int do_pd_setup(struct fs_enet_private *fep) return -EINVAL; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); - fep->scc.sccp = (void *)r->start; + fep->scc.sccp = ioremap(r->start, r->end - r->start + 1); if (fep->scc.sccp == NULL) return -EINVAL; r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram"); - fep->scc.ep = (void *)r->start; + fep->scc.ep = ioremap(r->start, r->end - r->start + 1); if (fep->scc.ep == NULL) return -EINVAL; @@ -397,6 +397,7 @@ static void stop(struct net_device *dev) static void pre_request_irq(struct net_device *dev, int irq) { +#ifndef CONFIG_PPC_MERGE immap_t *immap = fs_enet_immap; u32 siel; @@ -410,6 +411,7 @@ static void pre_request_irq(struct net_device *dev, int irq) siel &= ~(0x80000000 >> (irq & ~1)); out_be32(&immap->im_siu_conf.sc_siel, siel); } +#endif } static void post_free_irq(struct net_device *dev, int irq) diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig index 896aa02000d..feb0ada7a02 100644 --- a/drivers/net/hamradio/Kconfig +++ b/drivers/net/hamradio/Kconfig @@ -113,7 +113,7 @@ config SCC_TRXECHO config BAYCOM_SER_FDX tristate "BAYCOM ser12 fullduplex driver for AX.25" - depends on AX25 + depends on AX25 && !S390 select CRC_CCITT ---help--- This is one of two drivers for Baycom style simple amateur radio @@ -133,7 +133,7 @@ config BAYCOM_SER_FDX config BAYCOM_SER_HDX tristate "BAYCOM ser12 halfduplex driver for AX.25" - depends on AX25 + depends on AX25 && !S390 select CRC_CCITT ---help--- This is one of two drivers for Baycom style simple amateur radio @@ -181,7 +181,7 @@ config BAYCOM_EPP config YAM tristate "YAM driver for AX.25" - depends on AX25 + depends on AX25 && !S390 help The YAM is a modem for packet radio which connects to the serial port and includes some of the functions of a Terminal Node diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 3ca1082ec77..340ee99652e 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -441,25 +441,13 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) goto drop; } - /* Make sure there is room for IrDA-USB header. The actual - * allocation will be done lower in skb_push(). - * Also, we don't use directly skb_cow(), because it require - * headroom >= 16, which force unnecessary copies - Jean II */ - if (skb_headroom(skb) < self->header_length) { - IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); - if (skb_cow(skb, self->header_length)) { - IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); - goto drop; - } - } + memcpy(self->tx_buff + self->header_length, skb->data, skb->len); /* Change setting for next frame */ - if (self->capability & IUC_STIR421X) { __u8 turnaround_time; - __u8* frame; + __u8* frame = self->tx_buff; turnaround_time = get_turnaround_time( skb ); - frame= skb_push(skb, self->header_length); irda_usb_build_header(self, frame, 0); frame[2] = turnaround_time; if ((skb->len != 0) && @@ -472,17 +460,17 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) frame[1] = 0; } } else { - irda_usb_build_header(self, skb_push(skb, self->header_length), 0); + irda_usb_build_header(self, self->tx_buff, 0); } /* FIXME: Make macro out of this one */ ((struct irda_skb_cb *)skb->cb)->context = self; - usb_fill_bulk_urb(urb, self->usbdev, + usb_fill_bulk_urb(urb, self->usbdev, usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), - skb->data, IRDA_SKB_MAX_MTU, + self->tx_buff, skb->len + self->header_length, write_bulk_callback, skb); - urb->transfer_buffer_length = skb->len; + /* This flag (URB_ZERO_PACKET) indicates that what we send is not * a continuous stream of data but separate packets. * In this case, the USB layer will insert an empty USB frame (TD) @@ -1455,6 +1443,9 @@ static inline void irda_usb_close(struct irda_usb_cb *self) /* Remove the speed buffer */ kfree(self->speed_buff); self->speed_buff = NULL; + + kfree(self->tx_buff); + self->tx_buff = NULL; } /********************** USB CONFIG SUBROUTINES **********************/ @@ -1524,8 +1515,6 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_ IRDA_DEBUG(0, "%s(), And our endpoints are : in=%02X, out=%02X (%d), int=%02X\n", __FUNCTION__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep); - /* Should be 8, 16, 32 or 64 bytes */ - IRDA_ASSERT(self->bulk_out_mtu == 64, ;); return((self->bulk_in_ep != 0) && (self->bulk_out_ep != 0)); } @@ -1753,9 +1742,14 @@ static int irda_usb_probe(struct usb_interface *intf, memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU); + self->tx_buff = kzalloc(IRDA_SKB_MAX_MTU + self->header_length, + GFP_KERNEL); + if (self->tx_buff == NULL) + goto err_out_4; + ret = irda_usb_open(self); if (ret) - goto err_out_4; + goto err_out_5; IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); usb_set_intfdata(intf, self); @@ -1766,14 +1760,14 @@ static int irda_usb_probe(struct usb_interface *intf, self->needspatch = (ret < 0); if (self->needspatch) { IRDA_ERROR("STIR421X: Couldn't upload patch\n"); - goto err_out_5; + goto err_out_6; } /* replace IrDA class descriptor with what patched device is now reporting */ irda_desc = irda_usb_find_class_desc (self->usbintf); if (irda_desc == NULL) { ret = -ENODEV; - goto err_out_5; + goto err_out_6; } if (self->irda_desc) kfree (self->irda_desc); @@ -1782,9 +1776,10 @@ static int irda_usb_probe(struct usb_interface *intf, } return 0; - -err_out_5: +err_out_6: unregister_netdev(self->netdev); +err_out_5: + kfree(self->tx_buff); err_out_4: kfree(self->speed_buff); err_out_3: diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h index 6b2271f18e7..e846c38224a 100644 --- a/drivers/net/irda/irda-usb.h +++ b/drivers/net/irda/irda-usb.h @@ -156,6 +156,7 @@ struct irda_usb_cb { struct irlap_cb *irlap; /* The link layer we are binded to */ struct qos_info qos; char *speed_buff; /* Buffer for speed changes */ + char *tx_buff; struct timeval stamp; struct timeval now; diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index c14a74634fd..20d306fea4c 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -59,7 +59,7 @@ #include <asm/byteorder.h> #include <asm/unaligned.h> -MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); +MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>"); MODULE_DESCRIPTION("IrDA-USB Dongle Driver for SigmaTel STIr4200"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 18c68193bf1..e2b1af61845 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -166,7 +166,7 @@ static void vlsi_proc_pdev(struct seq_file *seq, struct pci_dev *pdev) unsigned i; seq_printf(seq, "\n%s (vid/did: %04x/%04x)\n", - PCIDEV_NAME(pdev), (int)pdev->vendor, (int)pdev->device); + pci_name(pdev), (int)pdev->vendor, (int)pdev->device); seq_printf(seq, "pci-power-state: %u\n", (unsigned) pdev->current_state); seq_printf(seq, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n", pdev->irq, (unsigned)pci_resource_start(pdev, 0), (unsigned long long)pdev->dma_mask); @@ -1401,7 +1401,7 @@ static void vlsi_tx_timeout(struct net_device *ndev) if (vlsi_start_hw(idev)) IRDA_ERROR("%s: failed to restart hw - %s(%s) unusable!\n", - __FUNCTION__, PCIDEV_NAME(idev->pdev), ndev->name); + __FUNCTION__, pci_name(idev->pdev), ndev->name); else netif_start_queue(ndev); } @@ -1643,7 +1643,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) pdev->current_state = 0; /* hw must be running now */ IRDA_MESSAGE("%s: IrDA PCI controller %s detected\n", - drivername, PCIDEV_NAME(pdev)); + drivername, pci_name(pdev)); if ( !pci_resource_start(pdev,0) || !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) { @@ -1728,7 +1728,7 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); - IRDA_MESSAGE("%s: %s removed\n", drivername, PCIDEV_NAME(pdev)); + IRDA_MESSAGE("%s: %s removed\n", drivername, pci_name(pdev)); } #ifdef CONFIG_PM @@ -1748,7 +1748,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) if (!ndev) { IRDA_ERROR("%s - %s: no netdevice \n", - __FUNCTION__, PCIDEV_NAME(pdev)); + __FUNCTION__, pci_name(pdev)); return 0; } idev = ndev->priv; @@ -1759,7 +1759,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) pdev->current_state = state.event; } else - IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __FUNCTION__, PCIDEV_NAME(pdev), pdev->current_state, state.event); + IRDA_ERROR("%s - %s: invalid suspend request %u -> %u\n", __FUNCTION__, pci_name(pdev), pdev->current_state, state.event); up(&idev->sem); return 0; } @@ -1787,7 +1787,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev) if (!ndev) { IRDA_ERROR("%s - %s: no netdevice \n", - __FUNCTION__, PCIDEV_NAME(pdev)); + __FUNCTION__, pci_name(pdev)); return 0; } idev = ndev->priv; @@ -1795,7 +1795,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev) if (pdev->current_state == 0) { up(&idev->sem); IRDA_WARNING("%s - %s: already resumed\n", - __FUNCTION__, PCIDEV_NAME(pdev)); + __FUNCTION__, pci_name(pdev)); return 0; } diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index c37f0bc4c7f..2d3b773d8e3 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h @@ -41,39 +41,6 @@ #define PCI_CLASS_SUBCLASS_MASK 0xffff #endif -/* in recent 2.5 interrupt handlers have non-void return value */ -#ifndef IRQ_RETVAL -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif - -/* some stuff need to check kernelversion. Not all 2.5 stuff was present - * in early 2.5.x - the test is merely to separate 2.4 from 2.5 - */ -#include <linux/version.h> - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - -/* PDE() introduced in 2.5.4 */ -#ifdef CONFIG_PROC_FS -#define PDE(inode) ((inode)->i_private) -#endif - -/* irda crc16 calculation exported in 2.5.42 */ -#define irda_calc_crc16(fcs,buf,len) (GOOD_FCS) - -/* we use this for unified pci device name access */ -#define PCIDEV_NAME(pdev) ((pdev)->name) - -#else /* 2.5 or later */ - -/* whatever we get from the associated struct device - bus:slot:dev.fn id */ -#define PCIDEV_NAME(pdev) (pci_name(pdev)) - -#endif - /* ================================================================ */ /* non-standard PCI registers */ diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index c41ae4286ee..b3bf8642273 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -314,6 +314,13 @@ int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) while (mp->tx_desc_count > 0) { spin_lock_irqsave(&mp->lock, flags); + + /* tx_desc_count might have changed before acquiring the lock */ + if (mp->tx_desc_count <= 0) { + spin_unlock_irqrestore(&mp->lock, flags); + return released; + } + tx_index = mp->tx_used_desc_q; desc = &mp->p_tx_desc_area[tx_index]; cmd_sts = desc->cmd_sts; @@ -332,13 +339,13 @@ int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) if (skb) mp->tx_skb[tx_index] = NULL; - spin_unlock_irqrestore(&mp->lock, flags); - if (cmd_sts & ETH_ERROR_SUMMARY) { printk("%s: Error in TX\n", dev->name); mp->stats.tx_errors++; } + spin_unlock_irqrestore(&mp->lock, flags); + if (cmd_sts & ETH_TX_FIRST_DESC) dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); else diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 07cf574197e..61cbd4a6044 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -71,7 +71,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.1.0" +#define MYRI10GE_VERSION_STR "1.2.0" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -274,6 +274,10 @@ static int myri10ge_fill_thresh = 256; module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); +static int myri10ge_wcfifo = 1; +module_param(myri10ge_wcfifo, int, S_IRUGO); +MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); + #define MYRI10GE_FW_OFFSET 1024*1024 #define MYRI10GE_HIGHPART_TO_U32(X) \ (sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) @@ -1714,7 +1718,7 @@ static int myri10ge_open(struct net_device *dev) goto abort_with_irq; } - if (mgp->mtrr >= 0) { + if (myri10ge_wcfifo && mgp->mtrr >= 0) { mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4; mgp->rx_small.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL; @@ -2878,7 +2882,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->hard_start_xmit = myri10ge_xmit; netdev->get_stats = myri10ge_get_stats; netdev->base_addr = mgp->iomem_base; - netdev->irq = pdev->irq; netdev->change_mtu = myri10ge_change_mtu; netdev->set_multicast_list = myri10ge_set_multicast_list; netdev->set_mac_address = myri10ge_set_mac_address; @@ -2888,6 +2891,15 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->poll = myri10ge_poll; netdev->weight = myri10ge_napi_weight; + /* make sure we can get an irq, and that MSI can be + * setup (if available). Also ensure netdev->irq + * is set to correct value if MSI is enabled */ + status = myri10ge_request_irq(mgp); + if (status != 0) + goto abort_with_firmware; + netdev->irq = pdev->irq; + myri10ge_free_irq(mgp); + /* Save configuration space to be restored if the * nic resets due to a parity error */ pci_save_state(pdev); @@ -2903,8 +2915,9 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "register_netdev failed: %d\n", status); goto abort_with_state; } - dev_info(dev, "%d, tx bndry %d, fw %s, WC %s\n", - pdev->irq, mgp->tx.boundary, mgp->fw_name, + dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n", + (mgp->msi_enabled ? "MSI" : "xPIC"), + netdev->irq, mgp->tx.boundary, mgp->fw_name, (mgp->mtrr >= 0 ? "Enabled" : "Disabled")); return 0; diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 6490acf0530..e8598b80922 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -63,12 +63,11 @@ #include "netxen_nic_hw.h" -#define NETXEN_NIC_BUILD_NO "4" +#define NETXEN_NIC_BUILD_NO "2" #define _NETXEN_NIC_LINUX_MAJOR 3 #define _NETXEN_NIC_LINUX_MINOR 3 -#define _NETXEN_NIC_LINUX_SUBVERSION 2 -#define NETXEN_NIC_LINUX_VERSIONID "3.3.2" "-" NETXEN_NIC_BUILD_NO -#define NETXEN_NIC_FW_VERSIONID "3.3.2" +#define _NETXEN_NIC_LINUX_SUBVERSION 3 +#define NETXEN_NIC_LINUX_VERSIONID "3.3.3" "-" NETXEN_NIC_BUILD_NO #define RCV_DESC_RINGSIZE \ (sizeof(struct rcv_desc) * adapter->max_rx_desc_count) @@ -240,49 +239,39 @@ extern unsigned long long netxen_dma_mask; typedef u32 netxen_ctx_msg; -#define _netxen_set_bits(config_word, start, bits, val) {\ - unsigned long long mask = (((1ULL << (bits)) - 1) << (start)); \ - unsigned long long value = (val); \ - (config_word) &= ~mask; \ - (config_word) |= (((value) << (start)) & mask); \ -} - #define netxen_set_msg_peg_id(config_word, val) \ - _netxen_set_bits(config_word, 0, 2, val) + ((config_word) &= ~3, (config_word) |= val & 3) #define netxen_set_msg_privid(config_word) \ - set_bit(2, (unsigned long*)&config_word) + ((config_word) |= 1 << 2) #define netxen_set_msg_count(config_word, val) \ - _netxen_set_bits(config_word, 3, 15, val) + ((config_word) &= ~(0x7fff<<3), (config_word) |= (val & 0x7fff) << 3) #define netxen_set_msg_ctxid(config_word, val) \ - _netxen_set_bits(config_word, 18, 10, val) + ((config_word) &= ~(0x3ff<<18), (config_word) |= (val & 0x3ff) << 18) #define netxen_set_msg_opcode(config_word, val) \ - _netxen_set_bits(config_word, 28, 4, val) + ((config_word) &= ~(0xf<<24), (config_word) |= (val & 0xf) << 24) struct netxen_rcv_context { - u32 rcv_ring_addr_lo; - u32 rcv_ring_addr_hi; - u32 rcv_ring_size; - u32 rsrvd; + __le64 rcv_ring_addr; + __le32 rcv_ring_size; + __le32 rsrvd; }; struct netxen_ring_ctx { /* one command ring */ - u64 cmd_consumer_offset; - u32 cmd_ring_addr_lo; - u32 cmd_ring_addr_hi; - u32 cmd_ring_size; - u32 rsrvd; + __le64 cmd_consumer_offset; + __le64 cmd_ring_addr; + __le32 cmd_ring_size; + __le32 rsrvd; /* three receive rings */ struct netxen_rcv_context rcv_ctx[3]; /* one status ring */ - u32 sts_ring_addr_lo; - u32 sts_ring_addr_hi; - u32 sts_ring_size; + __le64 sts_ring_addr; + __le32 sts_ring_size; - u32 ctx_id; + __le32 ctx_id; } __attribute__ ((aligned(64))); /* @@ -306,81 +295,85 @@ struct netxen_ring_ctx { ((cmd_desc)->port_ctxid |= ((var) & 0x0F)) #define netxen_set_cmd_desc_flags(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->flags_opcode, 0, 7, val) + ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \ + (cmd_desc)->flags_opcode |= cpu_to_le16((val) & 0x7f)) #define netxen_set_cmd_desc_opcode(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->flags_opcode, 7, 6, val) + ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x3f<<7), \ + (cmd_desc)->flags_opcode |= cpu_to_le16((val) & (0x3f<<7))) #define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 0, 8, val); + ((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xff), \ + (cmd_desc)->num_of_buffers_total_length |= cpu_to_le32((val) & 0xff)) #define netxen_set_cmd_desc_totallength(cmd_desc, val) \ - _netxen_set_bits((cmd_desc)->num_of_buffers_total_length, 8, 24, val); + ((cmd_desc)->num_of_buffers_total_length &= cpu_to_le32(0xff), \ + (cmd_desc)->num_of_buffers_total_length |= cpu_to_le32(val << 24)) #define netxen_get_cmd_desc_opcode(cmd_desc) \ - (((cmd_desc)->flags_opcode >> 7) & 0x003F) + ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003F) #define netxen_get_cmd_desc_totallength(cmd_desc) \ - (((cmd_desc)->num_of_buffers_total_length >> 8) & 0x0FFFFFF) + (le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) struct cmd_desc_type0 { u8 tcp_hdr_offset; /* For LSO only */ u8 ip_hdr_offset; /* For LSO only */ /* Bit pattern: 0-6 flags, 7-12 opcode, 13-15 unused */ - u16 flags_opcode; + __le16 flags_opcode; /* Bit pattern: 0-7 total number of segments, 8-31 Total size of the packet */ - u32 num_of_buffers_total_length; + __le32 num_of_buffers_total_length; union { struct { - u32 addr_low_part2; - u32 addr_high_part2; + __le32 addr_low_part2; + __le32 addr_high_part2; }; - u64 addr_buffer2; + __le64 addr_buffer2; }; - u16 reference_handle; /* changed to u16 to add mss */ - u16 mss; /* passed by NDIS_PACKET for LSO */ + __le16 reference_handle; /* changed to u16 to add mss */ + __le16 mss; /* passed by NDIS_PACKET for LSO */ /* Bit pattern 0-3 port, 0-3 ctx id */ u8 port_ctxid; u8 total_hdr_length; /* LSO only : MAC+IP+TCP Hdr size */ - u16 conn_id; /* IPSec offoad only */ + __le16 conn_id; /* IPSec offoad only */ union { struct { - u32 addr_low_part3; - u32 addr_high_part3; + __le32 addr_low_part3; + __le32 addr_high_part3; }; - u64 addr_buffer3; + __le64 addr_buffer3; }; union { struct { - u32 addr_low_part1; - u32 addr_high_part1; + __le32 addr_low_part1; + __le32 addr_high_part1; }; - u64 addr_buffer1; + __le64 addr_buffer1; }; - u16 buffer1_length; - u16 buffer2_length; - u16 buffer3_length; - u16 buffer4_length; + __le16 buffer1_length; + __le16 buffer2_length; + __le16 buffer3_length; + __le16 buffer4_length; union { struct { - u32 addr_low_part4; - u32 addr_high_part4; + __le32 addr_low_part4; + __le32 addr_high_part4; }; - u64 addr_buffer4; + __le64 addr_buffer4; }; - u64 unused; + __le64 unused; } __attribute__ ((aligned(64))); /* Note: sizeof(rcv_desc) should always be a mutliple of 2 */ struct rcv_desc { - u16 reference_handle; - u16 reserved; - u32 buffer_length; /* allocated buffer length (usually 2K) */ - u64 addr_buffer; + __le16 reference_handle; + __le16 reserved; + __le32 buffer_length; /* allocated buffer length (usually 2K) */ + __le64 addr_buffer; }; /* opcode field in status_desc */ @@ -406,36 +399,36 @@ struct rcv_desc { (((status_desc)->lro & 0x80) >> 7) #define netxen_get_sts_port(status_desc) \ - ((status_desc)->status_desc_data & 0x0F) + (le64_to_cpu((status_desc)->status_desc_data) & 0x0F) #define netxen_get_sts_status(status_desc) \ - (((status_desc)->status_desc_data >> 4) & 0x0F) + ((le64_to_cpu((status_desc)->status_desc_data) >> 4) & 0x0F) #define netxen_get_sts_type(status_desc) \ - (((status_desc)->status_desc_data >> 8) & 0x0F) + ((le64_to_cpu((status_desc)->status_desc_data) >> 8) & 0x0F) #define netxen_get_sts_totallength(status_desc) \ - (((status_desc)->status_desc_data >> 12) & 0xFFFF) + ((le64_to_cpu((status_desc)->status_desc_data) >> 12) & 0xFFFF) #define netxen_get_sts_refhandle(status_desc) \ - (((status_desc)->status_desc_data >> 28) & 0xFFFF) + ((le64_to_cpu((status_desc)->status_desc_data) >> 28) & 0xFFFF) #define netxen_get_sts_prot(status_desc) \ - (((status_desc)->status_desc_data >> 44) & 0x0F) + ((le64_to_cpu((status_desc)->status_desc_data) >> 44) & 0x0F) #define netxen_get_sts_owner(status_desc) \ - (((status_desc)->status_desc_data >> 56) & 0x03) + ((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03) #define netxen_get_sts_opcode(status_desc) \ - (((status_desc)->status_desc_data >> 58) & 0x03F) + ((le64_to_cpu((status_desc)->status_desc_data) >> 58) & 0x03F) #define netxen_clear_sts_owner(status_desc) \ ((status_desc)->status_desc_data &= \ - ~(((unsigned long long)3) << 56 )) + ~cpu_to_le64(((unsigned long long)3) << 56 )) #define netxen_set_sts_owner(status_desc, val) \ ((status_desc)->status_desc_data |= \ - (((unsigned long long)((val) & 0x3)) << 56 )) + cpu_to_le64(((unsigned long long)((val) & 0x3)) << 56 )) struct status_desc { /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length 28-43 reference_handle, 44-47 protocol, 48-52 unused 53-55 desc_cnt, 56-57 owner, 58-63 opcode */ - u64 status_desc_data; - u32 hash_value; + __le64 status_desc_data; + __le32 hash_value; u8 hash_type; u8 msg_type; u8 unused; @@ -1006,9 +999,9 @@ void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, int port, void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int port, long enable); int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, long reg, - __le32 * readval); + __u32 * readval); int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long phy, - long reg, __le32 val); + long reg, __u32 val); /* Functions available from netxen_nic_hw.c */ int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 34044616b3c..c381d77a733 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -218,7 +218,7 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 status; + __u32 status; /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { @@ -226,7 +226,7 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (adapter->phy_write && adapter->phy_write(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32) ecmd->autoneg) != 0) + ecmd->autoneg) != 0) return -EIO; else port->link_autoneg = ecmd->autoneg; @@ -279,7 +279,7 @@ static int netxen_nic_get_regs_len(struct net_device *dev) } struct netxen_niu_regs { - __le32 reg[NETXEN_NIC_REGS_COUNT]; + __u32 reg[NETXEN_NIC_REGS_COUNT]; }; static struct netxen_niu_regs niu_registers[] = { @@ -372,7 +372,7 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 mode, *regs_buff = p; + __u32 mode, *regs_buff = p; void __iomem *addr; int i, window; @@ -415,7 +415,7 @@ static u32 netxen_nic_get_link(struct net_device *dev) { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 status; + __u32 status; /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { @@ -482,13 +482,13 @@ netxen_nic_get_pauseparam(struct net_device *dev, { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 val; + __u32 val; if (adapter->ahw.board_type == NETXEN_NIC_GBE) { /* get flow control settings */ netxen_nic_read_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum), - (u32 *) & val); + &val); pause->rx_pause = netxen_gb_get_rx_flowctl(val); pause->tx_pause = netxen_gb_get_tx_flowctl(val); /* get autoneg settings */ @@ -502,7 +502,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - __le32 val; + __u32 val; unsigned int autoneg; /* read mode */ @@ -522,13 +522,13 @@ netxen_nic_set_pauseparam(struct net_device *dev, netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port->portnum), - *(u32 *) (&val)); + *&val); /* set autoneg */ autoneg = pause->autoneg; if (adapter->phy_write && adapter->phy_write(adapter, port->portnum, NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, - (__le32) autoneg) != 0) + autoneg) != 0) return -EIO; else { port->link_autoneg = pause->autoneg; @@ -543,7 +543,7 @@ static int netxen_nic_reg_test(struct net_device *dev) struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; u32 data_read, data_written, save; - __le32 mode; + __u32 mode; /* * first test the "Read Only" registers by writing which mode diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index c0c31d1914a..f263232f499 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -95,7 +95,7 @@ void netxen_nic_set_multi(struct net_device *netdev) struct netxen_port *port = netdev_priv(netdev); struct netxen_adapter *adapter = port->adapter; struct dev_mc_list *mc_ptr; - __le32 netxen_mac_addr_cntl_data = 0; + __u32 netxen_mac_addr_cntl_data = 0; mc_ptr = netdev->mc_list; if (netdev->flags & IFF_PROMISC) { @@ -236,8 +236,9 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) } memset(addr, 0, sizeof(struct netxen_ring_ctx)); adapter->ctx_desc = (struct netxen_ring_ctx *)addr; - adapter->ctx_desc->cmd_consumer_offset = adapter->ctx_desc_phys_addr - + sizeof(struct netxen_ring_ctx); + adapter->ctx_desc->cmd_consumer_offset = + cpu_to_le64(adapter->ctx_desc_phys_addr + + sizeof(struct netxen_ring_ctx)); adapter->cmd_consumer = (uint32_t *) (((char *)addr) + sizeof(struct netxen_ring_ctx)); @@ -253,11 +254,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return -ENOMEM; } - adapter->ctx_desc->cmd_ring_addr_lo = - hw->cmd_desc_phys_addr & 0xffffffffUL; - adapter->ctx_desc->cmd_ring_addr_hi = - ((u64) hw->cmd_desc_phys_addr >> 32); - adapter->ctx_desc->cmd_ring_size = adapter->max_tx_desc_count; + adapter->ctx_desc->cmd_ring_addr = + cpu_to_le64(hw->cmd_desc_phys_addr); + adapter->ctx_desc->cmd_ring_size = + cpu_to_le32(adapter->max_tx_desc_count); hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; @@ -278,12 +278,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } rcv_desc->desc_head = (struct rcv_desc *)addr; - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_lo = - rcv_desc->phys_addr & 0xffffffffUL; - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr_hi = - ((u64) rcv_desc->phys_addr >> 32); + adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr = + cpu_to_le64(rcv_desc->phys_addr); adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = - rcv_desc->max_rx_desc_count; + cpu_to_le32(rcv_desc->max_rx_desc_count); } addr = netxen_alloc(adapter->ahw.pdev, STATUS_DESC_RINGSIZE, @@ -297,11 +295,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } recv_ctx->rcv_status_desc_head = (struct status_desc *)addr; - adapter->ctx_desc->sts_ring_addr_lo = - recv_ctx->rcv_status_desc_phys_addr & 0xffffffffUL; - adapter->ctx_desc->sts_ring_addr_hi = - ((u64) recv_ctx->rcv_status_desc_phys_addr >> 32); - adapter->ctx_desc->sts_ring_size = adapter->max_rx_desc_count; + adapter->ctx_desc->sts_ring_addr = + cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); + adapter->ctx_desc->sts_ring_size = + cpu_to_le32(adapter->max_rx_desc_count); } /* Window = 1 */ @@ -387,10 +384,6 @@ void netxen_tso_check(struct netxen_adapter *adapter, } adapter->stats.xmitcsummed++; desc->tcp_hdr_offset = skb->h.raw - skb->data; - netxen_set_cmd_desc_totallength(desc, - cpu_to_le32 - (netxen_get_cmd_desc_totallength - (desc))); desc->ip_hdr_offset = skb->nh.raw - skb->data; } @@ -867,9 +860,9 @@ netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, void netxen_nic_set_link_parameters(struct netxen_port *port) { struct netxen_adapter *adapter = port->adapter; - __le32 status; - __le32 autoneg; - __le32 mode; + __u32 status; + __u32 autoneg; + __u32 mode; netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ @@ -984,7 +977,8 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) _NETXEN_NIC_LINUX_MAJOR, fw_major); adapter->driver_mismatch = 1; } - if (fw_minor != _NETXEN_NIC_LINUX_MINOR) { + if (fw_minor != _NETXEN_NIC_LINUX_MINOR && + fw_minor != (_NETXEN_NIC_LINUX_MINOR + 1)) { printk(KERN_ERR "The mismatch in driver version and firmware " "version minor number\n" "Driver version minor number = %d \t" diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index 0685633a9c1..ab1112eb1b0 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h @@ -124,28 +124,28 @@ typedef enum { */ #define netxen_gb_enable_tx(config_word) \ - set_bit(0, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 0) #define netxen_gb_enable_rx(config_word) \ - set_bit(2, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 2) #define netxen_gb_tx_flowctl(config_word) \ - set_bit(4, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 4) #define netxen_gb_rx_flowctl(config_word) \ - set_bit(5, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 5) #define netxen_gb_tx_reset_pb(config_word) \ - set_bit(16, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 16) #define netxen_gb_rx_reset_pb(config_word) \ - set_bit(17, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 17) #define netxen_gb_tx_reset_mac(config_word) \ - set_bit(18, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 18) #define netxen_gb_rx_reset_mac(config_word) \ - set_bit(19, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 19) #define netxen_gb_soft_reset(config_word) \ - set_bit(31, (unsigned long*)(&config_word)) + ((config_word) |= 1 << 31) #define netxen_gb_unset_tx_flowctl(config_word) \ - clear_bit(4, (unsigned long *)(&config_word)) + ((config_word) &= ~(1 << 4)) #define netxen_gb_unset_rx_flowctl(config_word) \ - clear_bit(5, (unsigned long*)(&config_word)) + ((config_word) &= ~(1 << 5)) #define netxen_gb_get_tx_synced(config_word) \ _netxen_crb_get_bit((config_word), 1) @@ -171,15 +171,15 @@ typedef enum { */ #define netxen_gb_set_duplex(config_word) \ - set_bit(0, (unsigned long*)&config_word) + ((config_word) |= 1 << 0) #define netxen_gb_set_crc_enable(config_word) \ - set_bit(1, (unsigned long*)&config_word) + ((config_word) |= 1 << 1) #define netxen_gb_set_padshort(config_word) \ - set_bit(2, (unsigned long*)&config_word) + ((config_word) |= 1 << 2) #define netxen_gb_set_checklength(config_word) \ - set_bit(4, (unsigned long*)&config_word) + ((config_word) |= 1 << 4) #define netxen_gb_set_hugeframes(config_word) \ - set_bit(5, (unsigned long*)&config_word) + ((config_word) |= 1 << 5) #define netxen_gb_set_preamblelen(config_word, val) \ ((config_word) |= ((val) << 12) & 0xF000) #define netxen_gb_set_intfmode(config_word, val) \ @@ -190,9 +190,9 @@ typedef enum { #define netxen_gb_set_mii_mgmt_clockselect(config_word, val) \ ((config_word) |= ((val) & 0x07)) #define netxen_gb_mii_mgmt_reset(config_word) \ - set_bit(31, (unsigned long*)&config_word) + ((config_word) |= 1 << 31) #define netxen_gb_mii_mgmt_unset(config_word) \ - clear_bit(31, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 31)) /* * NIU GB MII Mgmt Command Register (applies to GB0, GB1, GB2, GB3) @@ -201,7 +201,7 @@ typedef enum { */ #define netxen_gb_mii_mgmt_set_read_cycle(config_word) \ - set_bit(0, (unsigned long*)&config_word) + ((config_word) |= 1 << 0) #define netxen_gb_mii_mgmt_reg_addr(config_word, val) \ ((config_word) |= ((val) & 0x1F)) #define netxen_gb_mii_mgmt_phy_addr(config_word, val) \ @@ -274,9 +274,9 @@ typedef enum { #define netxen_set_phy_speed(config_word, val) \ ((config_word) |= ((val & 0x03) << 14)) #define netxen_set_phy_duplex(config_word) \ - set_bit(13, (unsigned long*)&config_word) + ((config_word) |= 1 << 13) #define netxen_clear_phy_duplex(config_word) \ - clear_bit(13, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 13)) #define netxen_get_phy_jabber(config_word) \ _netxen_crb_get_bit(config_word, 0) @@ -350,11 +350,11 @@ typedef enum { _netxen_crb_get_bit(config_word, 15) #define netxen_set_phy_int_link_status_changed(config_word) \ - set_bit(10, (unsigned long*)&config_word) + ((config_word) |= 1 << 10) #define netxen_set_phy_int_autoneg_completed(config_word) \ - set_bit(11, (unsigned long*)&config_word) + ((config_word) |= 1 << 11) #define netxen_set_phy_int_speed_changed(config_word) \ - set_bit(14, (unsigned long*)&config_word) + ((config_word) |= 1 << 14) /* * NIU Mode Register. @@ -382,22 +382,22 @@ typedef enum { */ #define netxen_set_gb_drop_gb0(config_word) \ - set_bit(0, (unsigned long*)&config_word) + ((config_word) |= 1 << 0) #define netxen_set_gb_drop_gb1(config_word) \ - set_bit(1, (unsigned long*)&config_word) + ((config_word) |= 1 << 1) #define netxen_set_gb_drop_gb2(config_word) \ - set_bit(2, (unsigned long*)&config_word) + ((config_word) |= 1 << 2) #define netxen_set_gb_drop_gb3(config_word) \ - set_bit(3, (unsigned long*)&config_word) + ((config_word) |= 1 << 3) #define netxen_clear_gb_drop_gb0(config_word) \ - clear_bit(0, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 0)) #define netxen_clear_gb_drop_gb1(config_word) \ - clear_bit(1, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 1)) #define netxen_clear_gb_drop_gb2(config_word) \ - clear_bit(2, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 2)) #define netxen_clear_gb_drop_gb3(config_word) \ - clear_bit(3, (unsigned long*)&config_word) + ((config_word) &= ~(1 << 3)) /* * NIU XG MAC Config Register @@ -413,7 +413,7 @@ typedef enum { */ #define netxen_xg_soft_reset(config_word) \ - set_bit(4, (unsigned long*)&config_word) + ((config_word) |= 1 << 4) /* * MAC Control Register @@ -433,19 +433,19 @@ typedef enum { #define netxen_nic_mcr_set_id_pool0(config, val) \ ((config) |= ((val) &0x03)) #define netxen_nic_mcr_set_enable_xtnd0(config) \ - (set_bit(3, (unsigned long *)&(config))) + ((config) |= 1 << 3) #define netxen_nic_mcr_set_id_pool1(config, val) \ ((config) |= (((val) & 0x03) << 4)) #define netxen_nic_mcr_set_enable_xtnd1(config) \ - (set_bit(6, (unsigned long *)&(config))) + ((config) |= 1 << 6) #define netxen_nic_mcr_set_id_pool2(config, val) \ ((config) |= (((val) & 0x03) << 8)) #define netxen_nic_mcr_set_enable_xtnd2(config) \ - (set_bit(10, (unsigned long *)&(config))) + ((config) |= 1 << 10) #define netxen_nic_mcr_set_id_pool3(config, val) \ ((config) |= (((val) & 0x03) << 12)) #define netxen_nic_mcr_set_enable_xtnd3(config) \ - (set_bit(14, (unsigned long *)&(config))) + ((config) |= 1 << 14) #define netxen_nic_mcr_set_mode_select(config, val) \ ((config) |= (((val) & 0x03) << 24)) #define netxen_nic_mcr_set_enable_pool(config, val) \ diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index c3e41f36855..973af96337a 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -690,8 +690,7 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) desc_head = recv_ctx->rcv_status_desc_head; desc = &desc_head[consumer]; - if (((le16_to_cpu(netxen_get_sts_owner(desc))) - & STATUS_OWNER_HOST)) + if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST) return 1; } @@ -787,11 +786,11 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, struct netxen_port *port = adapter->port[netxen_get_sts_port(desc)]; struct pci_dev *pdev = port->pdev; struct net_device *netdev = port->netdev; - int index = le16_to_cpu(netxen_get_sts_refhandle(desc)); + int index = netxen_get_sts_refhandle(desc); struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); struct netxen_rx_buffer *buffer; struct sk_buff *skb; - u32 length = le16_to_cpu(netxen_get_sts_totallength(desc)); + u32 length = netxen_get_sts_totallength(desc); u32 desc_ctx; struct netxen_rcv_desc_ctx *rcv_desc; int ret; @@ -918,16 +917,14 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) */ while (count < max) { desc = &desc_head[consumer]; - if (! - (le16_to_cpu(netxen_get_sts_owner(desc)) & - STATUS_OWNER_HOST)) { + if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) { DPRINTK(ERR, "desc %p ownedby %x\n", desc, netxen_get_sts_owner(desc)); break; } netxen_process_rcv(adapter, ctxid, desc); netxen_clear_sts_owner(desc); - netxen_set_sts_owner(desc, cpu_to_le16(STATUS_OWNER_PHANTOM)); + netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); count++; } @@ -1232,7 +1229,7 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, /* make a rcv descriptor */ pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); - pdesc->buffer_length = cpu_to_le16(rcv_desc->dma_size); + pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size); pdesc->addr_buffer = cpu_to_le64(buffer->dma); DPRINTK(INFO, "done writing descripter\n"); producer = diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index 06847d4252c..be366e48007 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -79,7 +79,7 @@ void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno, void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, u32 enable) { - __le32 int_src; + __u32 int_src; struct netxen_port *port; /* This should clear the interrupt source */ @@ -110,7 +110,7 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno, /* write it down later.. */ if ((netxen_get_phy_int_speed_changed(int_src)) || (netxen_get_phy_int_link_status_changed(int_src))) { - __le32 status; + __u32 status; DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n"); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 8a5792fea77..69c1b9d23a1 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -117,7 +117,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *mem_ptr1 = NULL; void __iomem *mem_ptr2 = NULL; - u8 *db_ptr = NULL; + u8 __iomem *db_ptr = NULL; unsigned long mem_base, mem_len, db_base, db_len; int pci_using_dac, i, err; int ring; @@ -191,7 +191,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) db_len); db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES); - if (db_ptr == 0UL) { + if (!db_ptr) { printk(KERN_ERR "%s: Failed to allocate doorbell map.", netxen_nic_driver_name); err = -EIO; @@ -818,7 +818,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* Take skb->data itself */ pbuf = &adapter->cmd_buf_arr[producer]; if ((netdev->features & NETIF_F_TSO) && skb_shinfo(skb)->gso_size > 0) { - pbuf->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbuf->mss = skb_shinfo(skb)->gso_size; hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); } else { pbuf->mss = 0; @@ -882,7 +882,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) hwdesc->addr_buffer3 = cpu_to_le64(temp_dma); break; case 3: - hwdesc->buffer4_length = temp_len; + hwdesc->buffer4_length = cpu_to_le16(temp_len); hwdesc->addr_buffer4 = cpu_to_le64(temp_dma); break; } @@ -1144,7 +1144,7 @@ static int __init netxen_init_module(void) if ((netxen_workq = create_singlethread_workqueue("netxen")) == 0) return -ENOMEM; - return pci_module_init(&netxen_driver); + return pci_register_driver(&netxen_driver); } module_init(netxen_init_module); diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 4987dc765d9..40d7003a371 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -89,15 +89,15 @@ static inline int phy_unlock(struct netxen_adapter *adapter) * */ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, - long reg, __le32 * readval) + long reg, __u32 * readval) { long timeout = 0; long result = 0; long restore = 0; - __le32 address; - __le32 command; - __le32 status; - __le32 mac_cfg0; + __u32 address; + __u32 command; + __u32 status; + __u32 mac_cfg0; if (phy_lock(adapter) != 0) { return -1; @@ -112,7 +112,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, &mac_cfg0, 4)) return -EIO; if (netxen_gb_get_soft_reset(mac_cfg0)) { - __le32 temp; + __u32 temp; temp = 0; netxen_gb_tx_reset_pb(temp); netxen_gb_rx_reset_pb(temp); @@ -184,15 +184,15 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, * */ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, - long phy, long reg, __le32 val) + long phy, long reg, __u32 val) { long timeout = 0; long result = 0; long restore = 0; - __le32 address; - __le32 command; - __le32 status; - __le32 mac_cfg0; + __u32 address; + __u32 command; + __u32 status; + __u32 mac_cfg0; /* * MII mgmt all goes through port 0 MAC interface, so it @@ -203,7 +203,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, &mac_cfg0, 4)) return -EIO; if (netxen_gb_get_soft_reset(mac_cfg0)) { - __le32 temp; + __u32 temp; temp = 0; netxen_gb_tx_reset_pb(temp); netxen_gb_rx_reset_pb(temp); @@ -269,7 +269,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter, int port) { int result = 0; - __le32 enable = 0; + __u32 enable = 0; netxen_set_phy_int_link_status_changed(enable); netxen_set_phy_int_autoneg_completed(enable); netxen_set_phy_int_speed_changed(enable); @@ -402,7 +402,7 @@ void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) { int result = 0; - __le32 status; + __u32 status; if (adapter->disable_phy_interrupts) adapter->disable_phy_interrupts(adapter, port); mdelay(2); @@ -410,7 +410,7 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) if (0 == netxen_niu_gbe_phy_read(adapter, port, NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, - (__le32 *) & status)) { + &status)) { if (netxen_get_phy_link(status)) { if (netxen_get_phy_speed(status) == 2) { netxen_niu_gbe_set_gmii_mode(adapter, port, 1); @@ -489,7 +489,7 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, int port, long enable) { int result = 0; - __le32 int_src; + __u32 int_src; printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d" " (device enable = %d)\n", (int)port, (int)enable); @@ -530,7 +530,7 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, printk(KERN_INFO PFX "autoneg_error "); if ((netxen_get_phy_int_speed_changed(int_src)) || (netxen_get_phy_int_link_status_changed(int_src))) { - __le32 status; + __u32 status; printk(KERN_INFO PFX "speed_changed or link status changed"); @@ -583,9 +583,9 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, int netxen_niu_macaddr_get(struct netxen_adapter *adapter, int phy, netxen_ethernet_macaddr_t * addr) { - u64 result = 0; - __le32 stationhigh; - __le32 stationlow; + u32 stationhigh; + u32 stationlow; + u8 val[8]; if (addr == NULL) return -EINVAL; @@ -598,10 +598,10 @@ int netxen_niu_macaddr_get(struct netxen_adapter *adapter, if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &stationlow, 4)) return -EIO; + ((__le32 *)val)[1] = cpu_to_le32(stationhigh); + ((__le32 *)val)[0] = cpu_to_le32(stationlow); - result = (u64) netxen_gb_get_stationaddress_low(stationlow); - result |= (u64) stationhigh << 16; - memcpy(*addr, &result, sizeof(netxen_ethernet_macaddr_t)); + memcpy(addr, val + 2, 6); return 0; } @@ -613,24 +613,25 @@ int netxen_niu_macaddr_get(struct netxen_adapter *adapter, int netxen_niu_macaddr_set(struct netxen_port *port, netxen_ethernet_macaddr_t addr) { - __le32 temp = 0; + u8 temp[4]; + u32 val; struct netxen_adapter *adapter = port->adapter; int phy = port->portnum; unsigned char mac_addr[6]; int i; for (i = 0; i < 10; i++) { - memcpy(&temp, addr, 2); - temp <<= 16; + temp[0] = temp[1] = 0; + memcpy(temp + 2, addr, 2); + val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx - (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &temp, 4)) + (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) return -EIO; - temp = 0; - - memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); + memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); + val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx - (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &temp, 4)) + (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) return -2; netxen_niu_macaddr_get(adapter, phy, @@ -659,9 +660,9 @@ int netxen_niu_macaddr_set(struct netxen_port *port, int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, int port, netxen_niu_gbe_ifmode_t mode) { - __le32 mac_cfg0; - __le32 mac_cfg1; - __le32 mii_cfg; + __u32 mac_cfg0; + __u32 mac_cfg1; + __u32 mii_cfg; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; @@ -736,7 +737,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, /* Disable a GbE interface */ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, int port) { - __le32 mac_cfg0; + __u32 mac_cfg0; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; @@ -752,7 +753,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, int port) /* Disable an XG interface */ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter, int port) { - __le32 mac_cfg; + __u32 mac_cfg; if (port != 0) return -EINVAL; @@ -769,7 +770,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter, int port) int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int port, netxen_niu_prom_mode_t mode) { - __le32 reg; + __u32 reg; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; @@ -826,22 +827,21 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, int port, int netxen_niu_xg_macaddr_set(struct netxen_port *port, netxen_ethernet_macaddr_t addr) { - __le32 temp = 0; + u8 temp[4]; + u32 val; struct netxen_adapter *adapter = port->adapter; - memcpy(&temp, addr, 2); - temp = cpu_to_le32(temp); - temp <<= 16; + temp[0] = temp[1] = 0; + memcpy(temp + 2, addr, 2); + val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, - &temp, 4)) + &val, 4)) return -EIO; - temp = 0; - memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); - temp = cpu_to_le32(temp); + val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, - &temp, 4)) + &val, 4)) return -EIO; return 0; @@ -854,9 +854,9 @@ int netxen_niu_xg_macaddr_set(struct netxen_port *port, int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy, netxen_ethernet_macaddr_t * addr) { - __le32 stationhigh; - __le32 stationlow; - u64 result; + u32 stationhigh; + u32 stationlow; + u8 val[8]; if (addr == NULL) return -EINVAL; @@ -869,10 +869,10 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy, if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, &stationlow, 4)) return -EIO; + ((__le32 *)val)[1] = cpu_to_le32(stationhigh); + ((__le32 *)val)[0] = cpu_to_le32(stationlow); - result = ((u64) stationlow) >> 16; - result |= (u64) stationhigh << 16; - memcpy(*addr, &result, sizeof(netxen_ethernet_macaddr_t)); + memcpy(addr, val + 2, 6); return 0; } @@ -880,7 +880,7 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, int phy, int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, int port, netxen_niu_prom_mode_t mode) { - __le32 reg; + __u32 reg; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 342f4062de0..461e8274ef6 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -606,11 +606,14 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) { kio_addr_t ioaddr = dev->base_addr; struct el3_private *priv = netdev_priv(dev); + unsigned long flags; DEBUG(3, "%s: el3_start_xmit(length = %ld) called, " "status %4.4x.\n", dev->name, (long)skb->len, inw(ioaddr + EL3_STATUS)); + spin_lock_irqsave(&priv->lock, flags); + priv->stats.tx_bytes += skb->len; /* Put out the doubleword header... */ @@ -628,6 +631,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb(skb); pop_tx_status(dev); + spin_unlock_irqrestore(&priv->lock, flags); return 0; } @@ -729,14 +733,13 @@ static void media_check(unsigned long arg) if (!netif_device_present(dev)) goto reschedule; - EL3WINDOW(1); /* Check for pending interrupt with expired latency timer: with this, we can limp along even if the interrupt is blocked */ if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + EL3_TIMER) == 0xff)) { if (!lp->fast_poll) printk(KERN_WARNING "%s: interrupt(s) dropped!\n", dev->name); - el3_interrupt(dev->irq, lp); + el3_interrupt(dev->irq, dev); lp->fast_poll = HZ; } if (lp->fast_poll) { diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index 096d4a100bf..86135397f43 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -349,7 +349,7 @@ static int __init fixed_init(void) fixed_mdio_register_device(0, 100, 1); #endif -#ifdef CONFIX_FIXED_MII_10_FDX +#ifdef CONFIG_FIXED_MII_10_FDX fixed_mdio_register_device(0, 10, 1); #endif return 0; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index e175f3910b1..9765fa66146 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -286,6 +286,7 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) return 0; } +EXPORT_SYMBOL(phy_ethtool_sset); int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) { @@ -302,7 +303,7 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) return 0; } - +EXPORT_SYMBOL(phy_ethtool_gset); /* Note that this function is currently incompatible with the * PHYCONTROL layer. It changes registers without regard to diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 250cdbeefdf..1dd66b8ea0f 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -556,10 +556,9 @@ static int init_shared_mem(struct s2io_nic *nic) } } - nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); + nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL); if (!nic->ufo_in_band_v) return -ENOMEM; - memset(nic->ufo_in_band_v, 0, size); /* Allocation and initialization of RXDs in Rings */ size = 0; diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index b70ed79d412..45d91b15910 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1562,7 +1562,7 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, for (i = 0; i < MAC_ADDR_LEN / 2; i++) { __le16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i); - ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w); + ((u16 *)dev->dev_addr)[i] = le16_to_cpu(w); } sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo)); diff --git a/drivers/net/skge.c b/drivers/net/skge.c index deedfd5f822..45283f3f95e 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -60,7 +60,7 @@ #define LINK_HZ (HZ/2) MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); -MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); +MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a6601e8d423..822dd0b1313 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -3639,29 +3639,6 @@ static int sky2_resume(struct pci_dev *pdev) out: return err; } - -/* BIOS resume runs after device (it's a bug in PM) - * as a temporary workaround on suspend/resume leave MSI disabled - */ -static int sky2_suspend_late(struct pci_dev *pdev, pm_message_t state) -{ - struct sky2_hw *hw = pci_get_drvdata(pdev); - - free_irq(pdev->irq, hw); - if (hw->msi) { - pci_disable_msi(pdev); - hw->msi = 0; - } - return 0; -} - -static int sky2_resume_early(struct pci_dev *pdev) -{ - struct sky2_hw *hw = pci_get_drvdata(pdev); - struct net_device *dev = hw->dev[0]; - - return request_irq(pdev->irq, sky2_intr, IRQF_SHARED, dev->name, hw); -} #endif static struct pci_driver sky2_driver = { @@ -3672,8 +3649,6 @@ static struct pci_driver sky2_driver = { #ifdef CONFIG_PM .suspend = sky2_suspend, .resume = sky2_resume, - .suspend_late = sky2_suspend_late, - .resume_early = sky2_resume_early, #endif }; @@ -3691,6 +3666,6 @@ module_init(sky2_init_module); module_exit(sky2_cleanup_module); MODULE_DESCRIPTION("Marvell Yukon 2 Gigabit Ethernet driver"); -MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); +MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 880d9fdd7c6..43af6143844 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -968,11 +968,11 @@ static void smc911x_phy_configure(struct work_struct *work) * We should not be called if phy_type is zero. */ if (lp->phy_type == 0) - goto smc911x_phy_configure_exit; + goto smc911x_phy_configure_exit_nolock; if (smc911x_phy_reset(dev, phyaddr)) { printk("%s: PHY reset timed out\n", dev->name); - goto smc911x_phy_configure_exit; + goto smc911x_phy_configure_exit_nolock; } spin_lock_irqsave(&lp->lock, flags); @@ -1041,6 +1041,7 @@ static void smc911x_phy_configure(struct work_struct *work) smc911x_phy_configure_exit: spin_unlock_irqrestore(&lp->lock, flags); +smc911x_phy_configure_exit_nolock: lp->work_pending = 0; } diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index ebb6aa39f9c..8ea2fc1b96c 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1925,6 +1925,8 @@ spider_net_stop(struct net_device *netdev) /* release chains */ spider_net_release_tx_chain(card, 1); + spider_net_free_rx_chain_contents(card); + spider_net_free_chain(card, &card->tx_chain); spider_net_free_chain(card, &card->rx_chain); diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 8243150f5b0..7e4b23c7c1b 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -29,6 +29,7 @@ #include <linux/fsl_devices.h> #include <linux/ethtool.h> #include <linux/mii.h> +#include <linux/workqueue.h> #include <asm/of_platform.h> #include <asm/uaccess.h> @@ -472,7 +473,7 @@ static void put_enet_addr_container(struct enet_addr_container *enet_addr_cont) kfree(enet_addr_cont); } -static int set_mac_addr(__be16 __iomem *reg, u8 *mac) +static void set_mac_addr(__be16 __iomem *reg, u8 *mac) { out_be16(®[0], ((u16)mac[5] << 8) | mac[4]); out_be16(®[1], ((u16)mac[3] << 8) | mac[2]); @@ -3920,10 +3921,11 @@ static irqreturn_t phy_interrupt(int irq, void *dev_id) } /* Scheduled by the phy_interrupt/timer to handle PHY changes */ -static void ugeth_phy_change(void *data) +static void ugeth_phy_change(struct work_struct *work) { - struct net_device *dev = (struct net_device *)data; - struct ucc_geth_private *ugeth = netdev_priv(dev); + struct ucc_geth_private *ugeth = + container_of(work, struct ucc_geth_private, tq); + struct net_device *dev = ugeth->dev; struct ucc_geth *ug_regs; int result = 0; @@ -4080,7 +4082,7 @@ static int ucc_geth_open(struct net_device *dev) #endif /* CONFIG_UGETH_NAPI */ /* Set up the PHY change work queue */ - INIT_WORK(&ugeth->tq, ugeth_phy_change, dev); + INIT_WORK(&ugeth->tq, ugeth_phy_change); init_timer(&ugeth->phy_info_timer); ugeth->phy_info_timer.function = &ugeth_phy_startup_timer; diff --git a/drivers/net/ucc_geth_phy.c b/drivers/net/ucc_geth_phy.c index 5360ec05eaa..3c86592ce03 100644 --- a/drivers/net/ucc_geth_phy.c +++ b/drivers/net/ucc_geth_phy.c @@ -68,8 +68,31 @@ static int gbit_config_aneg(struct ugeth_mii_info *mii_info); static int genmii_config_aneg(struct ugeth_mii_info *mii_info); static int genmii_update_link(struct ugeth_mii_info *mii_info); static int genmii_read_status(struct ugeth_mii_info *mii_info); -u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum); -void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val); + +static u16 ucc_geth_phy_read(struct ugeth_mii_info *mii_info, u16 regnum) +{ + u16 retval; + unsigned long flags; + + ugphy_vdbg("%s: IN", __FUNCTION__); + + spin_lock_irqsave(&mii_info->mdio_lock, flags); + retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum); + spin_unlock_irqrestore(&mii_info->mdio_lock, flags); + + return retval; +} + +static void ucc_geth_phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val) +{ + unsigned long flags; + + ugphy_vdbg("%s: IN", __FUNCTION__); + + spin_lock_irqsave(&mii_info->mdio_lock, flags); + mii_info->mdio_write(mii_info->dev, mii_info->mii_id, regnum, val); + spin_unlock_irqrestore(&mii_info->mdio_lock, flags); +} /* Write value to the PHY for this device to the register at regnum, */ /* waiting until the write is done before it returns. All PHY */ @@ -184,7 +207,7 @@ static void config_genmii_advert(struct ugeth_mii_info *mii_info) advertise = mii_info->advertising; /* Setup standard advertisement */ - adv = phy_read(mii_info, MII_ADVERTISE); + adv = ucc_geth_phy_read(mii_info, MII_ADVERTISE); adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); if (advertise & ADVERTISED_10baseT_Half) adv |= ADVERTISE_10HALF; @@ -194,7 +217,7 @@ static void config_genmii_advert(struct ugeth_mii_info *mii_info) adv |= ADVERTISE_100HALF; if (advertise & ADVERTISED_100baseT_Full) adv |= ADVERTISE_100FULL; - phy_write(mii_info, MII_ADVERTISE, adv); + ucc_geth_phy_write(mii_info, MII_ADVERTISE, adv); } static void genmii_setup_forced(struct ugeth_mii_info *mii_info) @@ -204,7 +227,7 @@ static void genmii_setup_forced(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); - ctrl = phy_read(mii_info, MII_BMCR); + ctrl = ucc_geth_phy_read(mii_info, MII_BMCR); ctrl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE); @@ -234,7 +257,7 @@ static void genmii_setup_forced(struct ugeth_mii_info *mii_info) break; } - phy_write(mii_info, MII_BMCR, ctrl); + ucc_geth_phy_write(mii_info, MII_BMCR, ctrl); } /* Enable and Restart Autonegotiation */ @@ -244,9 +267,9 @@ static void genmii_restart_aneg(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); - ctl = phy_read(mii_info, MII_BMCR); + ctl = ucc_geth_phy_read(mii_info, MII_BMCR); ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); - phy_write(mii_info, MII_BMCR, ctl); + ucc_geth_phy_write(mii_info, MII_BMCR, ctl); } static int gbit_config_aneg(struct ugeth_mii_info *mii_info) @@ -261,14 +284,14 @@ static int gbit_config_aneg(struct ugeth_mii_info *mii_info) config_genmii_advert(mii_info); advertise = mii_info->advertising; - adv = phy_read(mii_info, MII_1000BASETCONTROL); + adv = ucc_geth_phy_read(mii_info, MII_1000BASETCONTROL); adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | MII_1000BASETCONTROL_HALFDUPLEXCAP); if (advertise & SUPPORTED_1000baseT_Half) adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; if (advertise & SUPPORTED_1000baseT_Full) adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; - phy_write(mii_info, MII_1000BASETCONTROL, adv); + ucc_geth_phy_write(mii_info, MII_1000BASETCONTROL, adv); /* Start/Restart aneg */ genmii_restart_aneg(mii_info); @@ -298,10 +321,10 @@ static int genmii_update_link(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); /* Do a fake read */ - phy_read(mii_info, MII_BMSR); + ucc_geth_phy_read(mii_info, MII_BMSR); /* Read link and autonegotiation status */ - status = phy_read(mii_info, MII_BMSR); + status = ucc_geth_phy_read(mii_info, MII_BMSR); if ((status & BMSR_LSTATUS) == 0) mii_info->link = 0; else @@ -329,7 +352,7 @@ static int genmii_read_status(struct ugeth_mii_info *mii_info) return err; if (mii_info->autoneg) { - status = phy_read(mii_info, MII_LPA); + status = ucc_geth_phy_read(mii_info, MII_LPA); if (status & (LPA_10FULL | LPA_100FULL)) mii_info->duplex = DUPLEX_FULL; @@ -352,9 +375,9 @@ static int marvell_init(struct ugeth_mii_info *mii_info) { ugphy_vdbg("%s: IN", __FUNCTION__); - phy_write(mii_info, 0x14, 0x0cd2); - phy_write(mii_info, MII_BMCR, - phy_read(mii_info, MII_BMCR) | BMCR_RESET); + ucc_geth_phy_write(mii_info, 0x14, 0x0cd2); + ucc_geth_phy_write(mii_info, MII_BMCR, + ucc_geth_phy_read(mii_info, MII_BMCR) | BMCR_RESET); msleep(4000); return 0; @@ -367,13 +390,13 @@ static int marvell_config_aneg(struct ugeth_mii_info *mii_info) /* The Marvell PHY has an errata which requires * that certain registers get written in order * to restart autonegotiation */ - phy_write(mii_info, MII_BMCR, BMCR_RESET); + ucc_geth_phy_write(mii_info, MII_BMCR, BMCR_RESET); - phy_write(mii_info, 0x1d, 0x1f); - phy_write(mii_info, 0x1e, 0x200c); - phy_write(mii_info, 0x1d, 0x5); - phy_write(mii_info, 0x1e, 0); - phy_write(mii_info, 0x1e, 0x100); + ucc_geth_phy_write(mii_info, 0x1d, 0x1f); + ucc_geth_phy_write(mii_info, 0x1e, 0x200c); + ucc_geth_phy_write(mii_info, 0x1d, 0x5); + ucc_geth_phy_write(mii_info, 0x1e, 0); + ucc_geth_phy_write(mii_info, 0x1e, 0x100); gbit_config_aneg(mii_info); @@ -398,7 +421,7 @@ static int marvell_read_status(struct ugeth_mii_info *mii_info) * are as set */ if (mii_info->autoneg && mii_info->link) { int speed; - status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS); + status = ucc_geth_phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS); /* Get the duplexity */ if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) @@ -430,7 +453,7 @@ static int marvell_ack_interrupt(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); /* Clear the interrupts by reading the reg */ - phy_read(mii_info, MII_M1011_IEVENT); + ucc_geth_phy_read(mii_info, MII_M1011_IEVENT); return 0; } @@ -440,9 +463,9 @@ static int marvell_config_intr(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); if (mii_info->interrupts == MII_INTERRUPT_ENABLED) - phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); + ucc_geth_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); else - phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); + ucc_geth_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); return 0; } @@ -451,9 +474,9 @@ static int cis820x_init(struct ugeth_mii_info *mii_info) { ugphy_vdbg("%s: IN", __FUNCTION__); - phy_write(mii_info, MII_CIS8201_AUX_CONSTAT, + ucc_geth_phy_write(mii_info, MII_CIS8201_AUX_CONSTAT, MII_CIS8201_AUXCONSTAT_INIT); - phy_write(mii_info, MII_CIS8201_EXT_CON1, MII_CIS8201_EXTCON1_INIT); + ucc_geth_phy_write(mii_info, MII_CIS8201_EXT_CON1, MII_CIS8201_EXTCON1_INIT); return 0; } @@ -477,7 +500,7 @@ static int cis820x_read_status(struct ugeth_mii_info *mii_info) if (mii_info->autoneg && mii_info->link) { int speed; - status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT); + status = ucc_geth_phy_read(mii_info, MII_CIS8201_AUX_CONSTAT); if (status & MII_CIS8201_AUXCONSTAT_DUPLEX) mii_info->duplex = DUPLEX_FULL; else @@ -505,7 +528,7 @@ static int cis820x_ack_interrupt(struct ugeth_mii_info *mii_info) { ugphy_vdbg("%s: IN", __FUNCTION__); - phy_read(mii_info, MII_CIS8201_ISTAT); + ucc_geth_phy_read(mii_info, MII_CIS8201_ISTAT); return 0; } @@ -515,9 +538,9 @@ static int cis820x_config_intr(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); if (mii_info->interrupts == MII_INTERRUPT_ENABLED) - phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK); + ucc_geth_phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK); else - phy_write(mii_info, MII_CIS8201_IMASK, 0); + ucc_geth_phy_write(mii_info, MII_CIS8201_IMASK, 0); return 0; } @@ -541,7 +564,7 @@ static int dm9161_read_status(struct ugeth_mii_info *mii_info) /* If we aren't autonegotiating, assume speeds * are as set */ if (mii_info->autoneg && mii_info->link) { - status = phy_read(mii_info, MII_DM9161_SCSR); + status = ucc_geth_phy_read(mii_info, MII_DM9161_SCSR); if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) mii_info->speed = SPEED_100; else @@ -572,7 +595,7 @@ static void dm9161_timer(unsigned long data) { struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data; struct dm9161_private *priv = mii_info->priv; - u16 status = phy_read(mii_info, MII_BMSR); + u16 status = ucc_geth_phy_read(mii_info, MII_BMSR); ugphy_vdbg("%s: IN", __FUNCTION__); @@ -599,11 +622,11 @@ static int dm9161_init(struct ugeth_mii_info *mii_info) /* Reset is not done yet */ priv->resetdone = 0; - phy_write(mii_info, MII_BMCR, - phy_read(mii_info, MII_BMCR) | BMCR_RESET); + ucc_geth_phy_write(mii_info, MII_BMCR, + ucc_geth_phy_read(mii_info, MII_BMCR) | BMCR_RESET); - phy_write(mii_info, MII_BMCR, - phy_read(mii_info, MII_BMCR) & ~BMCR_ISOLATE); + ucc_geth_phy_write(mii_info, MII_BMCR, + ucc_geth_phy_read(mii_info, MII_BMCR) & ~BMCR_ISOLATE); config_genmii_advert(mii_info); /* Start/Restart aneg */ @@ -634,7 +657,7 @@ static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); /* Clear the interrupts by reading the reg */ - phy_read(mii_info, MII_DM9161_INTR); + ucc_geth_phy_read(mii_info, MII_DM9161_INTR); return 0; @@ -645,9 +668,9 @@ static int dm9161_config_intr(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); if (mii_info->interrupts == MII_INTERRUPT_ENABLED) - phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT); + ucc_geth_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT); else - phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP); + ucc_geth_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP); return 0; } @@ -718,31 +741,6 @@ static struct phy_info *phy_info[] = { NULL }; -u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum) -{ - u16 retval; - unsigned long flags; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - spin_lock_irqsave(&mii_info->mdio_lock, flags); - retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum); - spin_unlock_irqrestore(&mii_info->mdio_lock, flags); - - return retval; -} - -void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val) -{ - unsigned long flags; - - ugphy_vdbg("%s: IN", __FUNCTION__); - - spin_lock_irqsave(&mii_info->mdio_lock, flags); - mii_info->mdio_write(mii_info->dev, mii_info->mii_id, regnum, val); - spin_unlock_irqrestore(&mii_info->mdio_lock, flags); -} - /* Use the PHY ID registers to determine what type of PHY is attached * to device dev. return a struct phy_info structure describing that PHY */ @@ -757,11 +755,11 @@ struct phy_info *get_phy_info(struct ugeth_mii_info *mii_info) ugphy_vdbg("%s: IN", __FUNCTION__); /* Grab the bits from PHYIR1, and put them in the upper half */ - phy_reg = phy_read(mii_info, MII_PHYSID1); + phy_reg = ucc_geth_phy_read(mii_info, MII_PHYSID1); phy_ID = (phy_reg & 0xffff) << 16; /* Grab the bits from PHYIR2, and put them in the lower half */ - phy_reg = phy_read(mii_info, MII_PHYSID2); + phy_reg = ucc_geth_phy_read(mii_info, MII_PHYSID2); phy_ID |= (phy_reg & 0xffff); /* loop through all the known PHY types, and find one that */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 2ec2e5afce6..91b752e3d07 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -2701,8 +2701,8 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm) sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); /* extract core_id, core_rev, core_vendor */ - core_id = (sb_id_hi & 0xFFF0) >> 4; - core_rev = (sb_id_hi & 0xF); + core_id = (sb_id_hi & 0x8FF0) >> 4; + core_rev = ((sb_id_hi & 0xF) | ((sb_id_hi & 0x7000) >> 8)); core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x\n", @@ -2873,7 +2873,10 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm, sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; - sbimconfiglow |= 0x32; + if (bcm->bustype == BCM43xx_BUSTYPE_PCI) + sbimconfiglow |= 0x32; + else + sbimconfiglow |= 0x53; bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow); } @@ -3077,7 +3080,7 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm, if (err) goto out; - if (bcm->current_core->rev < 6 || + if (bcm->current_core->rev < 6 && bcm->current_core->id == BCM43xx_COREID_PCI) { value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC); value |= (1 << backplane_flag_nr); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index b8d2385e29b..92d5e8db0de 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -150,8 +150,7 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, } /** - * pci_match_device - Tell if a PCI device structure has a matching - * PCI device id structure + * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure * @drv: the PCI driver to match against * @dev: the PCI device structure to match against * diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0a70943f8bb..c913ea4e545 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -654,19 +654,42 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vi * VIA bridges which have VLink */ -static const struct pci_device_id via_vlink_fixup_tbl[] = { - /* Internal devices need IRQ line routing, pre VLink */ - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 }, - /* Devices with VLink */ - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17}, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 }, - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 }, - { 0, }, -}; +static int via_vlink_dev_lo = -1, via_vlink_dev_hi = 18; + +static void quirk_via_bridge(struct pci_dev *dev) +{ + /* See what bridge we have and find the device ranges */ + switch (dev->device) { + case PCI_DEVICE_ID_VIA_82C686: + /* The VT82C686 is special, it attaches to PCI and can have + any device number. All its subdevices are functions of + that single device. */ + via_vlink_dev_lo = PCI_SLOT(dev->devfn); + via_vlink_dev_hi = PCI_SLOT(dev->devfn); + break; + case PCI_DEVICE_ID_VIA_8237: + case PCI_DEVICE_ID_VIA_8237A: + via_vlink_dev_lo = 15; + break; + case PCI_DEVICE_ID_VIA_8235: + via_vlink_dev_lo = 16; + break; + case PCI_DEVICE_ID_VIA_8231: + case PCI_DEVICE_ID_VIA_8233_0: + case PCI_DEVICE_ID_VIA_8233A: + case PCI_DEVICE_ID_VIA_8233C_0: + via_vlink_dev_lo = 17; + break; + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233C_0, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_bridge); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A, quirk_via_bridge); /** * quirk_via_vlink - VIA VLink IRQ number update @@ -675,35 +698,20 @@ static const struct pci_device_id via_vlink_fixup_tbl[] = { * If the device we are dealing with is on a PIC IRQ we need to * ensure that the IRQ line register which usually is not relevant * for PCI cards, is actually written so that interrupts get sent - * to the right place + * to the right place. + * We only do this on systems where a VIA south bridge was detected, + * and only for VIA devices on the motherboard (see quirk_via_bridge + * above). */ static void quirk_via_vlink(struct pci_dev *dev) { - const struct pci_device_id *via_vlink_fixup; - static int dev_lo = -1, dev_hi = 18; u8 irq, new_irq; - /* Check if we have VLink and cache the result */ - - /* Checked already - no */ - if (dev_lo == -2) + /* Check if we have VLink at all */ + if (via_vlink_dev_lo == -1) return; - /* Not checked - see what bridge we have and find the device - ranges */ - - if (dev_lo == -1) { - via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl); - if (via_vlink_fixup == NULL) { - dev_lo = -2; - return; - } - dev_lo = via_vlink_fixup->driver_data; - /* 82C686 is special - 0/0 */ - if (dev_lo == 0) - dev_hi = 0; - } new_irq = dev->irq; /* Don't quirk interrupts outside the legacy IRQ range */ @@ -711,8 +719,8 @@ static void quirk_via_vlink(struct pci_dev *dev) return; /* Internal device ? */ - if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi || - PCI_SLOT(dev->devfn) < dev_lo) + if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > via_vlink_dev_hi || + PCI_SLOT(dev->devfn) < via_vlink_dev_lo) return; /* This is an internal VLink device on a PIC interrupt. The BIOS @@ -1002,6 +1010,11 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x186a: /* M6Ne notebook */ asus_hides_smbus = 1; } + if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB) + switch (dev->subsystem_device) { + case 0x80f2: /* P4P800-X */ + asus_hides_smbus = 1; + } if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) { switch (dev->subsystem_device) { case 0x1882: /* M6V notebook */ @@ -1249,8 +1262,8 @@ static void quirk_jmicron_dualfn(struct pci_dev *pdev) pci_read_config_dword(pdev, 0x40, &conf); /* Enable dual function mode, AHCI on fn 0, IDE fn1 */ /* Set the class codes correctly and then direct IDE 0 */ - conf &= ~0x000F0200; /* Clear bit 9 and 16-19 */ - conf |= 0x00C20002; /* Set bit 1, 17, 22, 23 */ + conf &= ~0x000FF200; /* Clear bit 9 and 12-19 */ + conf |= 0x00C2A102; /* Set 1, 8, 13, 15, 17, 22, 23 */ pci_write_config_dword(pdev, 0x40, conf); /* Reconfigure so that the PCI scanner discovers the diff --git a/drivers/pci/search.c b/drivers/pci/search.c index fab381ed853..b2653c4afe9 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -200,11 +200,8 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor, * can cause some machines to crash. So here we detect and flag that * situation and bail out early. */ - if (unlikely(list_empty(&pci_devices))) { - printk(KERN_INFO "pci_find_subsys() called while pci_devices " - "is still empty\n"); + if (unlikely(list_empty(&pci_devices))) return NULL; - } down_read(&pci_bus_sem); n = from ? from->global_list.next : pci_devices.next; @@ -278,11 +275,8 @@ pci_get_subsys(unsigned int vendor, unsigned int device, * can cause some machines to crash. So here we detect and flag that * situation and bail out early. */ - if (unlikely(list_empty(&pci_devices))) { - printk(KERN_NOTICE "pci_get_subsys() called while pci_devices " - "is still empty\n"); + if (unlikely(list_empty(&pci_devices))) return NULL; - } down_read(&pci_bus_sem); n = from ? from->global_list.next : pci_devices.next; diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index e9e0934380b..198b9f22fbf 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -492,10 +492,10 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) spin_lock_irq(&rtc->lock); - /* disable alarm interrupt and clear flag */ + /* disable alarm interrupt and clear the alarm flag */ rcr1 = readb(rtc->regbase + RCR1); - rcr1 &= ~RCR1_AF; - writeb(rcr1 & ~RCR1_AIE, rtc->regbase + RCR1); + rcr1 &= ~(RCR1_AF|RCR1_AIE); + writeb(rcr1, rtc->regbase + RCR1); rtc->rearm_aie = 0; @@ -510,8 +510,10 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) mon += 1; sh_rtc_write_alarm_value(rtc, mon, RMONAR); - /* Restore interrupt activation status */ - writeb(rcr1, rtc->regbase + RCR1); + if (wkalrm->enabled) { + rcr1 |= RCR1_AIE; + writeb(rcr1, rtc->regbase + RCR1); + } spin_unlock_irq(&rtc->lock); diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 9418a59fb36..2ddd0cf0714 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c @@ -78,7 +78,7 @@ static struct attribute_group rtc_attr_group = { .attrs = rtc_attrs, }; -static int __devinit rtc_sysfs_add_device(struct class_device *class_dev, +static int rtc_sysfs_add_device(struct class_device *class_dev, struct class_interface *class_intf) { int err; diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 99a259c5a0c..e1b44d6c0c3 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -6,7 +6,7 @@ Arnaldo Carvalho de Melo <acme@conectiva.com.br> Brad Strand <linux@3ware.com> - Copyright (C) 1999-2005 3ware Inc. + Copyright (C) 1999-2007 3ware Inc. Kernel compatiblity By: Andre Hedrick <andre@suse.com> Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com> @@ -191,6 +191,9 @@ before shutting down card. Change to new 'change_queue_depth' api. Fix 'handled=1' ISR usage, remove bogus IRQ check. + 1.26.02.002 - Free irq handler in __tw_shutdown(). + Turn on RCD bit for caching mode page. + Serialize reset code. */ #include <linux/module.h> @@ -214,7 +217,7 @@ #include "3w-xxxx.h" /* Globals */ -#define TW_DRIVER_VERSION "1.26.02.001" +#define TW_DRIVER_VERSION "1.26.02.002" static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT]; static int tw_device_extension_count = 0; static int twe_major = -1; @@ -226,7 +229,7 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(TW_DRIVER_VERSION); /* Function prototypes */ -static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset); +static int tw_reset_device_extension(TW_Device_Extension *tw_dev); /* Functions */ @@ -984,24 +987,12 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int /* Now wait for the command to complete */ timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout); - /* See if we reset while waiting for the ioctl to complete */ - if (test_bit(TW_IN_RESET, &tw_dev->flags)) { - clear_bit(TW_IN_RESET, &tw_dev->flags); - retval = -ERESTARTSYS; - goto out2; - } - /* We timed out, and didn't get an interrupt */ if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) { /* Now we need to reset the board */ printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd); retval = -EIO; - spin_lock_irqsave(tw_dev->host->host_lock, flags); - tw_dev->state[request_id] = TW_S_COMPLETED; - tw_state_request_finish(tw_dev, request_id); - tw_dev->posted_request_count--; - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); - if (tw_reset_device_extension(tw_dev, 1)) { + if (tw_reset_device_extension(tw_dev)) { printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no); } goto out2; @@ -1336,7 +1327,7 @@ static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) } /* End tw_unmap_scsi_data() */ /* This function will reset a device extension */ -static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset) +static int tw_reset_device_extension(TW_Device_Extension *tw_dev) { int i = 0; struct scsi_cmnd *srb; @@ -1382,15 +1373,10 @@ static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_rese printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no); return 1; } - TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); - /* Wake up any ioctl that was pending before the reset */ - if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) { - clear_bit(TW_IN_RESET, &tw_dev->flags); - } else { - tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; - wake_up(&tw_dev->ioctl_wqueue); - } + TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev); + clear_bit(TW_IN_RESET, &tw_dev->flags); + tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE; return 0; } /* End tw_reset_device_extension() */ @@ -1437,14 +1423,18 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt) "WARNING: Command (0x%x) timed out, resetting card.\n", SCpnt->cmnd[0]); + /* Make sure we are not issuing an ioctl or resetting from ioctl */ + mutex_lock(&tw_dev->ioctl_lock); + /* Now reset the card and some of the device extension data */ - if (tw_reset_device_extension(tw_dev, 0)) { + if (tw_reset_device_extension(tw_dev)) { printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no); goto out; } retval = SUCCESS; out: + mutex_unlock(&tw_dev->ioctl_lock); return retval; } /* End tw_scsi_eh_reset() */ @@ -1660,9 +1650,9 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques request_buffer[4] = 0x8; /* caching page */ request_buffer[5] = 0xa; /* page length */ if (*flags & 0x1) - request_buffer[6] = 0x4; /* WCE on */ + request_buffer[6] = 0x5; /* WCE on, RCD on */ else - request_buffer[6] = 0x0; /* WCE off */ + request_buffer[6] = 0x1; /* WCE off, RCD on */ tw_transfer_internal(tw_dev, request_id, request_buffer, sizeof(request_buffer)); @@ -2012,6 +2002,10 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd int retval = 1; TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; + /* If we are resetting due to timed out ioctl, report as busy */ + if (test_bit(TW_IN_RESET, &tw_dev->flags)) + return SCSI_MLQUEUE_HOST_BUSY; + /* Save done function into Scsi_Cmnd struct */ SCpnt->scsi_done = done; @@ -2100,6 +2094,10 @@ static irqreturn_t tw_interrupt(int irq, void *dev_instance) handled = 1; + /* If we are resetting, bail */ + if (test_bit(TW_IN_RESET, &tw_dev->flags)) + goto tw_interrupt_bail; + /* Check controller for errors */ if (tw_check_bits(status_reg_value)) { dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n"); @@ -2276,6 +2274,9 @@ static void __tw_shutdown(TW_Device_Extension *tw_dev) /* Disable interrupts */ TW_DISABLE_INTERRUPTS(tw_dev); + /* Free up the IRQ */ + free_irq(tw_dev->tw_pci_dev->irq, tw_dev); + printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", tw_dev->host->host_no); /* Tell the card we are shutting down */ @@ -2444,9 +2445,6 @@ static void tw_remove(struct pci_dev *pdev) twe_major = -1; } - /* Free up the IRQ */ - free_irq(tw_dev->tw_pci_dev->irq, tw_dev); - /* Shutdown the card */ __tw_shutdown(tw_dev); diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h index bbd654a2b9b..0742e684665 100644 --- a/drivers/scsi/3w-xxxx.h +++ b/drivers/scsi/3w-xxxx.h @@ -6,7 +6,7 @@ Arnaldo Carvalho de Melo <acme@conectiva.com.br> Brad Strand <linux@3ware.com> - Copyright (C) 1999-2005 3ware Inc. + Copyright (C) 1999-2007 3ware Inc. Kernel compatiblity By: Andre Hedrick <andre@suse.com> Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com> diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 60f58272718..7869c34a4a3 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1303,7 +1303,7 @@ config SCSI_LPFC config SCSI_SEAGATE tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" - depends on X86 && ISA && SCSI && BROKEN + depends on X86 && ISA && SCSI ---help--- These are 8-bit SCSI controllers; the ST-01 is also supported by this driver. It is explained in section 3.9 of the SCSI-HOWTO, diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 359e7ddfdb4..d2cf875af59 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -117,8 +117,8 @@ static struct pci_device_id aac_pci_tbl[] = { { 0x9005, 0x0286, 0x9005, 0x029b, 0, 0, 22 }, /* AAR-2820SA (Intruder) */ { 0x9005, 0x0286, 0x9005, 0x029c, 0, 0, 23 }, /* AAR-2620SA (Intruder) */ { 0x9005, 0x0286, 0x9005, 0x029d, 0, 0, 24 }, /* AAR-2420SA (Intruder) */ - { 0x9005, 0x0286, 0x9005, 0x029e, 0, 0, 25 }, /* ICP9024R0 (Lancer) */ - { 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014R0 (Lancer) */ + { 0x9005, 0x0286, 0x9005, 0x029e, 0, 0, 25 }, /* ICP9024RO (Lancer) */ + { 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014RO (Lancer) */ { 0x9005, 0x0286, 0x9005, 0x02a0, 0, 0, 27 }, /* ICP9047MA (Lancer) */ { 0x9005, 0x0286, 0x9005, 0x02a1, 0, 0, 28 }, /* ICP9087MA (Lancer) */ { 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5445AU (Hurricane44) */ @@ -137,15 +137,15 @@ static struct pci_device_id aac_pci_tbl[] = { { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 41 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ { 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 42 }, /* AAR-2610SA PCI SATA 6ch */ { 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 43 }, /* ASR-2240S (SabreExpress) */ - { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005SAS */ + { 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005 */ { 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 45 }, /* IBM 8i (AvonPark) */ { 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 45 }, /* IBM 8i (AvonPark Lite) */ { 0x9005, 0x0286, 0x1014, 0x9580, 0, 0, 46 }, /* IBM 8k/8k-l8 (Aurora) */ { 0x9005, 0x0286, 0x1014, 0x9540, 0, 0, 47 }, /* IBM 8k/8k-l4 (Aurora Lite) */ - { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */ + { 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000 (BlackBird) */ { 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */ { 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */ - { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-3800SAS (Hurricane44) */ + { 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-3800 (Hurricane44) */ { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/ { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/ @@ -193,8 +193,8 @@ static struct aac_driver_ident aac_drivers[] = { { aac_rkt_init, "aacraid", "ADAPTEC ", "AAR-2820SA ", 1 }, /* AAR-2820SA (Intruder) */ { aac_rkt_init, "aacraid", "ADAPTEC ", "AAR-2620SA ", 1 }, /* AAR-2620SA (Intruder) */ { aac_rkt_init, "aacraid", "ADAPTEC ", "AAR-2420SA ", 1 }, /* AAR-2420SA (Intruder) */ - { aac_rkt_init, "aacraid", "ICP ", "ICP9024R0 ", 2 }, /* ICP9024R0 (Lancer) */ - { aac_rkt_init, "aacraid", "ICP ", "ICP9014R0 ", 1 }, /* ICP9014R0 (Lancer) */ + { aac_rkt_init, "aacraid", "ICP ", "ICP9024RO ", 2 }, /* ICP9024RO (Lancer) */ + { aac_rkt_init, "aacraid", "ICP ", "ICP9014RO ", 1 }, /* ICP9014RO (Lancer) */ { aac_rkt_init, "aacraid", "ICP ", "ICP9047MA ", 1 }, /* ICP9047MA (Lancer) */ { aac_rkt_init, "aacraid", "ICP ", "ICP9087MA ", 1 }, /* ICP9087MA (Lancer) */ { aac_rkt_init, "aacraid", "ICP ", "ICP5445AU ", 1 }, /* ICP5445AU (Hurricane44) */ @@ -212,14 +212,14 @@ static struct aac_driver_ident aac_drivers[] = { { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2026ZCR ", 1 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2610SA ", 1 }, /* SATA 6Ch (Bearcat) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2240S ", 1 }, /* ASR-2240S (SabreExpress) */ - { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4005SAS ", 1 }, /* ASR-4005SAS */ + { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4005 ", 1 }, /* ASR-4005 */ { aac_rx_init, "ServeRAID","IBM ", "ServeRAID 8i ", 1 }, /* IBM 8i (AvonPark) */ { aac_rkt_init, "ServeRAID","IBM ", "ServeRAID 8k-l8 ", 1 }, /* IBM 8k/8k-l8 (Aurora) */ { aac_rkt_init, "ServeRAID","IBM ", "ServeRAID 8k-l4 ", 1 }, /* IBM 8k/8k-l4 (Aurora Lite) */ - { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4000SAS ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4000 ", 1 }, /* ASR-4000 (BlackBird & AvonPark) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4800SAS ", 1 }, /* ASR-4800SAS (Marauder-X) */ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4805SAS ", 1 }, /* ASR-4805SAS (Marauder-E) */ - { aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-3800SAS ", 1 }, /* ASR-3800SAS (Hurricane44) */ + { aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-3800 ", 1 }, /* ASR-3800 (Hurricane44) */ { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/ { aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/ diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 2b344356a29..306bec355e4 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -18215,6 +18215,7 @@ AdvInquiryHandling( } MODULE_LICENSE("Dual BSD/GPL"); +#ifdef CONFIG_PCI /* PCI Devices supported by this driver */ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A, @@ -18232,4 +18233,4 @@ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { { } }; MODULE_DEVICE_TABLE(pci, advansys_pci_tbl); - +#endif /* CONFIG_PCI */ diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index d0b139cccbb..43768408437 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -749,7 +749,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) if (!offset) crypto_hash_update( &tcp_conn->rx_hash, - &sg[i], 1); + &sg[i], sg[i].length); else partial_sg_digest_update( &tcp_conn->rx_hash, @@ -1777,13 +1777,13 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0, CRYPTO_ALG_ASYNC); tcp_conn->tx_hash.flags = 0; - if (!tcp_conn->tx_hash.tfm) + if (IS_ERR(tcp_conn->tx_hash.tfm)) goto free_tcp_conn; tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0, CRYPTO_ALG_ASYNC); tcp_conn->rx_hash.flags = 0; - if (!tcp_conn->rx_hash.tfm) + if (IS_ERR(tcp_conn->rx_hash.tfm)) goto free_tx_tfm; return cls_conn; @@ -2044,13 +2044,11 @@ iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, sk = tcp_conn->sock->sk; if (sk->sk_family == PF_INET) { inet = inet_sk(sk); - len = sprintf(buf, "%u.%u.%u.%u\n", + len = sprintf(buf, NIPQUAD_FMT "\n", NIPQUAD(inet->daddr)); } else { np = inet6_sk(sk); - len = sprintf(buf, - "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - NIP6(np->daddr)); + len = sprintf(buf, NIP6_FMT "\n", NIP6(np->daddr)); } mutex_unlock(&conn->xmitmutex); break; diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index e11b23c641e..d37048c96ea 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -260,7 +260,7 @@ static int iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } if (rhdr->cmd_status == SAM_STAT_CHECK_CONDITION) { - int senselen; + uint16_t senselen; if (datalen < 2) { invalid_datalen: @@ -270,12 +270,12 @@ invalid_datalen: goto out; } - senselen = (data[0] << 8) | data[1]; + senselen = be16_to_cpu(*(uint16_t *)data); if (datalen < senselen) goto invalid_datalen; memcpy(sc->sense_buffer, data + 2, - min(senselen, SCSI_SENSE_BUFFERSIZE)); + min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); debug_scsi("copied %d bytes of sense\n", min(senselen, SCSI_SENSE_BUFFERSIZE)); } diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 066292d3995..ec3bbbde6f7 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -56,6 +56,9 @@ lpfc_mem_alloc(struct lpfc_hba * phba) pool->elements = kmalloc(sizeof(struct lpfc_dmabuf) * LPFC_MBUF_POOL_SIZE, GFP_KERNEL); + if (!pool->elements) + goto fail_free_lpfc_mbuf_pool; + pool->max_count = 0; pool->current_count = 0; for ( i = 0; i < LPFC_MBUF_POOL_SIZE; i++) { @@ -82,10 +85,11 @@ lpfc_mem_alloc(struct lpfc_hba * phba) fail_free_mbox_pool: mempool_destroy(phba->mbox_mem_pool); fail_free_mbuf_pool: - while (--i) + while (i--) pci_pool_free(phba->lpfc_mbuf_pool, pool->elements[i].virt, pool->elements[i].phys); kfree(pool->elements); + fail_free_lpfc_mbuf_pool: pci_pool_destroy(phba->lpfc_mbuf_pool); fail_free_dma_buf_pool: pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 046223b4ae5..b5bdd0d7a8b 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -13,8 +13,8 @@ * Version : v00.00.03.05 * * Authors: - * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> - * Sumant Patro <Sumant.Patro@lsil.com> + * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsi.com> + * Sumant Patro <Sumant.Patro@lsi.com> * * List of supported controllers * @@ -45,7 +45,7 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(MEGASAS_VERSION); -MODULE_AUTHOR("sreenivas.bagalkote@lsil.com"); +MODULE_AUTHOR("megaraidlinux@lsi.com"); MODULE_DESCRIPTION("LSI Logic MegaRAID SAS Driver"); /* diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 9fb0ea5c1fb..5b458d2478f 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -545,8 +545,6 @@ SYM53C500_release(struct pcmcia_device *link) */ if (shost->irq) free_irq(shost->irq, shost); - if (shost->dma_channel != 0xff) - free_dma(shost->dma_channel); if (shost->io_port && shost->n_io_port) release_region(shost->io_port, shost->n_io_port); diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 16af5b79e58..1548d42a3b4 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -1341,7 +1341,7 @@ qla1280_return_status(struct response * sts, struct scsi_cmnd *cp) int host_status = DID_ERROR; uint16_t comp_status = le16_to_cpu(sts->comp_status); uint16_t state_flags = le16_to_cpu(sts->state_flags); - uint16_t residual_length = le32_to_cpu(sts->residual_length); + uint32_t residual_length = le32_to_cpu(sts->residual_length); uint16_t scsi_status = le16_to_cpu(sts->scsi_status); #if DEBUG_QLA1280_INTR static char *reason[] = { @@ -1413,8 +1413,10 @@ qla1280_return_status(struct response * sts, struct scsi_cmnd *cp) "scsi: Underflow detected - retrying " "command.\n"); host_status = DID_ERROR; - } else + } else { + cp->resid = residual_length; host_status = DID_OK; + } break; default: diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c4fc40f8e8c..2c10130d9e0 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1602,6 +1602,7 @@ typedef struct fc_port { #define CT_REJECT_RESPONSE 0x8001 #define CT_ACCEPT_RESPONSE 0x8002 +#define CT_REASON_INVALID_COMMAND_CODE 0x01 #define CT_REASON_CANNOT_PERFORM 0x09 #define CT_EXPL_ALREADY_REGISTERED 0x10 @@ -2079,6 +2080,7 @@ typedef struct scsi_qla_host { uint32_t msi_enabled :1; uint32_t msix_enabled :1; uint32_t disable_serdes :1; + uint32_t gpsc_supported :1; } flags; atomic_t loop_state; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 32ebeec45ff..e4dd12f4b80 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -45,7 +45,6 @@ extern void qla2x00_update_fcports(scsi_qla_host_t *); extern int qla2x00_abort_isp(scsi_qla_host_t *); extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); -extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 97fbc62ec66..ec5b2dd90d6 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -127,8 +127,8 @@ qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt, ha->host_no, routine, ms_pkt->entry_status)); } else { if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) - comp_status = - ((struct ct_entry_24xx *)ms_pkt)->comp_status; + comp_status = le16_to_cpu( + ((struct ct_entry_24xx *)ms_pkt)->comp_status); else comp_status = le16_to_cpu(ms_pkt->status); switch (comp_status) { @@ -143,6 +143,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt, DEBUG2_3(qla2x00_dump_buffer( (uint8_t *)&ct_rsp->header, sizeof(struct ct_rsp_hdr))); + rval = QLA_INVALID_COMMAND; } else rval = QLA_SUCCESS; break; @@ -1683,7 +1684,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list) memset(list[i].fabric_port_name, 0, WWN_SIZE); /* Prepare common MS IOCB */ - ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, + ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, GFPN_ID_RSP_SIZE); /* Prepare CT request */ @@ -1784,6 +1785,8 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) return QLA_FUNCTION_FAILED; + if (!ha->flags.gpsc_supported) + return QLA_FUNCTION_FAILED; rval = qla2x00_mgmt_svr_login(ha); if (rval) @@ -1813,8 +1816,19 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) /*EMPTY*/ DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB " "failed (%d).\n", ha->host_no, rval)); - } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, - "GPSC") != QLA_SUCCESS) { + } else if ((rval = qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, + "GPSC")) != QLA_SUCCESS) { + /* FM command unsupported? */ + if (rval == QLA_INVALID_COMMAND && + ct_rsp->header.reason_code == + CT_REASON_INVALID_COMMAND_CODE) { + DEBUG2(printk("scsi(%ld): GPSC command " + "unsupported, disabling query...\n", + ha->host_no)); + ha->flags.gpsc_supported = 0; + rval = QLA_FUNCTION_FAILED; + break; + } rval = QLA_FUNCTION_FAILED; } else { /* Save portname */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a823f0bc519..b3dac26ddba 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2103,40 +2103,7 @@ qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) } } -/* - * qla2x00_update_fcport - * Updates device on list. - * - * Input: - * ha = adapter block pointer. - * fcport = port structure pointer. - * - * Return: - * 0 - Success - * BIT_0 - error - * - * Context: - * Kernel context. - */ -void -qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) -{ - fcport->ha = ha; - fcport->login_retry = 0; - fcport->port_login_retry_count = ha->port_down_retry_count * - PORT_RETRY_TIME; - atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * - PORT_RETRY_TIME); - fcport->flags &= ~FCF_LOGIN_NEEDED; - - qla2x00_iidma_fcport(ha, fcport); - - atomic_set(&fcport->state, FCS_ONLINE); - - qla2x00_reg_remote_port(ha, fcport); -} - -void +static void qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) { struct fc_rport_identifiers rport_ids; @@ -2179,6 +2146,39 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) } /* + * qla2x00_update_fcport + * Updates device on list. + * + * Input: + * ha = adapter block pointer. + * fcport = port structure pointer. + * + * Return: + * 0 - Success + * BIT_0 - error + * + * Context: + * Kernel context. + */ +void +qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) +{ + fcport->ha = ha; + fcport->login_retry = 0; + fcport->port_login_retry_count = ha->port_down_retry_count * + PORT_RETRY_TIME; + atomic_set(&fcport->port_down_timer, ha->port_down_retry_count * + PORT_RETRY_TIME); + fcport->flags &= ~FCF_LOGIN_NEEDED; + + qla2x00_iidma_fcport(ha, fcport); + + atomic_set(&fcport->state, FCS_ONLINE); + + qla2x00_reg_remote_port(ha, fcport); +} + +/* * qla2x00_configure_fabric * Setup SNS devices with loop ID's. * @@ -3476,9 +3476,11 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) /* Set host adapter parameters. */ ha->flags.disable_risc_code_load = 0; - ha->flags.enable_lip_reset = 1; - ha->flags.enable_lip_full_login = 1; - ha->flags.enable_target_reset = 1; + ha->flags.enable_lip_reset = 0; + ha->flags.enable_lip_full_login = + le32_to_cpu(nv->host_p) & BIT_10 ? 1: 0; + ha->flags.enable_target_reset = + le32_to_cpu(nv->host_p) & BIT_11 ? 1: 0; ha->flags.enable_led_scheme = 0; ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d3b6df4d55c..39fd17b05be 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -134,11 +134,11 @@ qla2300_intr_handler(int irq, void *dev_id) if (stat & HSR_RISC_PAUSED) { hccr = RD_REG_WORD(®->hccr); if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8)) - qla_printk(KERN_INFO, ha, - "Parity error -- HCCR=%x.\n", hccr); + qla_printk(KERN_INFO, ha, "Parity error -- " + "HCCR=%x, Dumping firmware!\n", hccr); else - qla_printk(KERN_INFO, ha, - "RISC paused -- HCCR=%x.\n", hccr); + qla_printk(KERN_INFO, ha, "RISC paused -- " + "HCCR=%x, Dumping firmware!\n", hccr); /* * Issue a "HARD" reset in order for the RISC @@ -147,6 +147,8 @@ qla2300_intr_handler(int irq, void *dev_id) */ WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); RD_REG_WORD(®->hccr); + + ha->isp_ops.fw_dump(ha, 1); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); break; } else if ((stat & HSR_RISC_INT) == 0) @@ -475,6 +477,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); } set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); + + ha->flags.gpsc_supported = 1; break; case MBA_CHG_IN_CONNECTION: /* Change in connection mode */ @@ -1440,8 +1444,7 @@ qla24xx_intr_handler(int irq, void *dev_id) qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " "Dumping firmware!\n", hccr); - qla24xx_fw_dump(ha, 1); - + ha->isp_ops.fw_dump(ha, 1); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); break; } else if ((stat & HSRX_RISC_INT) == 0) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 4cde76c85cb..077e5789bee 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -1339,9 +1339,9 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { mcp->mb[0] = MBC_LIP_FULL_LOGIN; - mcp->mb[1] = BIT_0; - mcp->mb[2] = 0xff; - mcp->mb[3] = 0; + mcp->mb[1] = BIT_6; + mcp->mb[2] = 0; + mcp->mb[3] = ha->loop_reset_delay; mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; } else { mcp->mb[0] = MBC_LIP_RESET; @@ -1823,8 +1823,8 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) ha->host_no)); mcp->mb[0] = MBC_LIP_FULL_LOGIN; - mcp->mb[1] = 0; - mcp->mb[2] = 0xff; + mcp->mb[1] = IS_QLA24XX(ha) || IS_QLA54XX(ha) ? BIT_3: 0; + mcp->mb[2] = 0; mcp->mb[3] = 0; mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; @@ -2486,7 +2486,7 @@ qla2x00_trace_control(scsi_qla_host_t *ha, uint16_t ctrl, dma_addr_t eft_dma, mcp->mb[4] = LSW(MSD(eft_dma)); mcp->mb[5] = MSW(MSD(eft_dma)); mcp->mb[6] = buffers; - mcp->mb[7] = buffers; + mcp->mb[7] = 0; mcp->out_mb |= MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2; } mcp->tov = 30; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d03523d3bf3..d6445ae841b 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1037,48 +1037,49 @@ eh_host_reset_lock: static int qla2x00_loop_reset(scsi_qla_host_t *ha) { - int status = QLA_SUCCESS; + int ret; struct fc_port *fcport; + if (ha->flags.enable_lip_full_login) { + ret = qla2x00_full_login_lip(ha); + if (ret != QLA_SUCCESS) { + DEBUG2_3(printk("%s(%ld): bus_reset failed: " + "full_login_lip=%d.\n", __func__, ha->host_no, + ret)); + } + atomic_set(&ha->loop_state, LOOP_DOWN); + atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); + qla2x00_mark_all_devices_lost(ha, 0); + qla2x00_wait_for_loop_ready(ha); + } + if (ha->flags.enable_lip_reset) { - status = qla2x00_lip_reset(ha); + ret = qla2x00_lip_reset(ha); + if (ret != QLA_SUCCESS) { + DEBUG2_3(printk("%s(%ld): bus_reset failed: " + "lip_reset=%d.\n", __func__, ha->host_no, ret)); + } + qla2x00_wait_for_loop_ready(ha); } - if (status == QLA_SUCCESS && ha->flags.enable_target_reset) { + if (ha->flags.enable_target_reset) { list_for_each_entry(fcport, &ha->fcports, list) { if (fcport->port_type != FCT_TARGET) continue; - status = qla2x00_device_reset(ha, fcport); - if (status != QLA_SUCCESS) - break; + ret = qla2x00_device_reset(ha, fcport); + if (ret != QLA_SUCCESS) { + DEBUG2_3(printk("%s(%ld): bus_reset failed: " + "target_reset=%d d_id=%x.\n", __func__, + ha->host_no, ret, fcport->d_id.b24)); + } } } - if (status == QLA_SUCCESS && - ((!ha->flags.enable_target_reset && - !ha->flags.enable_lip_reset) || - ha->flags.enable_lip_full_login)) { - - status = qla2x00_full_login_lip(ha); - } - /* Issue marker command only when we are going to start the I/O */ ha->marker_needed = 1; - if (status) { - /* Empty */ - DEBUG2_3(printk("%s(%ld): **** FAILED ****\n", - __func__, - ha->host_no)); - } else { - /* Empty */ - DEBUG3(printk("%s(%ld): exiting normally.\n", - __func__, - ha->host_no)); - } - - return(status); + return QLA_SUCCESS; } /* @@ -1413,7 +1414,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) sht = &qla2x00_driver_template; if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || - pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432) sht = &qla24xx_driver_template; host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); if (host == NULL) { diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 1fa0bce6b24..459e0d6bd2b 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.07-k3" +#define QLA2XXX_VERSION "8.01.07-k4" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 4249e52a559..6f4cf2dd2f4 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -418,7 +418,6 @@ struct scsi_qla_host { * concurrently. */ struct mutex mbox_sem; - wait_queue_head_t mailbox_wait_queue; /* temporary mailbox status registers */ volatile uint8_t mbox_status_count; diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 2122967bbf0..e021eb5db2b 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -76,4 +76,5 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, extern int ql4xextended_error_logging; extern int ql4xdiscoverywait; extern int ql4xdontresethba; +extern int ql4_mod_unload; #endif /* _QLA4x_GBL_H */ diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index cc210f297a7..b907b06d72a 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -958,25 +958,25 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) return status; } -int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) +int ql4xxx_lock_drvr_wait(struct scsi_qla_host *ha) { -#define QL4_LOCK_DRVR_WAIT 300 -#define QL4_LOCK_DRVR_SLEEP 100 +#define QL4_LOCK_DRVR_WAIT 30 +#define QL4_LOCK_DRVR_SLEEP 1 int drvr_wait = QL4_LOCK_DRVR_WAIT; while (drvr_wait) { - if (ql4xxx_lock_drvr(a) == 0) { - msleep(QL4_LOCK_DRVR_SLEEP); + if (ql4xxx_lock_drvr(ha) == 0) { + ssleep(QL4_LOCK_DRVR_SLEEP); if (drvr_wait) { DEBUG2(printk("scsi%ld: %s: Waiting for " - "Global Init Semaphore...n", - a->host_no, - __func__)); + "Global Init Semaphore(%d)...n", + ha->host_no, + __func__, drvr_wait)); } drvr_wait -= QL4_LOCK_DRVR_SLEEP; } else { DEBUG2(printk("scsi%ld: %s: Global Init Semaphore " - "acquired.n", a->host_no, __func__)); + "acquired.n", ha->host_no, __func__)); return QLA_SUCCESS; } } diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index ef975e0dc87..35b9e36a0e8 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -433,7 +433,6 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, readl(&ha->reg->mailbox[i]); set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); - wake_up(&ha->mailbox_wait_queue); } } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { /* Immediately process the AENs that don't require much work. @@ -686,7 +685,8 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) &ha->reg->ctrl_status); readl(&ha->reg->ctrl_status); - set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); + if (!ql4_mod_unload) + set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); break; } else if (intr_status & INTR_PENDING) { diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index b721dc5dd71..7f28657eef3 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -29,18 +29,30 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, u_long wait_count; uint32_t intr_status; unsigned long flags = 0; - DECLARE_WAITQUEUE(wait, current); - - mutex_lock(&ha->mbox_sem); - - /* Mailbox code active */ - set_bit(AF_MBOX_COMMAND, &ha->flags); /* Make sure that pointers are valid */ if (!mbx_cmd || !mbx_sts) { DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " "pointer\n", ha->host_no, __func__)); - goto mbox_exit; + return status; + } + /* Mailbox code active */ + wait_count = MBOX_TOV * 100; + + while (wait_count--) { + mutex_lock(&ha->mbox_sem); + if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { + set_bit(AF_MBOX_COMMAND, &ha->flags); + mutex_unlock(&ha->mbox_sem); + break; + } + mutex_unlock(&ha->mbox_sem); + if (!wait_count) { + DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n", + ha->host_no, __func__)); + return status; + } + msleep(10); } /* To prevent overwriting mailbox registers for a command that has @@ -73,8 +85,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Wait for completion */ - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(&ha->mailbox_wait_queue, &wait); /* * If we don't want status, don't wait for the mailbox command to @@ -83,8 +93,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, */ if (outCount == 0) { status = QLA_SUCCESS; - set_current_state(TASK_RUNNING); - remove_wait_queue(&ha->mailbox_wait_queue, &wait); goto mbox_exit; } /* Wait for command to complete */ @@ -108,8 +116,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, spin_unlock_irqrestore(&ha->hardware_lock, flags); msleep(10); } - set_current_state(TASK_RUNNING); - remove_wait_queue(&ha->mailbox_wait_queue, &wait); /* Check for mailbox timeout. */ if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { @@ -155,9 +161,10 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, spin_unlock_irqrestore(&ha->hardware_lock, flags); mbox_exit: + mutex_lock(&ha->mbox_sem); clear_bit(AF_MBOX_COMMAND, &ha->flags); - clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); mutex_unlock(&ha->mbox_sem); + clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); return status; } diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 9ef693c8809..81fb7bd44f0 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -40,6 +40,8 @@ MODULE_PARM_DESC(ql4xextended_error_logging, "Option to enable extended error logging, " "Default is 0 - no logging, 1 - debug logging"); +int ql4_mod_unload = 0; + /* * SCSI host template entry points */ @@ -422,6 +424,9 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, goto qc_host_busy; } + if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) + goto qc_host_busy; + spin_unlock_irq(ha->host->host_lock); srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done); @@ -707,16 +712,12 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) return stat; } -/** - * qla4xxx_soft_reset - performs soft reset. - * @ha: Pointer to host adapter structure. - **/ -int qla4xxx_soft_reset(struct scsi_qla_host *ha) +static void qla4xxx_hw_reset(struct scsi_qla_host *ha) { - uint32_t max_wait_time; - unsigned long flags = 0; - int status = QLA_ERROR; uint32_t ctrl_status; + unsigned long flags = 0; + + DEBUG2(printk(KERN_ERR "scsi%ld: %s\n", ha->host_no, __func__)); spin_lock_irqsave(&ha->hardware_lock, flags); @@ -733,6 +734,20 @@ int qla4xxx_soft_reset(struct scsi_qla_host *ha) readl(&ha->reg->ctrl_status); spin_unlock_irqrestore(&ha->hardware_lock, flags); +} + +/** + * qla4xxx_soft_reset - performs soft reset. + * @ha: Pointer to host adapter structure. + **/ +int qla4xxx_soft_reset(struct scsi_qla_host *ha) +{ + uint32_t max_wait_time; + unsigned long flags = 0; + int status = QLA_ERROR; + uint32_t ctrl_status; + + qla4xxx_hw_reset(ha); /* Wait until the Network Reset Intr bit is cleared */ max_wait_time = RESET_INTR_TOV; @@ -966,10 +981,12 @@ static void qla4xxx_do_dpc(struct work_struct *work) struct scsi_qla_host *ha = container_of(work, struct scsi_qla_host, dpc_work); struct ddb_entry *ddb_entry, *dtemp; + int status = QLA_ERROR; DEBUG2(printk("scsi%ld: %s: DPC handler waking up." - "flags = 0x%08lx, dpc_flags = 0x%08lx\n", - ha->host_no, __func__, ha->flags, ha->dpc_flags)); + "flags = 0x%08lx, dpc_flags = 0x%08lx ctrl_stat = 0x%08x\n", + ha->host_no, __func__, ha->flags, ha->dpc_flags, + readw(&ha->reg->ctrl_status))); /* Initialization not yet finished. Don't do anything yet. */ if (!test_bit(AF_INIT_DONE, &ha->flags)) @@ -983,31 +1000,28 @@ static void qla4xxx_do_dpc(struct work_struct *work) test_bit(DPC_RESET_HA, &ha->dpc_flags)) qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); - if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { + if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { uint8_t wait_time = RESET_INTR_TOV; - unsigned long flags = 0; - - qla4xxx_flush_active_srbs(ha); - spin_lock_irqsave(&ha->hardware_lock, flags); while ((readw(&ha->reg->ctrl_status) & (CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) { if (--wait_time == 0) break; - - spin_unlock_irqrestore(&ha->hardware_lock, - flags); - msleep(1000); - - spin_lock_irqsave(&ha->hardware_lock, flags); } - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (wait_time == 0) DEBUG2(printk("scsi%ld: %s: SR|FSR " "bit not cleared-- resetting\n", ha->host_no, __func__)); + qla4xxx_flush_active_srbs(ha); + if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) { + qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); + status = qla4xxx_initialize_adapter(ha, + PRESERVE_DDB_LIST); + } + clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); + if (status == QLA_SUCCESS) + qla4xxx_enable_intrs(ha); } } @@ -1062,7 +1076,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) /* Issue Soft Reset to put firmware in unknown state */ if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) - qla4xxx_soft_reset(ha); + qla4xxx_hw_reset(ha); /* Remove timer thread, if present */ if (ha->timer_active) @@ -1198,7 +1212,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, INIT_LIST_HEAD(&ha->free_srb_q); mutex_init(&ha->mbox_sem); - init_waitqueue_head(&ha->mailbox_wait_queue); spin_lock_init(&ha->hardware_lock); @@ -1665,6 +1678,7 @@ no_srp_cache: static void __exit qla4xxx_module_exit(void) { + ql4_mod_unload = 1; pci_unregister_driver(&qla4xxx_pci_driver); iscsi_unregister_transport(&qla4xxx_iscsi_transport); kmem_cache_destroy(srb_cachep); diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index 454e19c8ad6..e5183a697d1 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h @@ -5,4 +5,4 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ -#define QLA4XXX_DRIVER_VERSION "5.00.07-k" +#define QLA4XXX_DRIVER_VERSION "5.00.07-k1" diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 14e635aa44c..96b7cbd746a 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -133,12 +133,10 @@ struct async_scan_data { /** * scsi_complete_async_scans - Wait for asynchronous scans to complete * - * Asynchronous scans add themselves to the scanning_hosts list. Once - * that list is empty, we know that the scans are complete. Rather than - * waking up periodically to check the state of the list, we pretend to be - * a scanning task by adding ourselves at the end of the list and going to - * sleep. When the task before us wakes us up, we take ourselves off the - * list and return. + * When this function returns, any host which started scanning before + * this function was called will have finished its scan. Hosts which + * started scanning after this function was called may or may not have + * finished. */ int scsi_complete_async_scans(void) { @@ -171,6 +169,11 @@ int scsi_complete_async_scans(void) spin_lock(&async_scan_lock); list_del(&data->list); + if (!list_empty(&scanning_hosts)) { + struct async_scan_data *next = list_entry(scanning_hosts.next, + struct async_scan_data, list); + complete(&next->prev_finished); + } done: spin_unlock(&async_scan_lock); @@ -739,6 +742,14 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, sdev->no_uld_attach = 1; switch (sdev->type = (inq_result[0] & 0x1f)) { + case TYPE_RBC: + /* RBC devices can return SCSI-3 compliance and yet + * still not support REPORT LUNS, so make them act as + * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is + * specifically set */ + if ((*bflags & BLIST_REPORTLUN2) == 0) + *bflags |= BLIST_NOREPORTLUN; + /* fall through */ case TYPE_TAPE: case TYPE_DISK: case TYPE_PRINTER: @@ -749,11 +760,17 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, case TYPE_ENCLOSURE: case TYPE_COMM: case TYPE_RAID: - case TYPE_RBC: sdev->writeable = 1; break; - case TYPE_WORM: case TYPE_ROM: + /* MMC devices can return SCSI-3 compliance and yet + * still not support REPORT LUNS, so make them act as + * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is + * specifically set */ + if ((*bflags & BLIST_REPORTLUN2) == 0) + *bflags |= BLIST_NOREPORTLUN; + /* fall through */ + case TYPE_WORM: sdev->writeable = 0; break; default: @@ -1436,6 +1453,12 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, struct device *parent = &shost->shost_gendev; struct scsi_target *starget; + if (strncmp(scsi_scan_type, "none", 4) == 0) + return ERR_PTR(-ENODEV); + + if (!shost->async_scan) + scsi_complete_async_scans(); + starget = scsi_alloc_target(parent, channel, id); if (!starget) return ERR_PTR(-ENOMEM); diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 9c22f134271..ce0d14af33c 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1416,7 +1416,7 @@ static __init int iscsi_transport_init(void) { int err; - printk(KERN_INFO "Loading iSCSI transport class v%s.", + printk(KERN_INFO "Loading iSCSI transport class v%s.\n", ISCSI_TRANSPORT_VERSION); err = class_register(&iscsi_transport_class); diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 3fded483146..014d7fea1ff 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -122,7 +122,7 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd, if (!sshdr) sshdr = &sshdr_tmp; - if (scsi_normalize_sense(sense, sizeof(*sense), + if (scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr) && sshdr->sense_key == UNIT_ATTENTION) continue; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 978bfc1e0c6..b781a90d669 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1647,16 +1647,6 @@ static int sd_probe(struct device *dev) if (error) goto out_put; - class_device_initialize(&sdkp->cdev); - sdkp->cdev.dev = &sdp->sdev_gendev; - sdkp->cdev.class = &sd_disk_class; - strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); - - if (class_device_add(&sdkp->cdev)) - goto out_put; - - get_device(&sdp->sdev_gendev); - sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd; @@ -1670,6 +1660,16 @@ static int sd_probe(struct device *dev) sdp->timeout = SD_MOD_TIMEOUT; } + class_device_initialize(&sdkp->cdev); + sdkp->cdev.dev = &sdp->sdev_gendev; + sdkp->cdev.class = &sd_disk_class; + strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); + + if (class_device_add(&sdkp->cdev)) + goto out_put; + + get_device(&sdp->sdev_gendev); + gd->major = sd_major((index & 0xf0) >> 4); gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); gd->minors = 16; diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 5ffec2721b2..ff62e9708e1 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -114,6 +114,7 @@ #define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0) #else #define DPRINTK( when, msg... ) do { } while (0) +#define DEBUG 0 #endif #define DANY( msg... ) DPRINTK( 0xffff, msg ); @@ -523,7 +524,7 @@ int __init seagate_st0x_detect (struct scsi_host_template * tpnt) #ifdef ARBITRATE " ARBITRATE" #endif -#ifdef DEBUG +#if DEBUG " DEBUG" #endif #ifdef FAST @@ -733,7 +734,7 @@ static int internal_command (unsigned char target, unsigned char lun, unsigned char *data = NULL; struct scatterlist *buffer = NULL; int clock, temp, nobuffs = 0, done = 0, len = 0; -#ifdef DEBUG +#if DEBUG int transfered = 0, phase = 0, newphase; #endif register unsigned char status_read; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index fae6e95a629..89e9b36b178 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -468,7 +468,7 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, } ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg); - if (ret != ENOSYS) + if (ret != -ENOSYS) return ret; /* diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index e016e0906e1..488ec7948a5 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -2816,15 +2816,18 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon if (cmd_in == MTWEOF && cmdstatp->have_sense && - (cmdstatp->flags & SENSE_EOM) && - (cmdstatp->sense_hdr.sense_key == NO_SENSE || - cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) && - undone == 0) { - ioctl_result = 0; /* EOF written successfully at EOM */ - if (fileno >= 0) - fileno++; + (cmdstatp->flags & SENSE_EOM)) { + if (cmdstatp->sense_hdr.sense_key == NO_SENSE || + cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) { + ioctl_result = 0; /* EOF(s) written successfully at EOM */ + STps->eof = ST_NOEOF; + } else { /* Writing EOF(s) failed */ + if (fileno >= 0) + fileno -= undone; + if (undone < arg) + STps->eof = ST_NOEOF; + } STps->drv_file = fileno; - STps->eof = ST_NOEOF; } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) { if (fileno >= 0) STps->drv_file = fileno - undone; diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 61db6973755..f69bd097166 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -589,6 +589,8 @@ static int __init pl010_console_setup(struct console *co, char *options) */ if (co->index >= UART_NR) co->index = 0; + if (!amba_ports[co->index]) + return -ENODEV; port = &amba_ports[co->index]->port; if (options) diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 9a3b374b2a0..44639e71372 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -661,6 +661,8 @@ static int __init pl011_console_setup(struct console *co, char *options) if (co->index >= UART_NR) co->index = 0; uap = amba_ports[co->index]; + if (!uap) + return -ENODEV; uap->port.uartclk = clk_get_rate(uap->clk); diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index ed7f7209ea5..881f886b91c 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -689,9 +689,9 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, struct struct atmel_uart_data *data = pdev->dev.platform_data; port->iotype = UPIO_MEM; - port->flags = UPF_BOOT_AUTOCONF; + port->flags = UPF_BOOT_AUTOCONF; port->ops = &atmel_pops; - port->fifosize = 1; + port->fifosize = 1; port->line = pdev->id; port->dev = &pdev->dev; @@ -890,7 +890,6 @@ static int atmel_serial_suspend(struct platform_device *pdev, pm_message_t state if (device_may_wakeup(&pdev->dev) && !at91_suspend_entering_slow_clock()) enable_irq_wake(port->irq); else { - disable_irq_wake(port->irq); uart_suspend_port(&atmel_uart, port); atmel_port->suspended = 1; } @@ -907,6 +906,8 @@ static int atmel_serial_resume(struct platform_device *pdev) uart_resume_port(&atmel_uart, port); atmel_port->suspended = 0; } + else + disable_irq_wake(port->irq); return 0; } diff --git a/drivers/serial/atmel_serial.h b/drivers/serial/atmel_serial.h index fe1763b2a6d..11b44360e10 100644 --- a/drivers/serial/atmel_serial.h +++ b/drivers/serial/atmel_serial.h @@ -106,7 +106,7 @@ #define ATMEL_US_CSR 0x14 /* Channel Status Register */ #define ATMEL_US_RHR 0x18 /* Receiver Holding Register */ #define ATMEL_US_THR 0x1c /* Transmitter Holding Register */ -#define ATMEL_US_SYNH (1 << 15) /* Transmit/Receive Sync [SAM9 only] */ +#define ATMEL_US_SYNH (1 << 15) /* Transmit/Receive Sync [AT91SAM9261 only] */ #define ATMEL_US_BRGR 0x20 /* Baud Rate Generator Register */ #define ATMEL_US_CD (0xffff << 0) /* Clock Divider */ diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 6ed3f1da929..8b41f9cc256 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -1169,8 +1169,9 @@ static int setup(struct spi_device *spi) spi->bits_per_word - 16 : spi->bits_per_word) | SSCR0_SSE | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0); - chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4) - | (((spi->mode & SPI_CPOL) != 0) << 3); + chip->cr1 &= ~(SSCR1_SPO | SSCR1_SPH); + chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) ? SSCR1_SPH : 0) + | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); /* NOTE: PXA25x_SSP _could_ use external clocking ... */ if (drv_data->ssp_type != PXA25x_SSP) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 270e6211c2e..6307428d2c9 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -366,7 +366,6 @@ spi_alloc_master(struct device *dev, unsigned size) class_device_initialize(&master->cdev); master->cdev.class = &spi_master_class; - kobj_set_kset_s(&master->cdev, spi_master_class.subsys); master->cdev.dev = get_device(dev); spi_master_set_devdata(master, &master[1]); @@ -466,14 +465,20 @@ EXPORT_SYMBOL_GPL(spi_unregister_master); */ struct spi_master *spi_busnum_to_master(u16 bus_num) { - char name[9]; - struct kobject *bus; - - snprintf(name, sizeof name, "spi%u", bus_num); - bus = kset_find_obj(&spi_master_class.subsys.kset, name); - if (bus) - return container_of(bus, struct spi_master, cdev.kobj); - return NULL; + struct class_device *cdev; + struct spi_master *master = NULL; + struct spi_master *m; + + down(&spi_master_class.sem); + list_for_each_entry(cdev, &spi_master_class.children, node) { + m = container_of(cdev, struct spi_master, cdev); + if (m->bus_num == bus_num) { + master = spi_master_get(m); + break; + } + } + up(&spi_master_class.sem); + return master; } EXPORT_SYMBOL_GPL(spi_busnum_to_master); diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 8ca08713528..651379c51ae 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -10,9 +10,6 @@ * */ - -//#define DEBUG - #include <linux/init.h> #include <linux/spinlock.h> #include <linux/workqueue.h> @@ -44,6 +41,9 @@ struct s3c24xx_spi { int len; int count; + int (*set_cs)(struct s3c2410_spi_info *spi, + int cs, int pol); + /* data buffers */ const unsigned char *tx; unsigned char *rx; @@ -64,6 +64,11 @@ static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) return spi_master_get_devdata(sdev->master); } +static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) +{ + s3c2410_gpio_setpin(spi->pin_cs, pol); +} + static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) { struct s3c24xx_spi *hw = to_hw(spi); @@ -72,10 +77,7 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) switch (value) { case BITBANG_CS_INACTIVE: - if (hw->pdata->set_cs) - hw->pdata->set_cs(hw->pdata, value, cspol); - else - s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1); + hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol^1); break; case BITBANG_CS_ACTIVE: @@ -96,14 +98,9 @@ static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) /* write new configration */ writeb(spcon, hw->regs + S3C2410_SPCON); - - if (hw->pdata->set_cs) - hw->pdata->set_cs(hw->pdata, value, cspol); - else - s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol); + hw->pdata->set_cs(hw->pdata, spi->chip_select, cspol); break; - } } @@ -330,9 +327,12 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) /* setup any gpio we can */ if (!hw->pdata->set_cs) { + hw->set_cs = s3c24xx_spi_gpiocs; + s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); - } + } else + hw->set_cs = hw->pdata->set_cs; /* register our spi controller */ diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index f8324d8d06a..3e66b2a9974 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -72,22 +72,6 @@ config USB_SUSPEND If you are unsure about this, say N here. -config USB_MULTITHREAD_PROBE - bool "USB Multi-threaded probe (EXPERIMENTAL)" - depends on USB && EXPERIMENTAL - default n - help - Say Y here if you want the USB core to spawn a new thread for - every USB device that is probed. This can cause a small speedup - in boot times on systems with a lot of different USB devices. - - This option should be safe to enable, but if any odd probing - problems are found, please disable it, or dynamically turn it - off in the /sys/module/usbcore/parameters/multithread_probe - file - - When in doubt, say N. - config USB_OTG bool depends on USB && EXPERIMENTAL diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2651c2e2a89..1988224b362 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -88,14 +88,7 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); static struct task_struct *khubd_task; /* multithreaded probe logic */ -static int multithread_probe = -#ifdef CONFIG_USB_MULTITHREAD_PROBE - 1; -#else - 0; -#endif -module_param(multithread_probe, bool, S_IRUGO); -MODULE_PARM_DESC(multithread_probe, "Run each USB device probe in a new thread"); +static int multithread_probe = 0; /* cycle leds on hubs that aren't blinking for attention */ static int blinkenlights = 0; diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 43ae696b2ec..3348b07f0fe 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -169,7 +169,7 @@ static int ohci_hcd_ep93xx_drv_remove(struct platform_device *pdev) static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_t state) { struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct ochi_hcd *ohci = hcd_to_ohci(hcd); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); if (time_before(jiffies, ohci->next_statechange)) msleep(5); diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 258a5d09d3d..c7d887540d8 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig @@ -7,7 +7,7 @@ comment "USB Input Devices" config USB_HID tristate "USB Human Interface Device (full HID) support" default y - depends on USB + depends on USB && INPUT select HID ---help--- Say Y here if you want full HID support to connect USB keyboards, diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 89fa6885709..c6c9e72e5fd 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -56,11 +56,6 @@ static unsigned int hid_mousepoll_interval; module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -static int usbhid_pb_fnmode = 1; -module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); -MODULE_PARM_DESC(pb_fnmode, - "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); - /* * Input submission and I/O error handler. */ @@ -106,18 +101,18 @@ static void hid_reset(struct work_struct *work) if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { dev_dbg(&usbhid->intf->dev, "clear halt\n"); - rc = usb_clear_halt(to_usb_device(hid->dev), usbhid->urbin->pipe); + rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe); clear_bit(HID_CLEAR_HALT, &usbhid->iofl); hid_start_in(hid); } else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { dev_dbg(&usbhid->intf->dev, "resetting device\n"); - rc = rc_lock = usb_lock_device_for_reset(to_usb_device(hid->dev), usbhid->intf); + rc = rc_lock = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); if (rc_lock >= 0) { - rc = usb_reset_composite_device(to_usb_device(hid->dev), usbhid->intf); + rc = usb_reset_composite_device(hid_to_usb_dev(hid), usbhid->intf); if (rc_lock) - usb_unlock_device(to_usb_device(hid->dev)); + usb_unlock_device(hid_to_usb_dev(hid)); } clear_bit(HID_RESET_PENDING, &usbhid->iofl); } @@ -129,8 +124,8 @@ static void hid_reset(struct work_struct *work) break; default: err("can't reset device, %s-%s/input%d, status %d", - to_usb_device(hid->dev)->bus->bus_name, - to_usb_device(hid->dev)->devpath, + hid_to_usb_dev(hid)->bus->bus_name, + hid_to_usb_dev(hid)->devpath, usbhid->ifnum, rc); /* FALLTHROUGH */ case -EHOSTUNREACH: @@ -217,8 +212,8 @@ static void hid_irq_in(struct urb *urb) clear_bit(HID_IN_RUNNING, &usbhid->iofl); if (status != -EPERM) { err("can't resubmit intr, %s-%s/input%d, status %d", - to_usb_device(hid->dev)->bus->bus_name, - to_usb_device(hid->dev)->devpath, + hid_to_usb_dev(hid)->bus->bus_name, + hid_to_usb_dev(hid)->devpath, usbhid->ifnum, status); hid_io_error(hid); } @@ -251,7 +246,7 @@ static int hid_submit_out(struct hid_device *hid) hid_output_report(report, usbhid->outbuf); usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); - usbhid->urbout->dev = to_usb_device(hid->dev); + usbhid->urbout->dev = hid_to_usb_dev(hid); dbg("submitting out urb"); @@ -276,13 +271,13 @@ static int hid_submit_ctrl(struct hid_device *hid) len = ((report->size - 1) >> 3) + 1 + (report->id > 0); if (dir == USB_DIR_OUT) { hid_output_report(report, usbhid->ctrlbuf); - usbhid->urbctrl->pipe = usb_sndctrlpipe(to_usb_device(hid->dev), 0); + usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); usbhid->urbctrl->transfer_buffer_length = len; } else { int maxpacket, padlen; - usbhid->urbctrl->pipe = usb_rcvctrlpipe(to_usb_device(hid->dev), 0); - maxpacket = usb_maxpacket(to_usb_device(hid->dev), usbhid->urbctrl->pipe, 0); + usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0); + maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0); if (maxpacket > 0) { padlen = (len + maxpacket - 1) / maxpacket; padlen *= maxpacket; @@ -292,7 +287,7 @@ static int hid_submit_ctrl(struct hid_device *hid) padlen = 0; usbhid->urbctrl->transfer_buffer_length = padlen; } - usbhid->urbctrl->dev = to_usb_device(hid->dev); + usbhid->urbctrl->dev = hid_to_usb_dev(hid); usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; @@ -582,6 +577,7 @@ void usbhid_init_reports(struct hid_device *hid) } #define USB_VENDOR_ID_GTCO 0x078c +#define USB_VENDOR_ID_GTCO_IPANEL_2 0x5543 #define USB_DEVICE_ID_GTCO_90 0x0090 #define USB_DEVICE_ID_GTCO_100 0x0100 #define USB_DEVICE_ID_GTCO_101 0x0101 @@ -627,6 +623,8 @@ void usbhid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_GTCO_1004 0x1004 #define USB_DEVICE_ID_GTCO_1005 0x1005 #define USB_DEVICE_ID_GTCO_1006 0x1006 +#define USB_DEVICE_ID_GTCO_8 0x0008 +#define USB_DEVICE_ID_GTCO_d 0x000d #define USB_VENDOR_ID_WACOM 0x056a @@ -791,6 +789,9 @@ void usbhid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_LOGITECH 0x046d #define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101 +#define USB_VENDOR_ID_IMATION 0x0718 +#define USB_DEVICE_ID_DISC_STAKKA 0xd000 + /* * Alphabetically sorted blacklist by quirk type. */ @@ -875,6 +876,9 @@ static const struct hid_blacklist { { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_8, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_d, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE }, @@ -951,7 +955,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, @@ -1187,7 +1191,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) hid->version = le16_to_cpu(hdesc->bcdHID); hid->country = hdesc->bCountryCode; - hid->dev = &dev->dev; + hid->dev = &intf->dev; usbhid->intf = intf; usbhid->ifnum = interface->desc.bInterfaceNumber; @@ -1237,10 +1241,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) hid->hiddev_hid_event = hiddev_hid_event; hid->hiddev_report_event = hiddev_report_event; #endif -#ifdef CONFIG_USB_HIDINPUT_POWERBOOK - hid->pb_fnmode = usbhid_pb_fnmode; -#endif - return hid; fail: @@ -1282,7 +1282,7 @@ static void hid_disconnect(struct usb_interface *intf) usb_free_urb(usbhid->urbctrl); usb_free_urb(usbhid->urbout); - hid_free_buffers(to_usb_device(hid->dev), hid); + hid_free_buffers(hid_to_usb_dev(hid), hid); hid_free_device(hid); } diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c index f8f660ee3fa..59ed65e7a62 100644 --- a/drivers/usb/input/hid-ff.c +++ b/drivers/usb/input/hid-ff.c @@ -33,6 +33,7 @@ #include <linux/usb.h> #include <linux/hid.h> +#include "usbhid.h" /* * This table contains pointers to initializers. To add support for new @@ -70,8 +71,8 @@ static struct hid_ff_initializer inits[] = { int hid_ff_init(struct hid_device* hid) { struct hid_ff_initializer *init; - int vendor = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idVendor); - int product = le16_to_cpu(to_usb_device(hid->dev)->descriptor.idProduct); + int vendor = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idVendor); + int product = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idProduct); for (init = inits; init->idVendor; init++) if (init->idVendor == vendor && init->idProduct == product) diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 114d6c9f64b..a8b3d66cd49 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c @@ -384,7 +384,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd struct hiddev_list *list = file->private_data; struct hiddev *hiddev = list->hiddev; struct hid_device *hid = hiddev->hid; - struct usb_device *dev = to_usb_device(hid->dev); + struct usb_device *dev = hid_to_usb_dev(hid); struct hiddev_collection_info cinfo; struct hiddev_report_info rinfo; struct hiddev_field_info finfo; diff --git a/drivers/usb/input/usbhid.h b/drivers/usb/input/usbhid.h index 830107e5251..0023f96d429 100644 --- a/drivers/usb/input/usbhid.h +++ b/drivers/usb/input/usbhid.h @@ -80,5 +80,8 @@ struct usbhid_device { }; +#define hid_to_usb_dev(hid_dev) \ + container_of(hid_dev->dev->parent, struct usb_device, dev) + #endif diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c index 7f3c57da9bc..86e37a20f8e 100644 --- a/drivers/usb/input/usbtouchscreen.c +++ b/drivers/usb/input/usbtouchscreen.c @@ -66,7 +66,7 @@ struct usbtouch_device_info { void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); int (*get_pkt_len) (unsigned char *pkt, int len); - int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); + int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); int (*init) (struct usbtouch_usb *usbtouch); }; @@ -85,6 +85,9 @@ struct usbtouch_usb { struct usbtouch_device_info *type; char name[128]; char phys[64]; + + int x, y; + int touch, press; }; @@ -161,14 +164,14 @@ static struct usb_device_id usbtouch_devices[] = { #define EGALAX_PKT_TYPE_REPT 0x80 #define EGALAX_PKT_TYPE_DIAG 0x0A -static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) return 0; - *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); - *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); - *touch = pkt[0] & 0x01; + dev->x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); + dev->y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); + dev->touch = pkt[0] & 0x01; return 1; } @@ -195,11 +198,11 @@ static int egalax_get_pkt_len(unsigned char *buf, int len) * PanJit Part */ #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT -static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { - *x = ((pkt[2] & 0x0F) << 8) | pkt[1]; - *y = ((pkt[4] & 0x0F) << 8) | pkt[3]; - *touch = pkt[0] & 0x01; + dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; + dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; + dev->touch = pkt[0] & 0x01; return 1; } @@ -215,11 +218,11 @@ static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int #define MTOUCHUSB_RESET 7 #define MTOUCHUSB_REQ_CTRLLR_ID 10 -static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { - *x = (pkt[8] << 8) | pkt[7]; - *y = (pkt[10] << 8) | pkt[9]; - *touch = (pkt[2] & 0x40) ? 1 : 0; + dev->x = (pkt[8] << 8) | pkt[7]; + dev->y = (pkt[10] << 8) | pkt[9]; + dev->touch = (pkt[2] & 0x40) ? 1 : 0; return 1; } @@ -260,14 +263,32 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) * ITM Part */ #ifdef CONFIG_USB_TOUCHSCREEN_ITM -static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { - *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); - *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); - *press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); - *touch = ~pkt[7] & 0x20; + int touch; + /* + * ITM devices report invalid x/y data if not touched. + * if the screen was touched before but is not touched any more + * report touch as 0 with the last valid x/y data once. then stop + * reporting data until touched again. + */ + dev->press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); + + touch = ~pkt[7] & 0x20; + if (!touch) { + if (dev->touch) { + dev->touch = 0; + return 1; + } - return *touch; + return 0; + } + + dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); + dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); + dev->touch = touch; + + return 1; } #endif @@ -276,7 +297,7 @@ static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *pr * eTurboTouch part */ #ifdef CONFIG_USB_TOUCHSCREEN_ETURBO -static int eturbo_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { unsigned int shift; @@ -285,9 +306,9 @@ static int eturbo_read_data(unsigned char *pkt, int *x, int *y, int *touch, int return 0; shift = (6 - (pkt[0] & 0x03)); - *x = ((pkt[3] << 7) | pkt[4]) >> shift; - *y = ((pkt[1] << 7) | pkt[2]) >> shift; - *touch = (pkt[0] & 0x10) ? 1 : 0; + dev->x = ((pkt[3] << 7) | pkt[4]) >> shift; + dev->y = ((pkt[1] << 7) | pkt[2]) >> shift; + dev->touch = (pkt[0] & 0x10) ? 1 : 0; return 1; } @@ -307,14 +328,14 @@ static int eturbo_get_pkt_len(unsigned char *buf, int len) * Gunze part */ #ifdef CONFIG_USB_TOUCHSCREEN_GUNZE -static int gunze_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80)) return 0; - *x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F); - *y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F); - *touch = pkt[0] & 0x20; + dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F); + dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F); + dev->touch = pkt[0] & 0x20; return 1; } @@ -383,11 +404,11 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) } -static int dmc_tsc10_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) +static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt) { - *x = ((pkt[2] & 0x03) << 8) | pkt[1]; - *y = ((pkt[4] & 0x03) << 8) | pkt[3]; - *touch = pkt[0] & 0x01; + dev->x = ((pkt[2] & 0x03) << 8) | pkt[1]; + dev->y = ((pkt[4] & 0x03) << 8) | pkt[3]; + dev->touch = pkt[0] & 0x01; return 1; } @@ -492,23 +513,22 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, unsigned char *pkt, int len) { - int x, y, touch, press; struct usbtouch_device_info *type = usbtouch->type; - if (!type->read_data(pkt, &x, &y, &touch, &press)) + if (!type->read_data(usbtouch, pkt)) return; - input_report_key(usbtouch->input, BTN_TOUCH, touch); + input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch); if (swap_xy) { - input_report_abs(usbtouch->input, ABS_X, y); - input_report_abs(usbtouch->input, ABS_Y, x); + input_report_abs(usbtouch->input, ABS_X, usbtouch->y); + input_report_abs(usbtouch->input, ABS_Y, usbtouch->x); } else { - input_report_abs(usbtouch->input, ABS_X, x); - input_report_abs(usbtouch->input, ABS_Y, y); + input_report_abs(usbtouch->input, ABS_X, usbtouch->x); + input_report_abs(usbtouch->input, ABS_Y, usbtouch->y); } if (type->max_press) - input_report_abs(usbtouch->input, ABS_PRESSURE, press); + input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press); input_sync(usbtouch->input); } diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index f538013965b..896449f0cf8 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c @@ -898,7 +898,7 @@ static int ax88772_link_reset(struct usbnet *dev) static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) { - int ret; + int ret, embd_phy; void *buf; u16 rx_ctl; struct asix_data *data = (struct asix_data *)&dev->data; @@ -919,13 +919,15 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0) goto out2; + /* 0x10 is the phy id of the embedded 10/100 ethernet phy */ + embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, - 1, 0, 0, buf)) < 0) { + embd_phy, 0, 0, buf)) < 0) { dbg("Select PHY #1 failed: %d", ret); goto out2; } - if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD)) < 0) + if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0) goto out2; msleep(150); @@ -933,8 +935,14 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) goto out2; msleep(150); - if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) - goto out2; + if (embd_phy) { + if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0) + goto out2; + } + else { + if ((ret = asix_sw_reset(dev, AX_SWRESET_PRTE)) < 0) + goto out2; + } msleep(150); rx_ctl = asix_read_rx_ctl(dev); diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index ea5f44de3de..a322a16d9cf 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c @@ -379,6 +379,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) { int retval; struct net_device *net = dev->net; + struct cdc_state *info = (void *) &dev->data; union { void *buf; struct rndis_msg_hdr *header; @@ -397,7 +398,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) return -ENOMEM; retval = usbnet_generic_cdc_bind(dev, intf); if (retval < 0) - goto done; + goto fail; net->hard_header_len += sizeof (struct rndis_data_hdr); @@ -412,10 +413,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) if (unlikely(retval < 0)) { /* it might not even be an RNDIS device!! */ dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); -fail: - usb_driver_release_interface(driver_of(intf), - ((struct cdc_state *)&(dev->data))->data); - goto done; + goto fail_and_release; } dev->hard_mtu = le32_to_cpu(u.init_c->max_transfer_size); /* REVISIT: peripheral "alignment" request is ignored ... */ @@ -431,7 +429,7 @@ fail: retval = rndis_command(dev, u.header); if (unlikely(retval < 0)) { dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); - goto fail; + goto fail_and_release; } tmp = le32_to_cpu(u.get_c->offset); if (unlikely((tmp + 8) > (1024 - ETH_ALEN) @@ -439,7 +437,7 @@ fail: dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n", tmp, le32_to_cpu(u.get_c->len)); retval = -EDOM; - goto fail; + goto fail_and_release; } memcpy(net->dev_addr, tmp + (char *)&u.get_c->request_id, ETH_ALEN); @@ -455,11 +453,18 @@ fail: retval = rndis_command(dev, u.header); if (unlikely(retval < 0)) { dev_err(&intf->dev, "rndis set packet filter, %d\n", retval); - goto fail; + goto fail_and_release; } retval = 0; -done: + + kfree(u.buf); + return retval; + +fail_and_release: + usb_set_intfdata(info->data, NULL); + usb_driver_release_interface(driver_of(intf), info->data); +fail: kfree(u.buf); return retval; } diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index e0eecda78ec..670262a38a0 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -284,7 +284,8 @@ static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg) u8 data[3], tmp; data[0] = phy; - *(data + 1) = cpu_to_le16p(®); + data[1] = reg & 0xff; + data[2] = (reg >> 8) & 0xff; tmp = indx | PHY_WRITE | PHY_GO; i = 0; diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index 31501c9361b..2bebd63d5ed 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c @@ -27,7 +27,7 @@ MODULE_DEVICE_TABLE(usb, id_table); static int funsoft_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg) { - struct termios t; + struct ktermios t; dbg("%s - port %d, cmd 0x%04x", __FUNCTION__, port->number, cmd); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5ca04e82ea1..0fed43a9687 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -78,6 +78,7 @@ static int option_send_setup(struct usb_serial_port *port); #define OPTION_PRODUCT_FUSION2 0x6300 #define OPTION_PRODUCT_COBRA 0x6500 #define OPTION_PRODUCT_COBRA2 0x6600 +#define OPTION_PRODUCT_GTMAX36 0x6701 #define HUAWEI_PRODUCT_E600 0x1001 #define HUAWEI_PRODUCT_E220 0x1003 #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 @@ -90,6 +91,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, @@ -104,6 +106,7 @@ static struct usb_device_id option_ids1[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index cddef3efba0..b49f2a78189 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -197,6 +197,13 @@ UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0370, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 ), +/* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */ +UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452, + "Nokia", + "Nokia 6233", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + /* Reported by Alex Corcoles <alex@corcoles.net> */ UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, "Nokia", @@ -254,6 +261,18 @@ UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), #endif +/* + * This virtual floppy is found in Sun equipment (x4600, x4200m2, etc.) + * Reported by Pete Zaitcev <zaitcev@redhat.com> + * This device chokes on both version of MODE SENSE which we have, so + * use_10_for_ms is not effective, and we use US_FL_NO_WP_DETECT. + */ +UNUSUAL_DEV( 0x046b, 0xff40, 0x0100, 0x0100, + "AMI", + "Virtual Floppy", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT), + /* Patch submitted by Philipp Friedrich <philipp@void.at> */ UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, "Kyocera", |