diff options
Diffstat (limited to 'drivers')
391 files changed, 9081 insertions, 3802 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 779e4e500df4..d060e6fd7fd5 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -300,9 +300,9 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state) | |||
300 | static struct platform_suspend_ops acpi_suspend_ops = { | 300 | static struct platform_suspend_ops acpi_suspend_ops = { |
301 | .valid = acpi_suspend_state_valid, | 301 | .valid = acpi_suspend_state_valid, |
302 | .begin = acpi_suspend_begin, | 302 | .begin = acpi_suspend_begin, |
303 | .prepare = acpi_pm_prepare, | 303 | .prepare_late = acpi_pm_prepare, |
304 | .enter = acpi_suspend_enter, | 304 | .enter = acpi_suspend_enter, |
305 | .finish = acpi_pm_finish, | 305 | .wake = acpi_pm_finish, |
306 | .end = acpi_pm_end, | 306 | .end = acpi_pm_end, |
307 | }; | 307 | }; |
308 | 308 | ||
@@ -328,9 +328,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) | |||
328 | static struct platform_suspend_ops acpi_suspend_ops_old = { | 328 | static struct platform_suspend_ops acpi_suspend_ops_old = { |
329 | .valid = acpi_suspend_state_valid, | 329 | .valid = acpi_suspend_state_valid, |
330 | .begin = acpi_suspend_begin_old, | 330 | .begin = acpi_suspend_begin_old, |
331 | .prepare = acpi_pm_disable_gpes, | 331 | .prepare_late = acpi_pm_disable_gpes, |
332 | .enter = acpi_suspend_enter, | 332 | .enter = acpi_suspend_enter, |
333 | .finish = acpi_pm_finish, | 333 | .wake = acpi_pm_finish, |
334 | .end = acpi_pm_end, | 334 | .end = acpi_pm_end, |
335 | .recover = acpi_pm_finish, | 335 | .recover = acpi_pm_finish, |
336 | }; | 336 | }; |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 57be6bea48eb..08186ecbaf8d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -114,6 +114,7 @@ enum { | |||
114 | board_ahci_sb700 = 5, /* for SB700 and SB800 */ | 114 | board_ahci_sb700 = 5, /* for SB700 and SB800 */ |
115 | board_ahci_mcp65 = 6, | 115 | board_ahci_mcp65 = 6, |
116 | board_ahci_nopmp = 7, | 116 | board_ahci_nopmp = 7, |
117 | board_ahci_yesncq = 8, | ||
117 | 118 | ||
118 | /* global controller registers */ | 119 | /* global controller registers */ |
119 | HOST_CAP = 0x00, /* host capabilities */ | 120 | HOST_CAP = 0x00, /* host capabilities */ |
@@ -469,6 +470,14 @@ static const struct ata_port_info ahci_port_info[] = { | |||
469 | .udma_mask = ATA_UDMA6, | 470 | .udma_mask = ATA_UDMA6, |
470 | .port_ops = &ahci_ops, | 471 | .port_ops = &ahci_ops, |
471 | }, | 472 | }, |
473 | /* board_ahci_yesncq */ | ||
474 | { | ||
475 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), | ||
476 | .flags = AHCI_FLAG_COMMON, | ||
477 | .pio_mask = ATA_PIO4, | ||
478 | .udma_mask = ATA_UDMA6, | ||
479 | .port_ops = &ahci_ops, | ||
480 | }, | ||
472 | }; | 481 | }; |
473 | 482 | ||
474 | static const struct pci_device_id ahci_pci_tbl[] = { | 483 | static const struct pci_device_id ahci_pci_tbl[] = { |
@@ -535,30 +544,30 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
535 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */ | 544 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */ |
536 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */ | 545 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */ |
537 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */ | 546 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */ |
538 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ | 547 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci_yesncq }, /* MCP67 */ |
539 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ | 548 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci_yesncq }, /* MCP67 */ |
540 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ | 549 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci_yesncq }, /* MCP67 */ |
541 | { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci }, /* MCP67 */ | 550 | { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci_yesncq }, /* MCP67 */ |
542 | { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */ | 551 | { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci_yesncq }, /* MCP67 */ |
543 | { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */ | 552 | { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci_yesncq }, /* MCP67 */ |
544 | { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */ | 553 | { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci_yesncq }, /* MCP67 */ |
545 | { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci }, /* MCP67 */ | 554 | { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci_yesncq }, /* MCP67 */ |
546 | { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci }, /* MCP67 */ | 555 | { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci_yesncq }, /* MCP67 */ |
547 | { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */ | 556 | { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_yesncq }, /* MCP67 */ |
548 | { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */ | 557 | { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */ |
549 | { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */ | 558 | { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */ |
550 | { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci }, /* MCP73 */ | 559 | { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */ |
551 | { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci }, /* MCP73 */ | 560 | { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */ |
552 | { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci }, /* MCP73 */ | 561 | { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */ |
553 | { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci }, /* MCP73 */ | 562 | { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci_yesncq }, /* MCP73 */ |
554 | { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci }, /* MCP73 */ | 563 | { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci_yesncq }, /* MCP73 */ |
555 | { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci }, /* MCP73 */ | 564 | { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci_yesncq }, /* MCP73 */ |
556 | { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci }, /* MCP73 */ | 565 | { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci_yesncq }, /* MCP73 */ |
557 | { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci }, /* MCP73 */ | 566 | { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci_yesncq }, /* MCP73 */ |
558 | { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci }, /* MCP73 */ | 567 | { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci_yesncq }, /* MCP73 */ |
559 | { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci }, /* MCP73 */ | 568 | { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci_yesncq }, /* MCP73 */ |
560 | { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci }, /* MCP73 */ | 569 | { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci_yesncq }, /* MCP73 */ |
561 | { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci }, /* MCP73 */ | 570 | { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci_yesncq }, /* MCP73 */ |
562 | { PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci }, /* MCP77 */ | 571 | { PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci }, /* MCP77 */ |
563 | { PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci }, /* MCP77 */ | 572 | { PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci }, /* MCP77 */ |
564 | { PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci }, /* MCP77 */ | 573 | { PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci }, /* MCP77 */ |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index e7ea77cf6069..17c5d48a75d2 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1231,6 +1231,9 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) | |||
1231 | * | 1231 | * |
1232 | * We follow the current spec and consider that 0x69/0x96 | 1232 | * We follow the current spec and consider that 0x69/0x96 |
1233 | * identifies a port multiplier and 0x3c/0xc3 a SEMB device. | 1233 | * identifies a port multiplier and 0x3c/0xc3 a SEMB device. |
1234 | * Unfortunately, WDC WD1600JS-62MHB5 (a hard drive) reports | ||
1235 | * SEMB signature. This is worked around in | ||
1236 | * ata_dev_read_id(). | ||
1234 | */ | 1237 | */ |
1235 | if ((tf->lbam == 0) && (tf->lbah == 0)) { | 1238 | if ((tf->lbam == 0) && (tf->lbah == 0)) { |
1236 | DPRINTK("found ATA device by sig\n"); | 1239 | DPRINTK("found ATA device by sig\n"); |
@@ -1248,8 +1251,8 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) | |||
1248 | } | 1251 | } |
1249 | 1252 | ||
1250 | if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) { | 1253 | if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) { |
1251 | printk(KERN_INFO "ata: SEMB device ignored\n"); | 1254 | DPRINTK("found SEMB device by sig (could be ATA device)\n"); |
1252 | return ATA_DEV_SEMB_UNSUP; /* not yet */ | 1255 | return ATA_DEV_SEMB; |
1253 | } | 1256 | } |
1254 | 1257 | ||
1255 | DPRINTK("unknown device\n"); | 1258 | DPRINTK("unknown device\n"); |
@@ -1653,8 +1656,8 @@ unsigned long ata_id_xfermask(const u16 *id) | |||
1653 | /* | 1656 | /* |
1654 | * Process compact flash extended modes | 1657 | * Process compact flash extended modes |
1655 | */ | 1658 | */ |
1656 | int pio = id[163] & 0x7; | 1659 | int pio = (id[ATA_ID_CFA_MODES] >> 0) & 0x7; |
1657 | int dma = (id[163] >> 3) & 7; | 1660 | int dma = (id[ATA_ID_CFA_MODES] >> 3) & 0x7; |
1658 | 1661 | ||
1659 | if (pio) | 1662 | if (pio) |
1660 | pio_mask |= (1 << 5); | 1663 | pio_mask |= (1 << 5); |
@@ -2080,6 +2083,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, | |||
2080 | struct ata_taskfile tf; | 2083 | struct ata_taskfile tf; |
2081 | unsigned int err_mask = 0; | 2084 | unsigned int err_mask = 0; |
2082 | const char *reason; | 2085 | const char *reason; |
2086 | bool is_semb = class == ATA_DEV_SEMB; | ||
2083 | int may_fallback = 1, tried_spinup = 0; | 2087 | int may_fallback = 1, tried_spinup = 0; |
2084 | int rc; | 2088 | int rc; |
2085 | 2089 | ||
@@ -2090,6 +2094,8 @@ retry: | |||
2090 | ata_tf_init(dev, &tf); | 2094 | ata_tf_init(dev, &tf); |
2091 | 2095 | ||
2092 | switch (class) { | 2096 | switch (class) { |
2097 | case ATA_DEV_SEMB: | ||
2098 | class = ATA_DEV_ATA; /* some hard drives report SEMB sig */ | ||
2093 | case ATA_DEV_ATA: | 2099 | case ATA_DEV_ATA: |
2094 | tf.command = ATA_CMD_ID_ATA; | 2100 | tf.command = ATA_CMD_ID_ATA; |
2095 | break; | 2101 | break; |
@@ -2126,6 +2132,14 @@ retry: | |||
2126 | return -ENOENT; | 2132 | return -ENOENT; |
2127 | } | 2133 | } |
2128 | 2134 | ||
2135 | if (is_semb) { | ||
2136 | ata_dev_printk(dev, KERN_INFO, "IDENTIFY failed on " | ||
2137 | "device w/ SEMB sig, disabled\n"); | ||
2138 | /* SEMB is not supported yet */ | ||
2139 | *p_class = ATA_DEV_SEMB_UNSUP; | ||
2140 | return 0; | ||
2141 | } | ||
2142 | |||
2129 | if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { | 2143 | if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { |
2130 | /* Device or controller might have reported | 2144 | /* Device or controller might have reported |
2131 | * the wrong device class. Give a shot at the | 2145 | * the wrong device class. Give a shot at the |
@@ -2412,7 +2426,8 @@ int ata_dev_configure(struct ata_device *dev) | |||
2412 | /* ATA-specific feature tests */ | 2426 | /* ATA-specific feature tests */ |
2413 | if (dev->class == ATA_DEV_ATA) { | 2427 | if (dev->class == ATA_DEV_ATA) { |
2414 | if (ata_id_is_cfa(id)) { | 2428 | if (ata_id_is_cfa(id)) { |
2415 | if (id[162] & 1) /* CPRM may make this media unusable */ | 2429 | /* CPRM may make this media unusable */ |
2430 | if (id[ATA_ID_CFA_KEY_MGMT] & 1) | ||
2416 | ata_dev_printk(dev, KERN_WARNING, | 2431 | ata_dev_printk(dev, KERN_WARNING, |
2417 | "supports DRM functions and may " | 2432 | "supports DRM functions and may " |
2418 | "not be fully accessable.\n"); | 2433 | "not be fully accessable.\n"); |
@@ -6110,13 +6125,11 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) | |||
6110 | ata_port_printk(ap, KERN_INFO, "DUMMY\n"); | 6125 | ata_port_printk(ap, KERN_INFO, "DUMMY\n"); |
6111 | } | 6126 | } |
6112 | 6127 | ||
6113 | /* perform each probe synchronously */ | 6128 | /* perform each probe asynchronously */ |
6114 | DPRINTK("probe begin\n"); | ||
6115 | for (i = 0; i < host->n_ports; i++) { | 6129 | for (i = 0; i < host->n_ports; i++) { |
6116 | struct ata_port *ap = host->ports[i]; | 6130 | struct ata_port *ap = host->ports[i]; |
6117 | async_schedule(async_port_probe, ap); | 6131 | async_schedule(async_port_probe, ap); |
6118 | } | 6132 | } |
6119 | DPRINTK("probe end\n"); | ||
6120 | 6133 | ||
6121 | return 0; | 6134 | return 0; |
6122 | } | 6135 | } |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b9747fa59e54..2733b0c90b75 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -647,23 +647,45 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) | |||
647 | return rc; | 647 | return rc; |
648 | } | 648 | } |
649 | 649 | ||
650 | static int ata_ioc32(struct ata_port *ap) | ||
651 | { | ||
652 | if (ap->flags & ATA_FLAG_PIO_DMA) | ||
653 | return 1; | ||
654 | if (ap->pflags & ATA_PFLAG_PIO32) | ||
655 | return 1; | ||
656 | return 0; | ||
657 | } | ||
658 | |||
650 | int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, | 659 | int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, |
651 | int cmd, void __user *arg) | 660 | int cmd, void __user *arg) |
652 | { | 661 | { |
653 | int val = -EINVAL, rc = -EINVAL; | 662 | int val = -EINVAL, rc = -EINVAL; |
663 | unsigned long flags; | ||
654 | 664 | ||
655 | switch (cmd) { | 665 | switch (cmd) { |
656 | case ATA_IOC_GET_IO32: | 666 | case ATA_IOC_GET_IO32: |
657 | val = 0; | 667 | spin_lock_irqsave(ap->lock, flags); |
668 | val = ata_ioc32(ap); | ||
669 | spin_unlock_irqrestore(ap->lock, flags); | ||
658 | if (copy_to_user(arg, &val, 1)) | 670 | if (copy_to_user(arg, &val, 1)) |
659 | return -EFAULT; | 671 | return -EFAULT; |
660 | return 0; | 672 | return 0; |
661 | 673 | ||
662 | case ATA_IOC_SET_IO32: | 674 | case ATA_IOC_SET_IO32: |
663 | val = (unsigned long) arg; | 675 | val = (unsigned long) arg; |
664 | if (val != 0) | 676 | rc = 0; |
665 | return -EINVAL; | 677 | spin_lock_irqsave(ap->lock, flags); |
666 | return 0; | 678 | if (ap->pflags & ATA_PFLAG_PIO32CHANGE) { |
679 | if (val) | ||
680 | ap->pflags |= ATA_PFLAG_PIO32; | ||
681 | else | ||
682 | ap->pflags &= ~ATA_PFLAG_PIO32; | ||
683 | } else { | ||
684 | if (val != ata_ioc32(ap)) | ||
685 | rc = -EINVAL; | ||
686 | } | ||
687 | spin_unlock_irqrestore(ap->lock, flags); | ||
688 | return rc; | ||
667 | 689 | ||
668 | case HDIO_GET_IDENTITY: | 690 | case HDIO_GET_IDENTITY: |
669 | return ata_get_identity(ap, scsidev, arg); | 691 | return ata_get_identity(ap, scsidev, arg); |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 8332e97a9de3..bb18415d3d63 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -87,6 +87,7 @@ const struct ata_port_operations ata_bmdma32_port_ops = { | |||
87 | .inherits = &ata_bmdma_port_ops, | 87 | .inherits = &ata_bmdma_port_ops, |
88 | 88 | ||
89 | .sff_data_xfer = ata_sff_data_xfer32, | 89 | .sff_data_xfer = ata_sff_data_xfer32, |
90 | .port_start = ata_sff_port_start32, | ||
90 | }; | 91 | }; |
91 | EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops); | 92 | EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops); |
92 | 93 | ||
@@ -769,6 +770,9 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf, | |||
769 | void __iomem *data_addr = ap->ioaddr.data_addr; | 770 | void __iomem *data_addr = ap->ioaddr.data_addr; |
770 | unsigned int words = buflen >> 2; | 771 | unsigned int words = buflen >> 2; |
771 | int slop = buflen & 3; | 772 | int slop = buflen & 3; |
773 | |||
774 | if (!(ap->pflags & ATA_PFLAG_PIO32)) | ||
775 | return ata_sff_data_xfer(dev, buf, buflen, rw); | ||
772 | 776 | ||
773 | /* Transfer multiple of 4 bytes */ | 777 | /* Transfer multiple of 4 bytes */ |
774 | if (rw == READ) | 778 | if (rw == READ) |
@@ -2402,6 +2406,29 @@ int ata_sff_port_start(struct ata_port *ap) | |||
2402 | EXPORT_SYMBOL_GPL(ata_sff_port_start); | 2406 | EXPORT_SYMBOL_GPL(ata_sff_port_start); |
2403 | 2407 | ||
2404 | /** | 2408 | /** |
2409 | * ata_sff_port_start32 - Set port up for dma. | ||
2410 | * @ap: Port to initialize | ||
2411 | * | ||
2412 | * Called just after data structures for each port are | ||
2413 | * initialized. Allocates space for PRD table if the device | ||
2414 | * is DMA capable SFF. | ||
2415 | * | ||
2416 | * May be used as the port_start() entry in ata_port_operations for | ||
2417 | * devices that are capable of 32bit PIO. | ||
2418 | * | ||
2419 | * LOCKING: | ||
2420 | * Inherited from caller. | ||
2421 | */ | ||
2422 | int ata_sff_port_start32(struct ata_port *ap) | ||
2423 | { | ||
2424 | ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; | ||
2425 | if (ap->ioaddr.bmdma_addr) | ||
2426 | return ata_port_start(ap); | ||
2427 | return 0; | ||
2428 | } | ||
2429 | EXPORT_SYMBOL_GPL(ata_sff_port_start32); | ||
2430 | |||
2431 | /** | ||
2405 | * ata_sff_std_ports - initialize ioaddr with standard port offsets. | 2432 | * ata_sff_std_ports - initialize ioaddr with standard port offsets. |
2406 | * @ioaddr: IO address structure to be initialized | 2433 | * @ioaddr: IO address structure to be initialized |
2407 | * | 2434 | * |
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 81ab57003aba..122c786449a9 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 8 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 9 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
10 | * Portions Copyright (C) 2003 Red Hat Inc | 10 | * Portions Copyright (C) 2003 Red Hat Inc |
11 | * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. | 11 | * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. |
12 | * | 12 | * |
13 | * TODO | 13 | * TODO |
14 | * Look into engine reset on timeout errors. Should not be required. | 14 | * Look into engine reset on timeout errors. Should not be required. |
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/libata.h> | 24 | #include <linux/libata.h> |
25 | 25 | ||
26 | #define DRV_NAME "pata_hpt37x" | 26 | #define DRV_NAME "pata_hpt37x" |
27 | #define DRV_VERSION "0.6.11" | 27 | #define DRV_VERSION "0.6.12" |
28 | 28 | ||
29 | struct hpt_clock { | 29 | struct hpt_clock { |
30 | u8 xfer_speed; | 30 | u8 xfer_speed; |
@@ -445,23 +445,6 @@ static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
445 | } | 445 | } |
446 | 446 | ||
447 | /** | 447 | /** |
448 | * hpt370_bmdma_start - DMA engine begin | ||
449 | * @qc: ATA command | ||
450 | * | ||
451 | * The 370 and 370A want us to reset the DMA engine each time we | ||
452 | * use it. The 372 and later are fine. | ||
453 | */ | ||
454 | |||
455 | static void hpt370_bmdma_start(struct ata_queued_cmd *qc) | ||
456 | { | ||
457 | struct ata_port *ap = qc->ap; | ||
458 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
459 | pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); | ||
460 | udelay(10); | ||
461 | ata_bmdma_start(qc); | ||
462 | } | ||
463 | |||
464 | /** | ||
465 | * hpt370_bmdma_end - DMA engine stop | 448 | * hpt370_bmdma_end - DMA engine stop |
466 | * @qc: ATA command | 449 | * @qc: ATA command |
467 | * | 450 | * |
@@ -598,7 +581,6 @@ static struct scsi_host_template hpt37x_sht = { | |||
598 | static struct ata_port_operations hpt370_port_ops = { | 581 | static struct ata_port_operations hpt370_port_ops = { |
599 | .inherits = &ata_bmdma_port_ops, | 582 | .inherits = &ata_bmdma_port_ops, |
600 | 583 | ||
601 | .bmdma_start = hpt370_bmdma_start, | ||
602 | .bmdma_stop = hpt370_bmdma_stop, | 584 | .bmdma_stop = hpt370_bmdma_stop, |
603 | 585 | ||
604 | .mode_filter = hpt370_filter, | 586 | .mode_filter = hpt370_filter, |
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 3f830f0fe2cc..f72c6c5b820f 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -108,6 +108,7 @@ struct legacy_controller { | |||
108 | struct ata_port_operations *ops; | 108 | struct ata_port_operations *ops; |
109 | unsigned int pio_mask; | 109 | unsigned int pio_mask; |
110 | unsigned int flags; | 110 | unsigned int flags; |
111 | unsigned int pflags; | ||
111 | int (*setup)(struct platform_device *, struct legacy_probe *probe, | 112 | int (*setup)(struct platform_device *, struct legacy_probe *probe, |
112 | struct legacy_data *data); | 113 | struct legacy_data *data); |
113 | }; | 114 | }; |
@@ -284,9 +285,11 @@ static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, | |||
284 | unsigned char *buf, unsigned int buflen, int rw) | 285 | unsigned char *buf, unsigned int buflen, int rw) |
285 | { | 286 | { |
286 | int slop = buflen & 3; | 287 | int slop = buflen & 3; |
288 | struct ata_port *ap = dev->link->ap; | ||
289 | |||
287 | /* 32bit I/O capable *and* we need to write a whole number of dwords */ | 290 | /* 32bit I/O capable *and* we need to write a whole number of dwords */ |
288 | if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) { | 291 | if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3) |
289 | struct ata_port *ap = dev->link->ap; | 292 | && (ap->pflags & ATA_PFLAG_PIO32)) { |
290 | unsigned long flags; | 293 | unsigned long flags; |
291 | 294 | ||
292 | local_irq_save(flags); | 295 | local_irq_save(flags); |
@@ -736,7 +739,8 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
736 | struct ata_port *ap = adev->link->ap; | 739 | struct ata_port *ap = adev->link->ap; |
737 | int slop = buflen & 3; | 740 | int slop = buflen & 3; |
738 | 741 | ||
739 | if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) { | 742 | if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3) |
743 | && (ap->pflags & ATA_PFLAG_PIO32)) { | ||
740 | if (rw == WRITE) | 744 | if (rw == WRITE) |
741 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | 745 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); |
742 | else | 746 | else |
@@ -858,27 +862,30 @@ static struct ata_port_operations winbond_port_ops = { | |||
858 | 862 | ||
859 | static struct legacy_controller controllers[] = { | 863 | static struct legacy_controller controllers[] = { |
860 | {"BIOS", &legacy_port_ops, 0x1F, | 864 | {"BIOS", &legacy_port_ops, 0x1F, |
861 | ATA_FLAG_NO_IORDY, NULL }, | 865 | ATA_FLAG_NO_IORDY, 0, NULL }, |
862 | {"Snooping", &simple_port_ops, 0x1F, | 866 | {"Snooping", &simple_port_ops, 0x1F, |
863 | 0 , NULL }, | 867 | 0, 0, NULL }, |
864 | {"PDC20230", &pdc20230_port_ops, 0x7, | 868 | {"PDC20230", &pdc20230_port_ops, 0x7, |
865 | ATA_FLAG_NO_IORDY, NULL }, | 869 | ATA_FLAG_NO_IORDY, |
870 | ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, NULL }, | ||
866 | {"HT6560A", &ht6560a_port_ops, 0x07, | 871 | {"HT6560A", &ht6560a_port_ops, 0x07, |
867 | ATA_FLAG_NO_IORDY, NULL }, | 872 | ATA_FLAG_NO_IORDY, 0, NULL }, |
868 | {"HT6560B", &ht6560b_port_ops, 0x1F, | 873 | {"HT6560B", &ht6560b_port_ops, 0x1F, |
869 | ATA_FLAG_NO_IORDY, NULL }, | 874 | ATA_FLAG_NO_IORDY, 0, NULL }, |
870 | {"OPTI82C611A", &opti82c611a_port_ops, 0x0F, | 875 | {"OPTI82C611A", &opti82c611a_port_ops, 0x0F, |
871 | 0 , NULL }, | 876 | 0, 0, NULL }, |
872 | {"OPTI82C46X", &opti82c46x_port_ops, 0x0F, | 877 | {"OPTI82C46X", &opti82c46x_port_ops, 0x0F, |
873 | 0 , NULL }, | 878 | 0, 0, NULL }, |
874 | {"QDI6500", &qdi6500_port_ops, 0x07, | 879 | {"QDI6500", &qdi6500_port_ops, 0x07, |
875 | ATA_FLAG_NO_IORDY, qdi_port }, | 880 | ATA_FLAG_NO_IORDY, |
881 | ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, | ||
876 | {"QDI6580", &qdi6580_port_ops, 0x1F, | 882 | {"QDI6580", &qdi6580_port_ops, 0x1F, |
877 | 0 , qdi_port }, | 883 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, |
878 | {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, | 884 | {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, |
879 | 0 , qdi_port }, | 885 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, |
880 | {"W83759A", &winbond_port_ops, 0x1F, | 886 | {"W83759A", &winbond_port_ops, 0x1F, |
881 | 0 , winbond_port } | 887 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, |
888 | winbond_port } | ||
882 | }; | 889 | }; |
883 | 890 | ||
884 | /** | 891 | /** |
@@ -1008,6 +1015,7 @@ static __init int legacy_init_one(struct legacy_probe *probe) | |||
1008 | ap->ops = ops; | 1015 | ap->ops = ops; |
1009 | ap->pio_mask = pio_modes; | 1016 | ap->pio_mask = pio_modes; |
1010 | ap->flags |= ATA_FLAG_SLAVE_POSS | iordy; | 1017 | ap->flags |= ATA_FLAG_SLAVE_POSS | iordy; |
1018 | ap->pflags |= controller->pflags; | ||
1011 | ap->ioaddr.cmd_addr = io_addr; | 1019 | ap->ioaddr.cmd_addr = io_addr; |
1012 | ap->ioaddr.altstatus_addr = ctrl_addr; | 1020 | ap->ioaddr.altstatus_addr = ctrl_addr; |
1013 | ap->ioaddr.ctl_addr = ctrl_addr; | 1021 | ap->ioaddr.ctl_addr = ctrl_addr; |
@@ -1032,6 +1040,7 @@ static __init int legacy_init_one(struct legacy_probe *probe) | |||
1032 | return 0; | 1040 | return 0; |
1033 | } | 1041 | } |
1034 | } | 1042 | } |
1043 | ata_host_detach(host); | ||
1035 | fail: | 1044 | fail: |
1036 | platform_device_unregister(pdev); | 1045 | platform_device_unregister(pdev); |
1037 | return ret; | 1046 | return ret; |
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index 0fb6b1b1e634..dd53a66b19e3 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #include <linux/libata.h> | 44 | #include <linux/libata.h> |
45 | 45 | ||
46 | #define DRV_NAME "pata_ninja32" | 46 | #define DRV_NAME "pata_ninja32" |
47 | #define DRV_VERSION "0.1.3" | 47 | #define DRV_VERSION "0.1.5" |
48 | 48 | ||
49 | 49 | ||
50 | /** | 50 | /** |
@@ -86,6 +86,7 @@ static struct ata_port_operations ninja32_port_ops = { | |||
86 | .sff_dev_select = ninja32_dev_select, | 86 | .sff_dev_select = ninja32_dev_select, |
87 | .cable_detect = ata_cable_40wire, | 87 | .cable_detect = ata_cable_40wire, |
88 | .set_piomode = ninja32_set_piomode, | 88 | .set_piomode = ninja32_set_piomode, |
89 | .sff_data_xfer = ata_sff_data_xfer32 | ||
89 | }; | 90 | }; |
90 | 91 | ||
91 | static void ninja32_program(void __iomem *base) | 92 | static void ninja32_program(void __iomem *base) |
@@ -144,6 +145,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
144 | ap->ioaddr.altstatus_addr = base + 0x1E; | 145 | ap->ioaddr.altstatus_addr = base + 0x1E; |
145 | ap->ioaddr.bmdma_addr = base; | 146 | ap->ioaddr.bmdma_addr = base; |
146 | ata_sff_std_ports(&ap->ioaddr); | 147 | ata_sff_std_ports(&ap->ioaddr); |
148 | ap->pflags = ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE; | ||
147 | 149 | ||
148 | ninja32_program(base); | 150 | ninja32_program(base); |
149 | /* FIXME: Should we disable them at remove ? */ | 151 | /* FIXME: Should we disable them at remove ? */ |
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index b08e6e0f82b6..45657cacec43 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #include <linux/dmi.h> | 62 | #include <linux/dmi.h> |
63 | 63 | ||
64 | #define DRV_NAME "pata_via" | 64 | #define DRV_NAME "pata_via" |
65 | #define DRV_VERSION "0.3.3" | 65 | #define DRV_VERSION "0.3.4" |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx | 68 | * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx |
@@ -136,6 +136,9 @@ static const struct via_isa_bridge { | |||
136 | { NULL } | 136 | { NULL } |
137 | }; | 137 | }; |
138 | 138 | ||
139 | struct via_port { | ||
140 | u8 cached_device; | ||
141 | }; | ||
139 | 142 | ||
140 | /* | 143 | /* |
141 | * Cable special cases | 144 | * Cable special cases |
@@ -346,14 +349,70 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
346 | */ | 349 | */ |
347 | static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | 350 | static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) |
348 | { | 351 | { |
349 | struct ata_taskfile tmp_tf; | 352 | struct ata_ioports *ioaddr = &ap->ioaddr; |
353 | struct via_port *vp = ap->private_data; | ||
354 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
355 | int newctl = 0; | ||
356 | |||
357 | if (tf->ctl != ap->last_ctl) { | ||
358 | iowrite8(tf->ctl, ioaddr->ctl_addr); | ||
359 | ap->last_ctl = tf->ctl; | ||
360 | ata_wait_idle(ap); | ||
361 | newctl = 1; | ||
362 | } | ||
363 | |||
364 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
365 | iowrite8(tf->device, ioaddr->device_addr); | ||
366 | vp->cached_device = tf->device; | ||
367 | } else if (newctl) | ||
368 | iowrite8(vp->cached_device, ioaddr->device_addr); | ||
369 | |||
370 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
371 | WARN_ON_ONCE(!ioaddr->ctl_addr); | ||
372 | iowrite8(tf->hob_feature, ioaddr->feature_addr); | ||
373 | iowrite8(tf->hob_nsect, ioaddr->nsect_addr); | ||
374 | iowrite8(tf->hob_lbal, ioaddr->lbal_addr); | ||
375 | iowrite8(tf->hob_lbam, ioaddr->lbam_addr); | ||
376 | iowrite8(tf->hob_lbah, ioaddr->lbah_addr); | ||
377 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
378 | tf->hob_feature, | ||
379 | tf->hob_nsect, | ||
380 | tf->hob_lbal, | ||
381 | tf->hob_lbam, | ||
382 | tf->hob_lbah); | ||
383 | } | ||
350 | 384 | ||
351 | if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) { | 385 | if (is_addr) { |
352 | tmp_tf = *tf; | 386 | iowrite8(tf->feature, ioaddr->feature_addr); |
353 | tmp_tf.flags |= ATA_TFLAG_DEVICE; | 387 | iowrite8(tf->nsect, ioaddr->nsect_addr); |
354 | tf = &tmp_tf; | 388 | iowrite8(tf->lbal, ioaddr->lbal_addr); |
389 | iowrite8(tf->lbam, ioaddr->lbam_addr); | ||
390 | iowrite8(tf->lbah, ioaddr->lbah_addr); | ||
391 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
392 | tf->feature, | ||
393 | tf->nsect, | ||
394 | tf->lbal, | ||
395 | tf->lbam, | ||
396 | tf->lbah); | ||
355 | } | 397 | } |
356 | ata_sff_tf_load(ap, tf); | 398 | |
399 | ata_wait_idle(ap); | ||
400 | } | ||
401 | |||
402 | static int via_port_start(struct ata_port *ap) | ||
403 | { | ||
404 | struct via_port *vp; | ||
405 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
406 | |||
407 | int ret = ata_sff_port_start(ap); | ||
408 | if (ret < 0) | ||
409 | return ret; | ||
410 | |||
411 | vp = devm_kzalloc(&pdev->dev, sizeof(struct via_port), GFP_KERNEL); | ||
412 | if (vp == NULL) | ||
413 | return -ENOMEM; | ||
414 | ap->private_data = vp; | ||
415 | return 0; | ||
357 | } | 416 | } |
358 | 417 | ||
359 | static struct scsi_host_template via_sht = { | 418 | static struct scsi_host_template via_sht = { |
@@ -367,6 +426,7 @@ static struct ata_port_operations via_port_ops = { | |||
367 | .set_dmamode = via_set_dmamode, | 426 | .set_dmamode = via_set_dmamode, |
368 | .prereset = via_pre_reset, | 427 | .prereset = via_pre_reset, |
369 | .sff_tf_load = via_tf_load, | 428 | .sff_tf_load = via_tf_load, |
429 | .port_start = via_port_start, | ||
370 | }; | 430 | }; |
371 | 431 | ||
372 | static struct ata_port_operations via_port_ops_noirq = { | 432 | static struct ata_port_operations via_port_ops_noirq = { |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 37ae5dc1070c..870dcfd82357 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1881,6 +1881,39 @@ static u8 mv_bmdma_status(struct ata_port *ap) | |||
1881 | return status; | 1881 | return status; |
1882 | } | 1882 | } |
1883 | 1883 | ||
1884 | static void mv_rw_multi_errata_sata24(struct ata_queued_cmd *qc) | ||
1885 | { | ||
1886 | struct ata_taskfile *tf = &qc->tf; | ||
1887 | /* | ||
1888 | * Workaround for 88SX60x1 FEr SATA#24. | ||
1889 | * | ||
1890 | * Chip may corrupt WRITEs if multi_count >= 4kB. | ||
1891 | * Note that READs are unaffected. | ||
1892 | * | ||
1893 | * It's not clear if this errata really means "4K bytes", | ||
1894 | * or if it always happens for multi_count > 7 | ||
1895 | * regardless of device sector_size. | ||
1896 | * | ||
1897 | * So, for safety, any write with multi_count > 7 | ||
1898 | * gets converted here into a regular PIO write instead: | ||
1899 | */ | ||
1900 | if ((tf->flags & ATA_TFLAG_WRITE) && is_multi_taskfile(tf)) { | ||
1901 | if (qc->dev->multi_count > 7) { | ||
1902 | switch (tf->command) { | ||
1903 | case ATA_CMD_WRITE_MULTI: | ||
1904 | tf->command = ATA_CMD_PIO_WRITE; | ||
1905 | break; | ||
1906 | case ATA_CMD_WRITE_MULTI_FUA_EXT: | ||
1907 | tf->flags &= ~ATA_TFLAG_FUA; /* ugh */ | ||
1908 | /* fall through */ | ||
1909 | case ATA_CMD_WRITE_MULTI_EXT: | ||
1910 | tf->command = ATA_CMD_PIO_WRITE_EXT; | ||
1911 | break; | ||
1912 | } | ||
1913 | } | ||
1914 | } | ||
1915 | } | ||
1916 | |||
1884 | /** | 1917 | /** |
1885 | * mv_qc_prep - Host specific command preparation. | 1918 | * mv_qc_prep - Host specific command preparation. |
1886 | * @qc: queued command to prepare | 1919 | * @qc: queued command to prepare |
@@ -1898,17 +1931,24 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1898 | struct ata_port *ap = qc->ap; | 1931 | struct ata_port *ap = qc->ap; |
1899 | struct mv_port_priv *pp = ap->private_data; | 1932 | struct mv_port_priv *pp = ap->private_data; |
1900 | __le16 *cw; | 1933 | __le16 *cw; |
1901 | struct ata_taskfile *tf; | 1934 | struct ata_taskfile *tf = &qc->tf; |
1902 | u16 flags = 0; | 1935 | u16 flags = 0; |
1903 | unsigned in_index; | 1936 | unsigned in_index; |
1904 | 1937 | ||
1905 | if ((qc->tf.protocol != ATA_PROT_DMA) && | 1938 | switch (tf->protocol) { |
1906 | (qc->tf.protocol != ATA_PROT_NCQ)) | 1939 | case ATA_PROT_DMA: |
1940 | case ATA_PROT_NCQ: | ||
1941 | break; /* continue below */ | ||
1942 | case ATA_PROT_PIO: | ||
1943 | mv_rw_multi_errata_sata24(qc); | ||
1944 | return; | ||
1945 | default: | ||
1907 | return; | 1946 | return; |
1947 | } | ||
1908 | 1948 | ||
1909 | /* Fill in command request block | 1949 | /* Fill in command request block |
1910 | */ | 1950 | */ |
1911 | if (!(qc->tf.flags & ATA_TFLAG_WRITE)) | 1951 | if (!(tf->flags & ATA_TFLAG_WRITE)) |
1912 | flags |= CRQB_FLAG_READ; | 1952 | flags |= CRQB_FLAG_READ; |
1913 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); | 1953 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); |
1914 | flags |= qc->tag << CRQB_TAG_SHIFT; | 1954 | flags |= qc->tag << CRQB_TAG_SHIFT; |
@@ -1924,7 +1964,6 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1924 | pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags); | 1964 | pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags); |
1925 | 1965 | ||
1926 | cw = &pp->crqb[in_index].ata_cmd[0]; | 1966 | cw = &pp->crqb[in_index].ata_cmd[0]; |
1927 | tf = &qc->tf; | ||
1928 | 1967 | ||
1929 | /* Sadly, the CRQB cannot accomodate all registers--there are | 1968 | /* Sadly, the CRQB cannot accomodate all registers--there are |
1930 | * only 11 bytes...so we must pick and choose required | 1969 | * only 11 bytes...so we must pick and choose required |
@@ -1990,16 +2029,16 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
1990 | struct ata_port *ap = qc->ap; | 2029 | struct ata_port *ap = qc->ap; |
1991 | struct mv_port_priv *pp = ap->private_data; | 2030 | struct mv_port_priv *pp = ap->private_data; |
1992 | struct mv_crqb_iie *crqb; | 2031 | struct mv_crqb_iie *crqb; |
1993 | struct ata_taskfile *tf; | 2032 | struct ata_taskfile *tf = &qc->tf; |
1994 | unsigned in_index; | 2033 | unsigned in_index; |
1995 | u32 flags = 0; | 2034 | u32 flags = 0; |
1996 | 2035 | ||
1997 | if ((qc->tf.protocol != ATA_PROT_DMA) && | 2036 | if ((tf->protocol != ATA_PROT_DMA) && |
1998 | (qc->tf.protocol != ATA_PROT_NCQ)) | 2037 | (tf->protocol != ATA_PROT_NCQ)) |
1999 | return; | 2038 | return; |
2000 | 2039 | ||
2001 | /* Fill in Gen IIE command request block */ | 2040 | /* Fill in Gen IIE command request block */ |
2002 | if (!(qc->tf.flags & ATA_TFLAG_WRITE)) | 2041 | if (!(tf->flags & ATA_TFLAG_WRITE)) |
2003 | flags |= CRQB_FLAG_READ; | 2042 | flags |= CRQB_FLAG_READ; |
2004 | 2043 | ||
2005 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); | 2044 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); |
@@ -2015,7 +2054,6 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
2015 | crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma[qc->tag] >> 16) >> 16); | 2054 | crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma[qc->tag] >> 16) >> 16); |
2016 | crqb->flags = cpu_to_le32(flags); | 2055 | crqb->flags = cpu_to_le32(flags); |
2017 | 2056 | ||
2018 | tf = &qc->tf; | ||
2019 | crqb->ata_cmd[0] = cpu_to_le32( | 2057 | crqb->ata_cmd[0] = cpu_to_le32( |
2020 | (tf->command << 16) | | 2058 | (tf->command << 16) | |
2021 | (tf->feature << 24) | 2059 | (tf->feature << 24) |
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 98e8c50703b3..bdd43c7f432e 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c | |||
@@ -566,7 +566,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
566 | static int printed_version; | 566 | static int printed_version; |
567 | unsigned int i; | 567 | unsigned int i; |
568 | int rc; | 568 | int rc; |
569 | struct ata_host *host; | 569 | struct ata_host *host = NULL; |
570 | int board_id = (int) ent->driver_data; | 570 | int board_id = (int) ent->driver_data; |
571 | const unsigned *bar_sizes; | 571 | const unsigned *bar_sizes; |
572 | 572 | ||
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index be204308cc1b..9359613addc5 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -1059,7 +1059,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1059 | goto out; | 1059 | goto out; |
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | err = pci_set_dma_mask(dev, DMA_32BIT_MASK); | 1062 | err = pci_set_dma_mask(dev, DMA_BIT_MASK(32)); |
1063 | if (err) { | 1063 | if (err) { |
1064 | dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n"); | 1064 | dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n"); |
1065 | goto out; | 1065 | goto out; |
diff --git a/drivers/base/base.h b/drivers/base/base.h index ddc97496db4a..b528145a078f 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -115,7 +115,7 @@ extern int driver_probe_device(struct device_driver *drv, struct device *dev); | |||
115 | static inline int driver_match_device(struct device_driver *drv, | 115 | static inline int driver_match_device(struct device_driver *drv, |
116 | struct device *dev) | 116 | struct device *dev) |
117 | { | 117 | { |
118 | return drv->bus->match && drv->bus->match(dev, drv); | 118 | return drv->bus->match ? drv->bus->match(dev, drv) : 1; |
119 | } | 119 | } |
120 | 120 | ||
121 | extern void sysdev_shutdown(void); | 121 | extern void sysdev_shutdown(void); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index e73c92d13a23..4aa527b8a913 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -891,7 +891,8 @@ int device_add(struct device *dev) | |||
891 | set_dev_node(dev, dev_to_node(parent)); | 891 | set_dev_node(dev, dev_to_node(parent)); |
892 | 892 | ||
893 | /* first, register with generic layer. */ | 893 | /* first, register with generic layer. */ |
894 | error = kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev_name(dev)); | 894 | /* we require the name to be set before, and pass NULL */ |
895 | error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); | ||
895 | if (error) | 896 | if (error) |
896 | goto Error; | 897 | goto Error; |
897 | 898 | ||
@@ -1142,6 +1143,9 @@ int device_for_each_child(struct device *parent, void *data, | |||
1142 | struct device *child; | 1143 | struct device *child; |
1143 | int error = 0; | 1144 | int error = 0; |
1144 | 1145 | ||
1146 | if (!parent->p) | ||
1147 | return 0; | ||
1148 | |||
1145 | klist_iter_init(&parent->p->klist_children, &i); | 1149 | klist_iter_init(&parent->p->klist_children, &i); |
1146 | while ((child = next_device(&i)) && !error) | 1150 | while ((child = next_device(&i)) && !error) |
1147 | error = fn(child, data); | 1151 | error = fn(child, data); |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index f17c3266a0e0..742cbe6b042b 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -179,6 +179,7 @@ void wait_for_device_probe(void) | |||
179 | wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); | 179 | wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); |
180 | async_synchronize_full(); | 180 | async_synchronize_full(); |
181 | } | 181 | } |
182 | EXPORT_SYMBOL_GPL(wait_for_device_probe); | ||
182 | 183 | ||
183 | /** | 184 | /** |
184 | * driver_probe_device - attempt to bind device & driver together | 185 | * driver_probe_device - attempt to bind device & driver together |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index d2198f64ad4e..b5b6c973a2e0 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -990,6 +990,8 @@ int __init platform_bus_init(void) | |||
990 | { | 990 | { |
991 | int error; | 991 | int error; |
992 | 992 | ||
993 | early_platform_cleanup(); | ||
994 | |||
993 | error = device_register(&platform_bus); | 995 | error = device_register(&platform_bus); |
994 | if (error) | 996 | if (error) |
995 | return error; | 997 | return error; |
@@ -1020,3 +1022,240 @@ u64 dma_get_required_mask(struct device *dev) | |||
1020 | } | 1022 | } |
1021 | EXPORT_SYMBOL_GPL(dma_get_required_mask); | 1023 | EXPORT_SYMBOL_GPL(dma_get_required_mask); |
1022 | #endif | 1024 | #endif |
1025 | |||
1026 | static __initdata LIST_HEAD(early_platform_driver_list); | ||
1027 | static __initdata LIST_HEAD(early_platform_device_list); | ||
1028 | |||
1029 | /** | ||
1030 | * early_platform_driver_register | ||
1031 | * @edrv: early_platform driver structure | ||
1032 | * @buf: string passed from early_param() | ||
1033 | */ | ||
1034 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, | ||
1035 | char *buf) | ||
1036 | { | ||
1037 | unsigned long index; | ||
1038 | int n; | ||
1039 | |||
1040 | /* Simply add the driver to the end of the global list. | ||
1041 | * Drivers will by default be put on the list in compiled-in order. | ||
1042 | */ | ||
1043 | if (!epdrv->list.next) { | ||
1044 | INIT_LIST_HEAD(&epdrv->list); | ||
1045 | list_add_tail(&epdrv->list, &early_platform_driver_list); | ||
1046 | } | ||
1047 | |||
1048 | /* If the user has specified device then make sure the driver | ||
1049 | * gets prioritized. The driver of the last device specified on | ||
1050 | * command line will be put first on the list. | ||
1051 | */ | ||
1052 | n = strlen(epdrv->pdrv->driver.name); | ||
1053 | if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { | ||
1054 | list_move(&epdrv->list, &early_platform_driver_list); | ||
1055 | |||
1056 | if (!strcmp(buf, epdrv->pdrv->driver.name)) | ||
1057 | epdrv->requested_id = -1; | ||
1058 | else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10, | ||
1059 | &index) == 0) | ||
1060 | epdrv->requested_id = index; | ||
1061 | else | ||
1062 | epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; | ||
1063 | } | ||
1064 | |||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1068 | /** | ||
1069 | * early_platform_add_devices - add a numbers of early platform devices | ||
1070 | * @devs: array of early platform devices to add | ||
1071 | * @num: number of early platform devices in array | ||
1072 | */ | ||
1073 | void __init early_platform_add_devices(struct platform_device **devs, int num) | ||
1074 | { | ||
1075 | struct device *dev; | ||
1076 | int i; | ||
1077 | |||
1078 | /* simply add the devices to list */ | ||
1079 | for (i = 0; i < num; i++) { | ||
1080 | dev = &devs[i]->dev; | ||
1081 | |||
1082 | if (!dev->devres_head.next) { | ||
1083 | INIT_LIST_HEAD(&dev->devres_head); | ||
1084 | list_add_tail(&dev->devres_head, | ||
1085 | &early_platform_device_list); | ||
1086 | } | ||
1087 | } | ||
1088 | } | ||
1089 | |||
1090 | /** | ||
1091 | * early_platform_driver_register_all | ||
1092 | * @class_str: string to identify early platform driver class | ||
1093 | */ | ||
1094 | void __init early_platform_driver_register_all(char *class_str) | ||
1095 | { | ||
1096 | /* The "class_str" parameter may or may not be present on the kernel | ||
1097 | * command line. If it is present then there may be more than one | ||
1098 | * matching parameter. | ||
1099 | * | ||
1100 | * Since we register our early platform drivers using early_param() | ||
1101 | * we need to make sure that they also get registered in the case | ||
1102 | * when the parameter is missing from the kernel command line. | ||
1103 | * | ||
1104 | * We use parse_early_options() to make sure the early_param() gets | ||
1105 | * called at least once. The early_param() may be called more than | ||
1106 | * once since the name of the preferred device may be specified on | ||
1107 | * the kernel command line. early_platform_driver_register() handles | ||
1108 | * this case for us. | ||
1109 | */ | ||
1110 | parse_early_options(class_str); | ||
1111 | } | ||
1112 | |||
1113 | /** | ||
1114 | * early_platform_match | ||
1115 | * @edrv: early platform driver structure | ||
1116 | * @id: id to match against | ||
1117 | */ | ||
1118 | static __init struct platform_device * | ||
1119 | early_platform_match(struct early_platform_driver *epdrv, int id) | ||
1120 | { | ||
1121 | struct platform_device *pd; | ||
1122 | |||
1123 | list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) | ||
1124 | if (platform_match(&pd->dev, &epdrv->pdrv->driver)) | ||
1125 | if (pd->id == id) | ||
1126 | return pd; | ||
1127 | |||
1128 | return NULL; | ||
1129 | } | ||
1130 | |||
1131 | /** | ||
1132 | * early_platform_left | ||
1133 | * @edrv: early platform driver structure | ||
1134 | * @id: return true if id or above exists | ||
1135 | */ | ||
1136 | static __init int early_platform_left(struct early_platform_driver *epdrv, | ||
1137 | int id) | ||
1138 | { | ||
1139 | struct platform_device *pd; | ||
1140 | |||
1141 | list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) | ||
1142 | if (platform_match(&pd->dev, &epdrv->pdrv->driver)) | ||
1143 | if (pd->id >= id) | ||
1144 | return 1; | ||
1145 | |||
1146 | return 0; | ||
1147 | } | ||
1148 | |||
1149 | /** | ||
1150 | * early_platform_driver_probe_id | ||
1151 | * @class_str: string to identify early platform driver class | ||
1152 | * @id: id to match against | ||
1153 | * @nr_probe: number of platform devices to successfully probe before exiting | ||
1154 | */ | ||
1155 | static int __init early_platform_driver_probe_id(char *class_str, | ||
1156 | int id, | ||
1157 | int nr_probe) | ||
1158 | { | ||
1159 | struct early_platform_driver *epdrv; | ||
1160 | struct platform_device *match; | ||
1161 | int match_id; | ||
1162 | int n = 0; | ||
1163 | int left = 0; | ||
1164 | |||
1165 | list_for_each_entry(epdrv, &early_platform_driver_list, list) { | ||
1166 | /* only use drivers matching our class_str */ | ||
1167 | if (strcmp(class_str, epdrv->class_str)) | ||
1168 | continue; | ||
1169 | |||
1170 | if (id == -2) { | ||
1171 | match_id = epdrv->requested_id; | ||
1172 | left = 1; | ||
1173 | |||
1174 | } else { | ||
1175 | match_id = id; | ||
1176 | left += early_platform_left(epdrv, id); | ||
1177 | |||
1178 | /* skip requested id */ | ||
1179 | switch (epdrv->requested_id) { | ||
1180 | case EARLY_PLATFORM_ID_ERROR: | ||
1181 | case EARLY_PLATFORM_ID_UNSET: | ||
1182 | break; | ||
1183 | default: | ||
1184 | if (epdrv->requested_id == id) | ||
1185 | match_id = EARLY_PLATFORM_ID_UNSET; | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | switch (match_id) { | ||
1190 | case EARLY_PLATFORM_ID_ERROR: | ||
1191 | pr_warning("%s: unable to parse %s parameter\n", | ||
1192 | class_str, epdrv->pdrv->driver.name); | ||
1193 | /* fall-through */ | ||
1194 | case EARLY_PLATFORM_ID_UNSET: | ||
1195 | match = NULL; | ||
1196 | break; | ||
1197 | default: | ||
1198 | match = early_platform_match(epdrv, match_id); | ||
1199 | } | ||
1200 | |||
1201 | if (match) { | ||
1202 | if (epdrv->pdrv->probe(match)) | ||
1203 | pr_warning("%s: unable to probe %s early.\n", | ||
1204 | class_str, match->name); | ||
1205 | else | ||
1206 | n++; | ||
1207 | } | ||
1208 | |||
1209 | if (n >= nr_probe) | ||
1210 | break; | ||
1211 | } | ||
1212 | |||
1213 | if (left) | ||
1214 | return n; | ||
1215 | else | ||
1216 | return -ENODEV; | ||
1217 | } | ||
1218 | |||
1219 | /** | ||
1220 | * early_platform_driver_probe | ||
1221 | * @class_str: string to identify early platform driver class | ||
1222 | * @nr_probe: number of platform devices to successfully probe before exiting | ||
1223 | * @user_only: only probe user specified early platform devices | ||
1224 | */ | ||
1225 | int __init early_platform_driver_probe(char *class_str, | ||
1226 | int nr_probe, | ||
1227 | int user_only) | ||
1228 | { | ||
1229 | int k, n, i; | ||
1230 | |||
1231 | n = 0; | ||
1232 | for (i = -2; n < nr_probe; i++) { | ||
1233 | k = early_platform_driver_probe_id(class_str, i, nr_probe - n); | ||
1234 | |||
1235 | if (k < 0) | ||
1236 | break; | ||
1237 | |||
1238 | n += k; | ||
1239 | |||
1240 | if (user_only) | ||
1241 | break; | ||
1242 | } | ||
1243 | |||
1244 | return n; | ||
1245 | } | ||
1246 | |||
1247 | /** | ||
1248 | * early_platform_cleanup - clean up early platform code | ||
1249 | */ | ||
1250 | void __init early_platform_cleanup(void) | ||
1251 | { | ||
1252 | struct platform_device *pd, *pd2; | ||
1253 | |||
1254 | /* clean up the devres list used to chain devices */ | ||
1255 | list_for_each_entry_safe(pd, pd2, &early_platform_device_list, | ||
1256 | dev.devres_head) { | ||
1257 | list_del(&pd->dev.devres_head); | ||
1258 | memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); | ||
1259 | } | ||
1260 | } | ||
1261 | |||
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index bdd4f5f45575..5f7e64ba87e5 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
@@ -275,8 +275,10 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page, | |||
275 | if (rw == READ) { | 275 | if (rw == READ) { |
276 | copy_from_brd(mem + off, brd, sector, len); | 276 | copy_from_brd(mem + off, brd, sector, len); |
277 | flush_dcache_page(page); | 277 | flush_dcache_page(page); |
278 | } else | 278 | } else { |
279 | flush_dcache_page(page); | ||
279 | copy_to_brd(brd, mem + off, sector, len); | 280 | copy_to_brd(brd, mem + off, sector, len); |
281 | } | ||
280 | kunmap_atomic(mem, KM_USER0); | 282 | kunmap_atomic(mem, KM_USER0); |
281 | 283 | ||
282 | out: | 284 | out: |
@@ -436,6 +438,7 @@ static struct brd_device *brd_alloc(int i) | |||
436 | if (!brd->brd_queue) | 438 | if (!brd->brd_queue) |
437 | goto out_free_dev; | 439 | goto out_free_dev; |
438 | blk_queue_make_request(brd->brd_queue, brd_make_request); | 440 | blk_queue_make_request(brd->brd_queue, brd_make_request); |
441 | blk_queue_ordered(brd->brd_queue, QUEUE_ORDERED_TAG, NULL); | ||
439 | blk_queue_max_sectors(brd->brd_queue, 1024); | 442 | blk_queue_max_sectors(brd->brd_queue, 1024); |
440 | blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY); | 443 | blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY); |
441 | 444 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 0ef6f08aa6ea..4d4d5e0d3fa6 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -3505,7 +3505,7 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u | |||
3505 | /* The Inbound Post Queue only accepts 32-bit physical addresses for the | 3505 | /* The Inbound Post Queue only accepts 32-bit physical addresses for the |
3506 | CCISS commands, so they must be allocated from the lower 4GiB of | 3506 | CCISS commands, so they must be allocated from the lower 4GiB of |
3507 | memory. */ | 3507 | memory. */ |
3508 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | 3508 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
3509 | if (err) { | 3509 | if (err) { |
3510 | iounmap(vaddr); | 3510 | iounmap(vaddr); |
3511 | return -ENOMEM; | 3511 | return -ENOMEM; |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 69b7f8e77596..689cd27ac890 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -1025,6 +1025,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1025 | { | 1025 | { |
1026 | struct urb *urb = &sc->work_urb; | 1026 | struct urb *urb = &sc->work_urb; |
1027 | struct bulk_cs_wrap *bcs; | 1027 | struct bulk_cs_wrap *bcs; |
1028 | int endp; | ||
1028 | int len; | 1029 | int len; |
1029 | int rc; | 1030 | int rc; |
1030 | 1031 | ||
@@ -1033,6 +1034,10 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1033 | return; | 1034 | return; |
1034 | } | 1035 | } |
1035 | 1036 | ||
1037 | endp = usb_pipeendpoint(sc->last_pipe); | ||
1038 | if (usb_pipein(sc->last_pipe)) | ||
1039 | endp |= USB_DIR_IN; | ||
1040 | |||
1036 | if (cmd->state == UB_CMDST_CLEAR) { | 1041 | if (cmd->state == UB_CMDST_CLEAR) { |
1037 | if (urb->status == -EPIPE) { | 1042 | if (urb->status == -EPIPE) { |
1038 | /* | 1043 | /* |
@@ -1048,9 +1053,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1048 | * We ignore the result for the halt clear. | 1053 | * We ignore the result for the halt clear. |
1049 | */ | 1054 | */ |
1050 | 1055 | ||
1051 | /* reset the endpoint toggle */ | 1056 | usb_reset_endpoint(sc->dev, endp); |
1052 | usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe), | ||
1053 | usb_pipeout(sc->last_pipe), 0); | ||
1054 | 1057 | ||
1055 | ub_state_sense(sc, cmd); | 1058 | ub_state_sense(sc, cmd); |
1056 | 1059 | ||
@@ -1065,9 +1068,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1065 | * We ignore the result for the halt clear. | 1068 | * We ignore the result for the halt clear. |
1066 | */ | 1069 | */ |
1067 | 1070 | ||
1068 | /* reset the endpoint toggle */ | 1071 | usb_reset_endpoint(sc->dev, endp); |
1069 | usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe), | ||
1070 | usb_pipeout(sc->last_pipe), 0); | ||
1071 | 1072 | ||
1072 | ub_state_stat(sc, cmd); | 1073 | ub_state_stat(sc, cmd); |
1073 | 1074 | ||
@@ -1082,9 +1083,7 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1082 | * We ignore the result for the halt clear. | 1083 | * We ignore the result for the halt clear. |
1083 | */ | 1084 | */ |
1084 | 1085 | ||
1085 | /* reset the endpoint toggle */ | 1086 | usb_reset_endpoint(sc->dev, endp); |
1086 | usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe), | ||
1087 | usb_pipeout(sc->last_pipe), 0); | ||
1088 | 1087 | ||
1089 | ub_state_stat_counted(sc, cmd); | 1088 | ub_state_stat_counted(sc, cmd); |
1090 | 1089 | ||
@@ -2119,8 +2118,7 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) | |||
2119 | del_timer_sync(&timer); | 2118 | del_timer_sync(&timer); |
2120 | usb_kill_urb(&sc->work_urb); | 2119 | usb_kill_urb(&sc->work_urb); |
2121 | 2120 | ||
2122 | /* reset the endpoint toggle */ | 2121 | usb_reset_endpoint(sc->dev, endp); |
2123 | usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0); | ||
2124 | 2122 | ||
2125 | return 0; | 2123 | return 0; |
2126 | } | 2124 | } |
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 9744d59a69f2..858c34dd032d 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
@@ -906,6 +906,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, | |||
906 | goto failed_alloc; | 906 | goto failed_alloc; |
907 | 907 | ||
908 | blk_queue_make_request(card->queue, mm_make_request); | 908 | blk_queue_make_request(card->queue, mm_make_request); |
909 | card->queue->queue_lock = &card->lock; | ||
909 | card->queue->queuedata = card; | 910 | card->queue->queuedata = card; |
910 | card->queue->unplug_fn = mm_unplug_device; | 911 | card->queue->unplug_fn = mm_unplug_device; |
911 | 912 | ||
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 10d6cbd7c05e..2224b762b7fb 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -1226,7 +1226,7 @@ int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *m | |||
1226 | int i, ret = -ENOMEM; | 1226 | int i, ret = -ENOMEM; |
1227 | 1227 | ||
1228 | for (i = 0; i < num_pages; i++) { | 1228 | for (i = 0; i < num_pages; i++) { |
1229 | page = alloc_page(GFP_KERNEL | GFP_DMA32); | 1229 | page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); |
1230 | /* agp_free_memory() needs gart address */ | 1230 | /* agp_free_memory() needs gart address */ |
1231 | if (page == NULL) | 1231 | if (page == NULL) |
1232 | goto out; | 1232 | goto out; |
@@ -1257,7 +1257,7 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | |||
1257 | { | 1257 | { |
1258 | struct page * page; | 1258 | struct page * page; |
1259 | 1259 | ||
1260 | page = alloc_page(GFP_KERNEL | GFP_DMA32); | 1260 | page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); |
1261 | if (page == NULL) | 1261 | if (page == NULL) |
1262 | return NULL; | 1262 | return NULL; |
1263 | 1263 | ||
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 9d9490e22e07..3686912427ba 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -2131,6 +2131,8 @@ static const struct intel_driver_description { | |||
2131 | { PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, 0, "830M", | 2131 | { PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, 0, "830M", |
2132 | &intel_845_driver, &intel_830_driver }, | 2132 | &intel_845_driver, &intel_830_driver }, |
2133 | { PCI_DEVICE_ID_INTEL_82850_HB, 0, 0, "i850", &intel_850_driver, NULL }, | 2133 | { PCI_DEVICE_ID_INTEL_82850_HB, 0, 0, "i850", &intel_850_driver, NULL }, |
2134 | { PCI_DEVICE_ID_INTEL_82854_HB, PCI_DEVICE_ID_INTEL_82854_IG, 0, "854", | ||
2135 | &intel_845_driver, &intel_830_driver }, | ||
2134 | { PCI_DEVICE_ID_INTEL_82855PM_HB, 0, 0, "855PM", &intel_845_driver, NULL }, | 2136 | { PCI_DEVICE_ID_INTEL_82855PM_HB, 0, 0, "855PM", &intel_845_driver, NULL }, |
2135 | { PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, 0, "855GM", | 2137 | { PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, 0, "855GM", |
2136 | &intel_845_driver, &intel_830_driver }, | 2138 | &intel_845_driver, &intel_830_driver }, |
@@ -2355,6 +2357,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2355 | ID(PCI_DEVICE_ID_INTEL_82845_HB), | 2357 | ID(PCI_DEVICE_ID_INTEL_82845_HB), |
2356 | ID(PCI_DEVICE_ID_INTEL_82845G_HB), | 2358 | ID(PCI_DEVICE_ID_INTEL_82845G_HB), |
2357 | ID(PCI_DEVICE_ID_INTEL_82850_HB), | 2359 | ID(PCI_DEVICE_ID_INTEL_82850_HB), |
2360 | ID(PCI_DEVICE_ID_INTEL_82854_HB), | ||
2358 | ID(PCI_DEVICE_ID_INTEL_82855PM_HB), | 2361 | ID(PCI_DEVICE_ID_INTEL_82855PM_HB), |
2359 | ID(PCI_DEVICE_ID_INTEL_82855GM_HB), | 2362 | ID(PCI_DEVICE_ID_INTEL_82855GM_HB), |
2360 | ID(PCI_DEVICE_ID_INTEL_82860_HB), | 2363 | ID(PCI_DEVICE_ID_INTEL_82860_HB), |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 50dfa3bc71ce..340ba4f9dc54 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -72,7 +72,7 @@ static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; | |||
72 | #ifdef CONFIG_IA64 | 72 | #ifdef CONFIG_IA64 |
73 | static void __iomem *hpet_mctr; | 73 | static void __iomem *hpet_mctr; |
74 | 74 | ||
75 | static cycle_t read_hpet(void) | 75 | static cycle_t read_hpet(struct clocksource *cs) |
76 | { | 76 | { |
77 | return (cycle_t)read_counter((void __iomem *)hpet_mctr); | 77 | return (cycle_t)read_counter((void __iomem *)hpet_mctr); |
78 | } | 78 | } |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index e93fc8d22fb2..aa83a0865ec1 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -285,6 +285,11 @@ enum ipmi_stat_indexes { | |||
285 | /* Events that were received with the proper format. */ | 285 | /* Events that were received with the proper format. */ |
286 | IPMI_STAT_events, | 286 | IPMI_STAT_events, |
287 | 287 | ||
288 | /* Retransmissions on IPMB that failed. */ | ||
289 | IPMI_STAT_dropped_rexmit_ipmb_commands, | ||
290 | |||
291 | /* Retransmissions on LAN that failed. */ | ||
292 | IPMI_STAT_dropped_rexmit_lan_commands, | ||
288 | 293 | ||
289 | /* This *must* remain last, add new values above this. */ | 294 | /* This *must* remain last, add new values above this. */ |
290 | IPMI_NUM_STATS | 295 | IPMI_NUM_STATS |
@@ -445,6 +450,20 @@ static DEFINE_MUTEX(smi_watchers_mutex); | |||
445 | #define ipmi_get_stat(intf, stat) \ | 450 | #define ipmi_get_stat(intf, stat) \ |
446 | ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat])) | 451 | ((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat])) |
447 | 452 | ||
453 | static int is_lan_addr(struct ipmi_addr *addr) | ||
454 | { | ||
455 | return addr->addr_type == IPMI_LAN_ADDR_TYPE; | ||
456 | } | ||
457 | |||
458 | static int is_ipmb_addr(struct ipmi_addr *addr) | ||
459 | { | ||
460 | return addr->addr_type == IPMI_IPMB_ADDR_TYPE; | ||
461 | } | ||
462 | |||
463 | static int is_ipmb_bcast_addr(struct ipmi_addr *addr) | ||
464 | { | ||
465 | return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE; | ||
466 | } | ||
448 | 467 | ||
449 | static void free_recv_msg_list(struct list_head *q) | 468 | static void free_recv_msg_list(struct list_head *q) |
450 | { | 469 | { |
@@ -601,8 +620,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2) | |||
601 | return (smi_addr1->lun == smi_addr2->lun); | 620 | return (smi_addr1->lun == smi_addr2->lun); |
602 | } | 621 | } |
603 | 622 | ||
604 | if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE) | 623 | if (is_ipmb_addr(addr1) || is_ipmb_bcast_addr(addr1)) { |
605 | || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) { | ||
606 | struct ipmi_ipmb_addr *ipmb_addr1 | 624 | struct ipmi_ipmb_addr *ipmb_addr1 |
607 | = (struct ipmi_ipmb_addr *) addr1; | 625 | = (struct ipmi_ipmb_addr *) addr1; |
608 | struct ipmi_ipmb_addr *ipmb_addr2 | 626 | struct ipmi_ipmb_addr *ipmb_addr2 |
@@ -612,7 +630,7 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2) | |||
612 | && (ipmb_addr1->lun == ipmb_addr2->lun)); | 630 | && (ipmb_addr1->lun == ipmb_addr2->lun)); |
613 | } | 631 | } |
614 | 632 | ||
615 | if (addr1->addr_type == IPMI_LAN_ADDR_TYPE) { | 633 | if (is_lan_addr(addr1)) { |
616 | struct ipmi_lan_addr *lan_addr1 | 634 | struct ipmi_lan_addr *lan_addr1 |
617 | = (struct ipmi_lan_addr *) addr1; | 635 | = (struct ipmi_lan_addr *) addr1; |
618 | struct ipmi_lan_addr *lan_addr2 | 636 | struct ipmi_lan_addr *lan_addr2 |
@@ -644,14 +662,13 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len) | |||
644 | || (addr->channel < 0)) | 662 | || (addr->channel < 0)) |
645 | return -EINVAL; | 663 | return -EINVAL; |
646 | 664 | ||
647 | if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE) | 665 | if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) { |
648 | || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) { | ||
649 | if (len < sizeof(struct ipmi_ipmb_addr)) | 666 | if (len < sizeof(struct ipmi_ipmb_addr)) |
650 | return -EINVAL; | 667 | return -EINVAL; |
651 | return 0; | 668 | return 0; |
652 | } | 669 | } |
653 | 670 | ||
654 | if (addr->addr_type == IPMI_LAN_ADDR_TYPE) { | 671 | if (is_lan_addr(addr)) { |
655 | if (len < sizeof(struct ipmi_lan_addr)) | 672 | if (len < sizeof(struct ipmi_lan_addr)) |
656 | return -EINVAL; | 673 | return -EINVAL; |
657 | return 0; | 674 | return 0; |
@@ -1503,8 +1520,7 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1503 | memcpy(&(smi_msg->data[2]), msg->data, msg->data_len); | 1520 | memcpy(&(smi_msg->data[2]), msg->data, msg->data_len); |
1504 | smi_msg->data_size = msg->data_len + 2; | 1521 | smi_msg->data_size = msg->data_len + 2; |
1505 | ipmi_inc_stat(intf, sent_local_commands); | 1522 | ipmi_inc_stat(intf, sent_local_commands); |
1506 | } else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE) | 1523 | } else if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) { |
1507 | || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)) { | ||
1508 | struct ipmi_ipmb_addr *ipmb_addr; | 1524 | struct ipmi_ipmb_addr *ipmb_addr; |
1509 | unsigned char ipmb_seq; | 1525 | unsigned char ipmb_seq; |
1510 | long seqid; | 1526 | long seqid; |
@@ -1583,8 +1599,6 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1583 | 1599 | ||
1584 | spin_lock_irqsave(&(intf->seq_lock), flags); | 1600 | spin_lock_irqsave(&(intf->seq_lock), flags); |
1585 | 1601 | ||
1586 | ipmi_inc_stat(intf, sent_ipmb_commands); | ||
1587 | |||
1588 | /* | 1602 | /* |
1589 | * Create a sequence number with a 1 second | 1603 | * Create a sequence number with a 1 second |
1590 | * timeout and 4 retries. | 1604 | * timeout and 4 retries. |
@@ -1606,6 +1620,8 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1606 | goto out_err; | 1620 | goto out_err; |
1607 | } | 1621 | } |
1608 | 1622 | ||
1623 | ipmi_inc_stat(intf, sent_ipmb_commands); | ||
1624 | |||
1609 | /* | 1625 | /* |
1610 | * Store the sequence number in the message, | 1626 | * Store the sequence number in the message, |
1611 | * so that when the send message response | 1627 | * so that when the send message response |
@@ -1635,7 +1651,7 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1635 | */ | 1651 | */ |
1636 | spin_unlock_irqrestore(&(intf->seq_lock), flags); | 1652 | spin_unlock_irqrestore(&(intf->seq_lock), flags); |
1637 | } | 1653 | } |
1638 | } else if (addr->addr_type == IPMI_LAN_ADDR_TYPE) { | 1654 | } else if (is_lan_addr(addr)) { |
1639 | struct ipmi_lan_addr *lan_addr; | 1655 | struct ipmi_lan_addr *lan_addr; |
1640 | unsigned char ipmb_seq; | 1656 | unsigned char ipmb_seq; |
1641 | long seqid; | 1657 | long seqid; |
@@ -1696,8 +1712,6 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1696 | 1712 | ||
1697 | spin_lock_irqsave(&(intf->seq_lock), flags); | 1713 | spin_lock_irqsave(&(intf->seq_lock), flags); |
1698 | 1714 | ||
1699 | ipmi_inc_stat(intf, sent_lan_commands); | ||
1700 | |||
1701 | /* | 1715 | /* |
1702 | * Create a sequence number with a 1 second | 1716 | * Create a sequence number with a 1 second |
1703 | * timeout and 4 retries. | 1717 | * timeout and 4 retries. |
@@ -1719,6 +1733,8 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1719 | goto out_err; | 1733 | goto out_err; |
1720 | } | 1734 | } |
1721 | 1735 | ||
1736 | ipmi_inc_stat(intf, sent_lan_commands); | ||
1737 | |||
1722 | /* | 1738 | /* |
1723 | * Store the sequence number in the message, | 1739 | * Store the sequence number in the message, |
1724 | * so that when the send message response | 1740 | * so that when the send message response |
@@ -1937,6 +1953,10 @@ static int stat_file_read_proc(char *page, char **start, off_t off, | |||
1937 | ipmi_get_stat(intf, invalid_events)); | 1953 | ipmi_get_stat(intf, invalid_events)); |
1938 | out += sprintf(out, "events: %u\n", | 1954 | out += sprintf(out, "events: %u\n", |
1939 | ipmi_get_stat(intf, events)); | 1955 | ipmi_get_stat(intf, events)); |
1956 | out += sprintf(out, "failed rexmit LAN msgs: %u\n", | ||
1957 | ipmi_get_stat(intf, dropped_rexmit_lan_commands)); | ||
1958 | out += sprintf(out, "failed rexmit IPMB msgs: %u\n", | ||
1959 | ipmi_get_stat(intf, dropped_rexmit_ipmb_commands)); | ||
1940 | 1960 | ||
1941 | return (out - ((char *) page)); | 1961 | return (out - ((char *) page)); |
1942 | } | 1962 | } |
@@ -3264,6 +3284,114 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf, | |||
3264 | return rv; | 3284 | return rv; |
3265 | } | 3285 | } |
3266 | 3286 | ||
3287 | /* | ||
3288 | * This routine will handle "Get Message" command responses with | ||
3289 | * channels that use an OEM Medium. The message format belongs to | ||
3290 | * the OEM. See IPMI 2.0 specification, Chapter 6 and | ||
3291 | * Chapter 22, sections 22.6 and 22.24 for more details. | ||
3292 | */ | ||
3293 | static int handle_oem_get_msg_cmd(ipmi_smi_t intf, | ||
3294 | struct ipmi_smi_msg *msg) | ||
3295 | { | ||
3296 | struct cmd_rcvr *rcvr; | ||
3297 | int rv = 0; | ||
3298 | unsigned char netfn; | ||
3299 | unsigned char cmd; | ||
3300 | unsigned char chan; | ||
3301 | ipmi_user_t user = NULL; | ||
3302 | struct ipmi_system_interface_addr *smi_addr; | ||
3303 | struct ipmi_recv_msg *recv_msg; | ||
3304 | |||
3305 | /* | ||
3306 | * We expect the OEM SW to perform error checking | ||
3307 | * so we just do some basic sanity checks | ||
3308 | */ | ||
3309 | if (msg->rsp_size < 4) { | ||
3310 | /* Message not big enough, just ignore it. */ | ||
3311 | ipmi_inc_stat(intf, invalid_commands); | ||
3312 | return 0; | ||
3313 | } | ||
3314 | |||
3315 | if (msg->rsp[2] != 0) { | ||
3316 | /* An error getting the response, just ignore it. */ | ||
3317 | return 0; | ||
3318 | } | ||
3319 | |||
3320 | /* | ||
3321 | * This is an OEM Message so the OEM needs to know how | ||
3322 | * handle the message. We do no interpretation. | ||
3323 | */ | ||
3324 | netfn = msg->rsp[0] >> 2; | ||
3325 | cmd = msg->rsp[1]; | ||
3326 | chan = msg->rsp[3] & 0xf; | ||
3327 | |||
3328 | rcu_read_lock(); | ||
3329 | rcvr = find_cmd_rcvr(intf, netfn, cmd, chan); | ||
3330 | if (rcvr) { | ||
3331 | user = rcvr->user; | ||
3332 | kref_get(&user->refcount); | ||
3333 | } else | ||
3334 | user = NULL; | ||
3335 | rcu_read_unlock(); | ||
3336 | |||
3337 | if (user == NULL) { | ||
3338 | /* We didn't find a user, just give up. */ | ||
3339 | ipmi_inc_stat(intf, unhandled_commands); | ||
3340 | |||
3341 | /* | ||
3342 | * Don't do anything with these messages, just allow | ||
3343 | * them to be freed. | ||
3344 | */ | ||
3345 | |||
3346 | rv = 0; | ||
3347 | } else { | ||
3348 | /* Deliver the message to the user. */ | ||
3349 | ipmi_inc_stat(intf, handled_commands); | ||
3350 | |||
3351 | recv_msg = ipmi_alloc_recv_msg(); | ||
3352 | if (!recv_msg) { | ||
3353 | /* | ||
3354 | * We couldn't allocate memory for the | ||
3355 | * message, so requeue it for handling | ||
3356 | * later. | ||
3357 | */ | ||
3358 | rv = 1; | ||
3359 | kref_put(&user->refcount, free_user); | ||
3360 | } else { | ||
3361 | /* | ||
3362 | * OEM Messages are expected to be delivered via | ||
3363 | * the system interface to SMS software. We might | ||
3364 | * need to visit this again depending on OEM | ||
3365 | * requirements | ||
3366 | */ | ||
3367 | smi_addr = ((struct ipmi_system_interface_addr *) | ||
3368 | &(recv_msg->addr)); | ||
3369 | smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
3370 | smi_addr->channel = IPMI_BMC_CHANNEL; | ||
3371 | smi_addr->lun = msg->rsp[0] & 3; | ||
3372 | |||
3373 | recv_msg->user = user; | ||
3374 | recv_msg->user_msg_data = NULL; | ||
3375 | recv_msg->recv_type = IPMI_OEM_RECV_TYPE; | ||
3376 | recv_msg->msg.netfn = msg->rsp[0] >> 2; | ||
3377 | recv_msg->msg.cmd = msg->rsp[1]; | ||
3378 | recv_msg->msg.data = recv_msg->msg_data; | ||
3379 | |||
3380 | /* | ||
3381 | * The message starts at byte 4 which follows the | ||
3382 | * the Channel Byte in the "GET MESSAGE" command | ||
3383 | */ | ||
3384 | recv_msg->msg.data_len = msg->rsp_size - 4; | ||
3385 | memcpy(recv_msg->msg_data, | ||
3386 | &(msg->rsp[4]), | ||
3387 | msg->rsp_size - 4); | ||
3388 | deliver_response(recv_msg); | ||
3389 | } | ||
3390 | } | ||
3391 | |||
3392 | return rv; | ||
3393 | } | ||
3394 | |||
3267 | static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg, | 3395 | static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg, |
3268 | struct ipmi_smi_msg *msg) | 3396 | struct ipmi_smi_msg *msg) |
3269 | { | 3397 | { |
@@ -3519,6 +3647,17 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3519 | goto out; | 3647 | goto out; |
3520 | } | 3648 | } |
3521 | 3649 | ||
3650 | /* | ||
3651 | ** We need to make sure the channels have been initialized. | ||
3652 | ** The channel_handler routine will set the "curr_channel" | ||
3653 | ** equal to or greater than IPMI_MAX_CHANNELS when all the | ||
3654 | ** channels for this interface have been initialized. | ||
3655 | */ | ||
3656 | if (intf->curr_channel < IPMI_MAX_CHANNELS) { | ||
3657 | requeue = 1; /* Just put the message back for now */ | ||
3658 | goto out; | ||
3659 | } | ||
3660 | |||
3522 | switch (intf->channels[chan].medium) { | 3661 | switch (intf->channels[chan].medium) { |
3523 | case IPMI_CHANNEL_MEDIUM_IPMB: | 3662 | case IPMI_CHANNEL_MEDIUM_IPMB: |
3524 | if (msg->rsp[4] & 0x04) { | 3663 | if (msg->rsp[4] & 0x04) { |
@@ -3554,11 +3693,20 @@ static int handle_new_recv_msg(ipmi_smi_t intf, | |||
3554 | break; | 3693 | break; |
3555 | 3694 | ||
3556 | default: | 3695 | default: |
3557 | /* | 3696 | /* Check for OEM Channels. Clients had better |
3558 | * We don't handle the channel type, so just | 3697 | register for these commands. */ |
3559 | * free the message. | 3698 | if ((intf->channels[chan].medium |
3560 | */ | 3699 | >= IPMI_CHANNEL_MEDIUM_OEM_MIN) |
3561 | requeue = 0; | 3700 | && (intf->channels[chan].medium |
3701 | <= IPMI_CHANNEL_MEDIUM_OEM_MAX)) { | ||
3702 | requeue = handle_oem_get_msg_cmd(intf, msg); | ||
3703 | } else { | ||
3704 | /* | ||
3705 | * We don't handle the channel type, so just | ||
3706 | * free the message. | ||
3707 | */ | ||
3708 | requeue = 0; | ||
3709 | } | ||
3562 | } | 3710 | } |
3563 | 3711 | ||
3564 | } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) | 3712 | } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) |
@@ -3730,7 +3878,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
3730 | list_add_tail(&msg->link, timeouts); | 3878 | list_add_tail(&msg->link, timeouts); |
3731 | if (ent->broadcast) | 3879 | if (ent->broadcast) |
3732 | ipmi_inc_stat(intf, timed_out_ipmb_broadcasts); | 3880 | ipmi_inc_stat(intf, timed_out_ipmb_broadcasts); |
3733 | else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE) | 3881 | else if (is_lan_addr(&ent->recv_msg->addr)) |
3734 | ipmi_inc_stat(intf, timed_out_lan_commands); | 3882 | ipmi_inc_stat(intf, timed_out_lan_commands); |
3735 | else | 3883 | else |
3736 | ipmi_inc_stat(intf, timed_out_ipmb_commands); | 3884 | ipmi_inc_stat(intf, timed_out_ipmb_commands); |
@@ -3744,15 +3892,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
3744 | */ | 3892 | */ |
3745 | ent->timeout = MAX_MSG_TIMEOUT; | 3893 | ent->timeout = MAX_MSG_TIMEOUT; |
3746 | ent->retries_left--; | 3894 | ent->retries_left--; |
3747 | if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE) | ||
3748 | ipmi_inc_stat(intf, retransmitted_lan_commands); | ||
3749 | else | ||
3750 | ipmi_inc_stat(intf, retransmitted_ipmb_commands); | ||
3751 | |||
3752 | smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, | 3895 | smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, |
3753 | ent->seqid); | 3896 | ent->seqid); |
3754 | if (!smi_msg) | 3897 | if (!smi_msg) { |
3898 | if (is_lan_addr(&ent->recv_msg->addr)) | ||
3899 | ipmi_inc_stat(intf, | ||
3900 | dropped_rexmit_lan_commands); | ||
3901 | else | ||
3902 | ipmi_inc_stat(intf, | ||
3903 | dropped_rexmit_ipmb_commands); | ||
3755 | return; | 3904 | return; |
3905 | } | ||
3756 | 3906 | ||
3757 | spin_unlock_irqrestore(&intf->seq_lock, *flags); | 3907 | spin_unlock_irqrestore(&intf->seq_lock, *flags); |
3758 | 3908 | ||
@@ -3764,10 +3914,17 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
3764 | * resent. | 3914 | * resent. |
3765 | */ | 3915 | */ |
3766 | handlers = intf->handlers; | 3916 | handlers = intf->handlers; |
3767 | if (handlers) | 3917 | if (handlers) { |
3918 | if (is_lan_addr(&ent->recv_msg->addr)) | ||
3919 | ipmi_inc_stat(intf, | ||
3920 | retransmitted_lan_commands); | ||
3921 | else | ||
3922 | ipmi_inc_stat(intf, | ||
3923 | retransmitted_ipmb_commands); | ||
3924 | |||
3768 | intf->handlers->sender(intf->send_info, | 3925 | intf->handlers->sender(intf->send_info, |
3769 | smi_msg, 0); | 3926 | smi_msg, 0); |
3770 | else | 3927 | } else |
3771 | ipmi_free_smi_msg(smi_msg); | 3928 | ipmi_free_smi_msg(smi_msg); |
3772 | 3929 | ||
3773 | spin_lock_irqsave(&intf->seq_lock, *flags); | 3930 | spin_lock_irqsave(&intf->seq_lock, *flags); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index e58ea4cd55ce..259644646b82 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -82,12 +82,6 @@ | |||
82 | #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a | 82 | #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a |
83 | short timeout */ | 83 | short timeout */ |
84 | 84 | ||
85 | /* Bit for BMC global enables. */ | ||
86 | #define IPMI_BMC_RCV_MSG_INTR 0x01 | ||
87 | #define IPMI_BMC_EVT_MSG_INTR 0x02 | ||
88 | #define IPMI_BMC_EVT_MSG_BUFF 0x04 | ||
89 | #define IPMI_BMC_SYS_LOG 0x08 | ||
90 | |||
91 | enum si_intf_state { | 85 | enum si_intf_state { |
92 | SI_NORMAL, | 86 | SI_NORMAL, |
93 | SI_GETTING_FLAGS, | 87 | SI_GETTING_FLAGS, |
@@ -220,6 +214,9 @@ struct smi_info { | |||
220 | OEM2_DATA_AVAIL) | 214 | OEM2_DATA_AVAIL) |
221 | unsigned char msg_flags; | 215 | unsigned char msg_flags; |
222 | 216 | ||
217 | /* Does the BMC have an event buffer? */ | ||
218 | char has_event_buffer; | ||
219 | |||
223 | /* | 220 | /* |
224 | * If set to true, this will request events the next time the | 221 | * If set to true, this will request events the next time the |
225 | * state machine is idle. | 222 | * state machine is idle. |
@@ -968,7 +965,8 @@ static void request_events(void *send_info) | |||
968 | { | 965 | { |
969 | struct smi_info *smi_info = send_info; | 966 | struct smi_info *smi_info = send_info; |
970 | 967 | ||
971 | if (atomic_read(&smi_info->stop_operation)) | 968 | if (atomic_read(&smi_info->stop_operation) || |
969 | !smi_info->has_event_buffer) | ||
972 | return; | 970 | return; |
973 | 971 | ||
974 | atomic_set(&smi_info->req_events, 1); | 972 | atomic_set(&smi_info->req_events, 1); |
@@ -2407,26 +2405,9 @@ static struct of_platform_driver ipmi_of_platform_driver = { | |||
2407 | }; | 2405 | }; |
2408 | #endif /* CONFIG_PPC_OF */ | 2406 | #endif /* CONFIG_PPC_OF */ |
2409 | 2407 | ||
2410 | 2408 | static int wait_for_msg_done(struct smi_info *smi_info) | |
2411 | static int try_get_dev_id(struct smi_info *smi_info) | ||
2412 | { | 2409 | { |
2413 | unsigned char msg[2]; | ||
2414 | unsigned char *resp; | ||
2415 | unsigned long resp_len; | ||
2416 | enum si_sm_result smi_result; | 2410 | enum si_sm_result smi_result; |
2417 | int rv = 0; | ||
2418 | |||
2419 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | ||
2420 | if (!resp) | ||
2421 | return -ENOMEM; | ||
2422 | |||
2423 | /* | ||
2424 | * Do a Get Device ID command, since it comes back with some | ||
2425 | * useful info. | ||
2426 | */ | ||
2427 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
2428 | msg[1] = IPMI_GET_DEVICE_ID_CMD; | ||
2429 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); | ||
2430 | 2411 | ||
2431 | smi_result = smi_info->handlers->event(smi_info->si_sm, 0); | 2412 | smi_result = smi_info->handlers->event(smi_info->si_sm, 0); |
2432 | for (;;) { | 2413 | for (;;) { |
@@ -2441,16 +2422,39 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
2441 | } else | 2422 | } else |
2442 | break; | 2423 | break; |
2443 | } | 2424 | } |
2444 | if (smi_result == SI_SM_HOSED) { | 2425 | if (smi_result == SI_SM_HOSED) |
2445 | /* | 2426 | /* |
2446 | * We couldn't get the state machine to run, so whatever's at | 2427 | * We couldn't get the state machine to run, so whatever's at |
2447 | * the port is probably not an IPMI SMI interface. | 2428 | * the port is probably not an IPMI SMI interface. |
2448 | */ | 2429 | */ |
2449 | rv = -ENODEV; | 2430 | return -ENODEV; |
2431 | |||
2432 | return 0; | ||
2433 | } | ||
2434 | |||
2435 | static int try_get_dev_id(struct smi_info *smi_info) | ||
2436 | { | ||
2437 | unsigned char msg[2]; | ||
2438 | unsigned char *resp; | ||
2439 | unsigned long resp_len; | ||
2440 | int rv = 0; | ||
2441 | |||
2442 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | ||
2443 | if (!resp) | ||
2444 | return -ENOMEM; | ||
2445 | |||
2446 | /* | ||
2447 | * Do a Get Device ID command, since it comes back with some | ||
2448 | * useful info. | ||
2449 | */ | ||
2450 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
2451 | msg[1] = IPMI_GET_DEVICE_ID_CMD; | ||
2452 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); | ||
2453 | |||
2454 | rv = wait_for_msg_done(smi_info); | ||
2455 | if (rv) | ||
2450 | goto out; | 2456 | goto out; |
2451 | } | ||
2452 | 2457 | ||
2453 | /* Otherwise, we got some data. */ | ||
2454 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, | 2458 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, |
2455 | resp, IPMI_MAX_MSG_LENGTH); | 2459 | resp, IPMI_MAX_MSG_LENGTH); |
2456 | 2460 | ||
@@ -2462,6 +2466,88 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
2462 | return rv; | 2466 | return rv; |
2463 | } | 2467 | } |
2464 | 2468 | ||
2469 | static int try_enable_event_buffer(struct smi_info *smi_info) | ||
2470 | { | ||
2471 | unsigned char msg[3]; | ||
2472 | unsigned char *resp; | ||
2473 | unsigned long resp_len; | ||
2474 | int rv = 0; | ||
2475 | |||
2476 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | ||
2477 | if (!resp) | ||
2478 | return -ENOMEM; | ||
2479 | |||
2480 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
2481 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; | ||
2482 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); | ||
2483 | |||
2484 | rv = wait_for_msg_done(smi_info); | ||
2485 | if (rv) { | ||
2486 | printk(KERN_WARNING | ||
2487 | "ipmi_si: Error getting response from get global," | ||
2488 | " enables command, the event buffer is not" | ||
2489 | " enabled.\n"); | ||
2490 | goto out; | ||
2491 | } | ||
2492 | |||
2493 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, | ||
2494 | resp, IPMI_MAX_MSG_LENGTH); | ||
2495 | |||
2496 | if (resp_len < 4 || | ||
2497 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || | ||
2498 | resp[1] != IPMI_GET_BMC_GLOBAL_ENABLES_CMD || | ||
2499 | resp[2] != 0) { | ||
2500 | printk(KERN_WARNING | ||
2501 | "ipmi_si: Invalid return from get global" | ||
2502 | " enables command, cannot enable the event" | ||
2503 | " buffer.\n"); | ||
2504 | rv = -EINVAL; | ||
2505 | goto out; | ||
2506 | } | ||
2507 | |||
2508 | if (resp[3] & IPMI_BMC_EVT_MSG_BUFF) | ||
2509 | /* buffer is already enabled, nothing to do. */ | ||
2510 | goto out; | ||
2511 | |||
2512 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
2513 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | ||
2514 | msg[2] = resp[3] | IPMI_BMC_EVT_MSG_BUFF; | ||
2515 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3); | ||
2516 | |||
2517 | rv = wait_for_msg_done(smi_info); | ||
2518 | if (rv) { | ||
2519 | printk(KERN_WARNING | ||
2520 | "ipmi_si: Error getting response from set global," | ||
2521 | " enables command, the event buffer is not" | ||
2522 | " enabled.\n"); | ||
2523 | goto out; | ||
2524 | } | ||
2525 | |||
2526 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, | ||
2527 | resp, IPMI_MAX_MSG_LENGTH); | ||
2528 | |||
2529 | if (resp_len < 3 || | ||
2530 | resp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || | ||
2531 | resp[1] != IPMI_SET_BMC_GLOBAL_ENABLES_CMD) { | ||
2532 | printk(KERN_WARNING | ||
2533 | "ipmi_si: Invalid return from get global," | ||
2534 | "enables command, not enable the event" | ||
2535 | " buffer.\n"); | ||
2536 | rv = -EINVAL; | ||
2537 | goto out; | ||
2538 | } | ||
2539 | |||
2540 | if (resp[2] != 0) | ||
2541 | /* | ||
2542 | * An error when setting the event buffer bit means | ||
2543 | * that the event buffer is not supported. | ||
2544 | */ | ||
2545 | rv = -ENOENT; | ||
2546 | out: | ||
2547 | kfree(resp); | ||
2548 | return rv; | ||
2549 | } | ||
2550 | |||
2465 | static int type_file_read_proc(char *page, char **start, off_t off, | 2551 | static int type_file_read_proc(char *page, char **start, off_t off, |
2466 | int count, int *eof, void *data) | 2552 | int count, int *eof, void *data) |
2467 | { | 2553 | { |
@@ -2847,6 +2933,10 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2847 | new_smi->intf_num = smi_num; | 2933 | new_smi->intf_num = smi_num; |
2848 | smi_num++; | 2934 | smi_num++; |
2849 | 2935 | ||
2936 | rv = try_enable_event_buffer(new_smi); | ||
2937 | if (rv == 0) | ||
2938 | new_smi->has_event_buffer = 1; | ||
2939 | |||
2850 | /* | 2940 | /* |
2851 | * Start clearing the flags before we enable interrupts or the | 2941 | * Start clearing the flags before we enable interrupts or the |
2852 | * timer to avoid racing with the timer. | 2942 | * timer to avoid racing with the timer. |
@@ -2863,7 +2953,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2863 | */ | 2953 | */ |
2864 | new_smi->pdev = platform_device_alloc("ipmi_si", | 2954 | new_smi->pdev = platform_device_alloc("ipmi_si", |
2865 | new_smi->intf_num); | 2955 | new_smi->intf_num); |
2866 | if (rv) { | 2956 | if (!new_smi->pdev) { |
2867 | printk(KERN_ERR | 2957 | printk(KERN_ERR |
2868 | "ipmi_si_intf:" | 2958 | "ipmi_si_intf:" |
2869 | " Unable to allocate platform device\n"); | 2959 | " Unable to allocate platform device\n"); |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 3586b3b3df3f..8f05c38c2f06 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -301,33 +301,7 @@ static inline int private_mapping_ok(struct vm_area_struct *vma) | |||
301 | } | 301 | } |
302 | #endif | 302 | #endif |
303 | 303 | ||
304 | void __attribute__((weak)) | ||
305 | map_devmem(unsigned long pfn, unsigned long len, pgprot_t prot) | ||
306 | { | ||
307 | /* nothing. architectures can override. */ | ||
308 | } | ||
309 | |||
310 | void __attribute__((weak)) | ||
311 | unmap_devmem(unsigned long pfn, unsigned long len, pgprot_t prot) | ||
312 | { | ||
313 | /* nothing. architectures can override. */ | ||
314 | } | ||
315 | |||
316 | static void mmap_mem_open(struct vm_area_struct *vma) | ||
317 | { | ||
318 | map_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start, | ||
319 | vma->vm_page_prot); | ||
320 | } | ||
321 | |||
322 | static void mmap_mem_close(struct vm_area_struct *vma) | ||
323 | { | ||
324 | unmap_devmem(vma->vm_pgoff, vma->vm_end - vma->vm_start, | ||
325 | vma->vm_page_prot); | ||
326 | } | ||
327 | |||
328 | static struct vm_operations_struct mmap_mem_ops = { | 304 | static struct vm_operations_struct mmap_mem_ops = { |
329 | .open = mmap_mem_open, | ||
330 | .close = mmap_mem_close, | ||
331 | #ifdef CONFIG_HAVE_IOREMAP_PROT | 305 | #ifdef CONFIG_HAVE_IOREMAP_PROT |
332 | .access = generic_access_phys | 306 | .access = generic_access_phys |
333 | #endif | 307 | #endif |
@@ -362,7 +336,6 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) | |||
362 | vma->vm_pgoff, | 336 | vma->vm_pgoff, |
363 | size, | 337 | size, |
364 | vma->vm_page_prot)) { | 338 | vma->vm_page_prot)) { |
365 | unmap_devmem(vma->vm_pgoff, size, vma->vm_page_prot); | ||
366 | return -EAGAIN; | 339 | return -EAGAIN; |
367 | } | 340 | } |
368 | return 0; | 341 | return 0; |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 6de020d078e1..b0a6a3e51924 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/vt_kern.h> | 35 | #include <linux/vt_kern.h> |
36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
37 | #include <linux/kexec.h> | 37 | #include <linux/kexec.h> |
38 | #include <linux/interrupt.h> | ||
39 | #include <linux/hrtimer.h> | 38 | #include <linux/hrtimer.h> |
40 | #include <linux/oom.h> | 39 | #include <linux/oom.h> |
41 | 40 | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 2c1d133819b5..08151d4de489 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -2274,7 +2274,7 @@ rescan_last_byte: | |||
2274 | continue; /* nothing to display */ | 2274 | continue; /* nothing to display */ |
2275 | } | 2275 | } |
2276 | /* Glyph not found */ | 2276 | /* Glyph not found */ |
2277 | if ((!(vc->vc_utf && !vc->vc_disp_ctrl) && c < 128) && !(c & ~charmask)) { | 2277 | if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) { |
2278 | /* In legacy mode use the glyph we get by a 1:1 mapping. | 2278 | /* In legacy mode use the glyph we get by a 1:1 mapping. |
2279 | This would make absolutely no sense with Unicode in mind, | 2279 | This would make absolutely no sense with Unicode in mind, |
2280 | but do this for ASCII characters since a font may lack | 2280 | but do this for ASCII characters since a font may lack |
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index ee19b6e8fcb4..40bd8c61c7d7 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c | |||
@@ -57,7 +57,7 @@ u32 acpi_pm_read_verified(void) | |||
57 | return v2; | 57 | return v2; |
58 | } | 58 | } |
59 | 59 | ||
60 | static cycle_t acpi_pm_read(void) | 60 | static cycle_t acpi_pm_read(struct clocksource *cs) |
61 | { | 61 | { |
62 | return (cycle_t)read_pmtmr(); | 62 | return (cycle_t)read_pmtmr(); |
63 | } | 63 | } |
@@ -83,7 +83,7 @@ static int __init acpi_pm_good_setup(char *__str) | |||
83 | } | 83 | } |
84 | __setup("acpi_pm_good", acpi_pm_good_setup); | 84 | __setup("acpi_pm_good", acpi_pm_good_setup); |
85 | 85 | ||
86 | static cycle_t acpi_pm_read_slow(void) | 86 | static cycle_t acpi_pm_read_slow(struct clocksource *cs) |
87 | { | 87 | { |
88 | return (cycle_t)acpi_pm_read_verified(); | 88 | return (cycle_t)acpi_pm_read_verified(); |
89 | } | 89 | } |
@@ -156,9 +156,9 @@ static int verify_pmtmr_rate(void) | |||
156 | unsigned long count, delta; | 156 | unsigned long count, delta; |
157 | 157 | ||
158 | mach_prepare_counter(); | 158 | mach_prepare_counter(); |
159 | value1 = clocksource_acpi_pm.read(); | 159 | value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); |
160 | mach_countup(&count); | 160 | mach_countup(&count); |
161 | value2 = clocksource_acpi_pm.read(); | 161 | value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); |
162 | delta = (value2 - value1) & ACPI_PM_MASK; | 162 | delta = (value2 - value1) & ACPI_PM_MASK; |
163 | 163 | ||
164 | /* Check that the PMTMR delta is within 5% of what we expect */ | 164 | /* Check that the PMTMR delta is within 5% of what we expect */ |
@@ -195,9 +195,9 @@ static int __init init_acpi_pm_clocksource(void) | |||
195 | /* "verify" this timing source: */ | 195 | /* "verify" this timing source: */ |
196 | for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { | 196 | for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { |
197 | udelay(100 * j); | 197 | udelay(100 * j); |
198 | value1 = clocksource_acpi_pm.read(); | 198 | value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); |
199 | for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { | 199 | for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { |
200 | value2 = clocksource_acpi_pm.read(); | 200 | value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); |
201 | if (value2 == value1) | 201 | if (value2 == value1) |
202 | continue; | 202 | continue; |
203 | if (value2 > value1) | 203 | if (value2 > value1) |
diff --git a/drivers/clocksource/cyclone.c b/drivers/clocksource/cyclone.c index 8615059a8729..64e528e8bfa6 100644 --- a/drivers/clocksource/cyclone.c +++ b/drivers/clocksource/cyclone.c | |||
@@ -19,7 +19,7 @@ | |||
19 | int use_cyclone = 0; | 19 | int use_cyclone = 0; |
20 | static void __iomem *cyclone_ptr; | 20 | static void __iomem *cyclone_ptr; |
21 | 21 | ||
22 | static cycle_t read_cyclone(void) | 22 | static cycle_t read_cyclone(struct clocksource *cs) |
23 | { | 23 | { |
24 | return (cycle_t)readl(cyclone_ptr); | 24 | return (cycle_t)readl(cyclone_ptr); |
25 | } | 25 | } |
diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c index b92da677aa5d..27f4d9637b62 100644 --- a/drivers/clocksource/scx200_hrt.c +++ b/drivers/clocksource/scx200_hrt.c | |||
@@ -43,7 +43,7 @@ MODULE_PARM_DESC(ppm, "+-adjust to actual XO freq (ppm)"); | |||
43 | /* The base timer frequency, * 27 if selected */ | 43 | /* The base timer frequency, * 27 if selected */ |
44 | #define HRT_FREQ 1000000 | 44 | #define HRT_FREQ 1000000 |
45 | 45 | ||
46 | static cycle_t read_hrt(void) | 46 | static cycle_t read_hrt(struct clocksource *cs) |
47 | { | 47 | { |
48 | /* Read the timer value */ | 48 | /* Read the timer value */ |
49 | return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET); | 49 | return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET); |
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c index 254f1064d973..01b886e68822 100644 --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | static void __iomem *tcaddr; | 40 | static void __iomem *tcaddr; |
41 | 41 | ||
42 | static cycle_t tc_get_cycles(void) | 42 | static cycle_t tc_get_cycles(struct clocksource *cs) |
43 | { | 43 | { |
44 | unsigned long flags; | 44 | unsigned long flags; |
45 | u32 lower, upper; | 45 | u32 lower, upper; |
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index 28f2c3f959b5..6ad95c8d6363 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h | |||
@@ -767,11 +767,19 @@ static inline void pci_write_bits16(struct pci_dev *pdev, int offset, | |||
767 | pci_write_config_word(pdev, offset, value); | 767 | pci_write_config_word(pdev, offset, value); |
768 | } | 768 | } |
769 | 769 | ||
770 | /* write all or some bits in a dword-register*/ | 770 | /* |
771 | * pci_write_bits32 | ||
772 | * | ||
773 | * edac local routine to do pci_write_config_dword, but adds | ||
774 | * a mask parameter. If mask is all ones, ignore the mask. | ||
775 | * Otherwise utilize the mask to isolate specified bits | ||
776 | * | ||
777 | * write all or some bits in a dword-register | ||
778 | */ | ||
771 | static inline void pci_write_bits32(struct pci_dev *pdev, int offset, | 779 | static inline void pci_write_bits32(struct pci_dev *pdev, int offset, |
772 | u32 value, u32 mask) | 780 | u32 value, u32 mask) |
773 | { | 781 | { |
774 | if (mask != 0xffff) { | 782 | if (mask != 0xffffffff) { |
775 | u32 buf; | 783 | u32 buf; |
776 | 784 | ||
777 | pci_read_config_dword(pdev, offset, &buf); | 785 | pci_read_config_dword(pdev, offset, &buf); |
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index ca9113e1c106..a7d2c717d033 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c | |||
@@ -389,7 +389,7 @@ static void del_edac_device_from_global_list(struct edac_device_ctl_info | |||
389 | */ | 389 | */ |
390 | static void edac_device_workq_function(struct work_struct *work_req) | 390 | static void edac_device_workq_function(struct work_struct *work_req) |
391 | { | 391 | { |
392 | struct delayed_work *d_work = (struct delayed_work *)work_req; | 392 | struct delayed_work *d_work = to_delayed_work(work_req); |
393 | struct edac_device_ctl_info *edac_dev = to_edac_device_ctl_work(d_work); | 393 | struct edac_device_ctl_info *edac_dev = to_edac_device_ctl_work(d_work); |
394 | 394 | ||
395 | mutex_lock(&device_ctls_mutex); | 395 | mutex_lock(&device_ctls_mutex); |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 25d66940b4fa..335b7ebdb11c 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -260,7 +260,7 @@ static int edac_mc_assert_error_check_and_clear(void) | |||
260 | */ | 260 | */ |
261 | static void edac_mc_workq_function(struct work_struct *work_req) | 261 | static void edac_mc_workq_function(struct work_struct *work_req) |
262 | { | 262 | { |
263 | struct delayed_work *d_work = (struct delayed_work *)work_req; | 263 | struct delayed_work *d_work = to_delayed_work(work_req); |
264 | struct mem_ctl_info *mci = to_edac_mem_ctl_work(d_work); | 264 | struct mem_ctl_info *mci = to_edac_mem_ctl_work(d_work); |
265 | 265 | ||
266 | mutex_lock(&mem_ctls_mutex); | 266 | mutex_lock(&mem_ctls_mutex); |
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c index 5b150aea703a..30b585b1d60b 100644 --- a/drivers/edac/edac_pci.c +++ b/drivers/edac/edac_pci.c | |||
@@ -233,7 +233,7 @@ EXPORT_SYMBOL_GPL(edac_pci_find); | |||
233 | */ | 233 | */ |
234 | static void edac_pci_workq_function(struct work_struct *work_req) | 234 | static void edac_pci_workq_function(struct work_struct *work_req) |
235 | { | 235 | { |
236 | struct delayed_work *d_work = (struct delayed_work *)work_req; | 236 | struct delayed_work *d_work = to_delayed_work(work_req); |
237 | struct edac_pci_ctl_info *pci = to_edac_pci_ctl_work(d_work); | 237 | struct edac_pci_ctl_info *pci = to_edac_pci_ctl_work(d_work); |
238 | int msec; | 238 | int msec; |
239 | unsigned long delay; | 239 | unsigned long delay; |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 4637a4a757df..7c8c2d72916f 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -674,7 +674,7 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci) | |||
674 | int row_index; | 674 | int row_index; |
675 | 675 | ||
676 | err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT); | 676 | err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT); |
677 | if (err_detect) | 677 | if (!err_detect) |
678 | return; | 678 | return; |
679 | 679 | ||
680 | mpc85xx_mc_printk(mci, KERN_ERR, "Err Detect Register: %#8.8x\n", | 680 | mpc85xx_mc_printk(mci, KERN_ERR, "Err Detect Register: %#8.8x\n", |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index d009661781bc..ef878615c49f 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -159,6 +159,9 @@ void drm_master_put(struct drm_master **master) | |||
159 | int drm_setmaster_ioctl(struct drm_device *dev, void *data, | 159 | int drm_setmaster_ioctl(struct drm_device *dev, void *data, |
160 | struct drm_file *file_priv) | 160 | struct drm_file *file_priv) |
161 | { | 161 | { |
162 | if (file_priv->is_master) | ||
163 | return 0; | ||
164 | |||
162 | if (file_priv->minor->master && file_priv->minor->master != file_priv->master) | 165 | if (file_priv->minor->master && file_priv->minor->master != file_priv->master) |
163 | return -EINVAL; | 166 | return -EINVAL; |
164 | 167 | ||
@@ -169,6 +172,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, | |||
169 | file_priv->minor->master != file_priv->master) { | 172 | file_priv->minor->master != file_priv->master) { |
170 | mutex_lock(&dev->struct_mutex); | 173 | mutex_lock(&dev->struct_mutex); |
171 | file_priv->minor->master = drm_master_get(file_priv->master); | 174 | file_priv->minor->master = drm_master_get(file_priv->master); |
175 | file_priv->is_master = 1; | ||
172 | mutex_unlock(&dev->struct_mutex); | 176 | mutex_unlock(&dev->struct_mutex); |
173 | } | 177 | } |
174 | 178 | ||
@@ -178,10 +182,15 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data, | |||
178 | int drm_dropmaster_ioctl(struct drm_device *dev, void *data, | 182 | int drm_dropmaster_ioctl(struct drm_device *dev, void *data, |
179 | struct drm_file *file_priv) | 183 | struct drm_file *file_priv) |
180 | { | 184 | { |
181 | if (!file_priv->master) | 185 | if (!file_priv->is_master) |
182 | return -EINVAL; | 186 | return -EINVAL; |
187 | |||
188 | if (!file_priv->minor->master) | ||
189 | return -EINVAL; | ||
190 | |||
183 | mutex_lock(&dev->struct_mutex); | 191 | mutex_lock(&dev->struct_mutex); |
184 | drm_master_put(&file_priv->minor->master); | 192 | drm_master_put(&file_priv->minor->master); |
193 | file_priv->is_master = 0; | ||
185 | mutex_unlock(&dev->struct_mutex); | 194 | mutex_unlock(&dev->struct_mutex); |
186 | return 0; | 195 | return 0; |
187 | } | 196 | } |
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index bc0c6849360c..022876ae34f0 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c | |||
@@ -132,6 +132,7 @@ void drm_sysfs_destroy(void) | |||
132 | */ | 132 | */ |
133 | static void drm_sysfs_device_release(struct device *dev) | 133 | static void drm_sysfs_device_release(struct device *dev) |
134 | { | 134 | { |
135 | memset(dev, 0, sizeof(struct device)); | ||
135 | return; | 136 | return; |
136 | } | 137 | } |
137 | 138 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3750d8003048..473a8f7fbdb5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -446,6 +446,9 @@ struct drm_i915_gem_object { | |||
446 | uint32_t tiling_mode; | 446 | uint32_t tiling_mode; |
447 | uint32_t stride; | 447 | uint32_t stride; |
448 | 448 | ||
449 | /** Record of address bit 17 of each page at last unbind. */ | ||
450 | long *bit_17; | ||
451 | |||
449 | /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ | 452 | /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */ |
450 | uint32_t agp_type; | 453 | uint32_t agp_type; |
451 | 454 | ||
@@ -635,9 +638,13 @@ int i915_gem_attach_phys_object(struct drm_device *dev, | |||
635 | void i915_gem_detach_phys_object(struct drm_device *dev, | 638 | void i915_gem_detach_phys_object(struct drm_device *dev, |
636 | struct drm_gem_object *obj); | 639 | struct drm_gem_object *obj); |
637 | void i915_gem_free_all_phys_object(struct drm_device *dev); | 640 | void i915_gem_free_all_phys_object(struct drm_device *dev); |
641 | int i915_gem_object_get_pages(struct drm_gem_object *obj); | ||
642 | void i915_gem_object_put_pages(struct drm_gem_object *obj); | ||
638 | 643 | ||
639 | /* i915_gem_tiling.c */ | 644 | /* i915_gem_tiling.c */ |
640 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 645 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
646 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); | ||
647 | void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj); | ||
641 | 648 | ||
642 | /* i915_gem_debug.c */ | 649 | /* i915_gem_debug.c */ |
643 | void i915_gem_dump_object(struct drm_gem_object *obj, int len, | 650 | void i915_gem_dump_object(struct drm_gem_object *obj, int len, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1449b452cc63..4642115902d6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -43,8 +43,6 @@ static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | |||
43 | uint64_t offset, | 43 | uint64_t offset, |
44 | uint64_t size); | 44 | uint64_t size); |
45 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj); | 45 | static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj); |
46 | static int i915_gem_object_get_pages(struct drm_gem_object *obj); | ||
47 | static void i915_gem_object_put_pages(struct drm_gem_object *obj); | ||
48 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | 46 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); |
49 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 47 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, |
50 | unsigned alignment); | 48 | unsigned alignment); |
@@ -143,15 +141,27 @@ fast_shmem_read(struct page **pages, | |||
143 | int length) | 141 | int length) |
144 | { | 142 | { |
145 | char __iomem *vaddr; | 143 | char __iomem *vaddr; |
146 | int ret; | 144 | int unwritten; |
147 | 145 | ||
148 | vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0); | 146 | vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0); |
149 | if (vaddr == NULL) | 147 | if (vaddr == NULL) |
150 | return -ENOMEM; | 148 | return -ENOMEM; |
151 | ret = __copy_to_user_inatomic(data, vaddr + page_offset, length); | 149 | unwritten = __copy_to_user_inatomic(data, vaddr + page_offset, length); |
152 | kunmap_atomic(vaddr, KM_USER0); | 150 | kunmap_atomic(vaddr, KM_USER0); |
153 | 151 | ||
154 | return ret; | 152 | if (unwritten) |
153 | return -EFAULT; | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) | ||
159 | { | ||
160 | drm_i915_private_t *dev_priv = obj->dev->dev_private; | ||
161 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
162 | |||
163 | return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && | ||
164 | obj_priv->tiling_mode != I915_TILING_NONE; | ||
155 | } | 165 | } |
156 | 166 | ||
157 | static inline int | 167 | static inline int |
@@ -181,6 +191,64 @@ slow_shmem_copy(struct page *dst_page, | |||
181 | return 0; | 191 | return 0; |
182 | } | 192 | } |
183 | 193 | ||
194 | static inline int | ||
195 | slow_shmem_bit17_copy(struct page *gpu_page, | ||
196 | int gpu_offset, | ||
197 | struct page *cpu_page, | ||
198 | int cpu_offset, | ||
199 | int length, | ||
200 | int is_read) | ||
201 | { | ||
202 | char *gpu_vaddr, *cpu_vaddr; | ||
203 | |||
204 | /* Use the unswizzled path if this page isn't affected. */ | ||
205 | if ((page_to_phys(gpu_page) & (1 << 17)) == 0) { | ||
206 | if (is_read) | ||
207 | return slow_shmem_copy(cpu_page, cpu_offset, | ||
208 | gpu_page, gpu_offset, length); | ||
209 | else | ||
210 | return slow_shmem_copy(gpu_page, gpu_offset, | ||
211 | cpu_page, cpu_offset, length); | ||
212 | } | ||
213 | |||
214 | gpu_vaddr = kmap_atomic(gpu_page, KM_USER0); | ||
215 | if (gpu_vaddr == NULL) | ||
216 | return -ENOMEM; | ||
217 | |||
218 | cpu_vaddr = kmap_atomic(cpu_page, KM_USER1); | ||
219 | if (cpu_vaddr == NULL) { | ||
220 | kunmap_atomic(gpu_vaddr, KM_USER0); | ||
221 | return -ENOMEM; | ||
222 | } | ||
223 | |||
224 | /* Copy the data, XORing A6 with A17 (1). The user already knows he's | ||
225 | * XORing with the other bits (A9 for Y, A9 and A10 for X) | ||
226 | */ | ||
227 | while (length > 0) { | ||
228 | int cacheline_end = ALIGN(gpu_offset + 1, 64); | ||
229 | int this_length = min(cacheline_end - gpu_offset, length); | ||
230 | int swizzled_gpu_offset = gpu_offset ^ 64; | ||
231 | |||
232 | if (is_read) { | ||
233 | memcpy(cpu_vaddr + cpu_offset, | ||
234 | gpu_vaddr + swizzled_gpu_offset, | ||
235 | this_length); | ||
236 | } else { | ||
237 | memcpy(gpu_vaddr + swizzled_gpu_offset, | ||
238 | cpu_vaddr + cpu_offset, | ||
239 | this_length); | ||
240 | } | ||
241 | cpu_offset += this_length; | ||
242 | gpu_offset += this_length; | ||
243 | length -= this_length; | ||
244 | } | ||
245 | |||
246 | kunmap_atomic(cpu_vaddr, KM_USER1); | ||
247 | kunmap_atomic(gpu_vaddr, KM_USER0); | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
184 | /** | 252 | /** |
185 | * This is the fast shmem pread path, which attempts to copy_from_user directly | 253 | * This is the fast shmem pread path, which attempts to copy_from_user directly |
186 | * from the backing pages of the object to the user's address space. On a | 254 | * from the backing pages of the object to the user's address space. On a |
@@ -269,6 +337,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
269 | int page_length; | 337 | int page_length; |
270 | int ret; | 338 | int ret; |
271 | uint64_t data_ptr = args->data_ptr; | 339 | uint64_t data_ptr = args->data_ptr; |
340 | int do_bit17_swizzling; | ||
272 | 341 | ||
273 | remain = args->size; | 342 | remain = args->size; |
274 | 343 | ||
@@ -286,13 +355,15 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
286 | 355 | ||
287 | down_read(&mm->mmap_sem); | 356 | down_read(&mm->mmap_sem); |
288 | pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, | 357 | pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, |
289 | num_pages, 0, 0, user_pages, NULL); | 358 | num_pages, 1, 0, user_pages, NULL); |
290 | up_read(&mm->mmap_sem); | 359 | up_read(&mm->mmap_sem); |
291 | if (pinned_pages < num_pages) { | 360 | if (pinned_pages < num_pages) { |
292 | ret = -EFAULT; | 361 | ret = -EFAULT; |
293 | goto fail_put_user_pages; | 362 | goto fail_put_user_pages; |
294 | } | 363 | } |
295 | 364 | ||
365 | do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | ||
366 | |||
296 | mutex_lock(&dev->struct_mutex); | 367 | mutex_lock(&dev->struct_mutex); |
297 | 368 | ||
298 | ret = i915_gem_object_get_pages(obj); | 369 | ret = i915_gem_object_get_pages(obj); |
@@ -327,11 +398,20 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
327 | if ((data_page_offset + page_length) > PAGE_SIZE) | 398 | if ((data_page_offset + page_length) > PAGE_SIZE) |
328 | page_length = PAGE_SIZE - data_page_offset; | 399 | page_length = PAGE_SIZE - data_page_offset; |
329 | 400 | ||
330 | ret = slow_shmem_copy(user_pages[data_page_index], | 401 | if (do_bit17_swizzling) { |
331 | data_page_offset, | 402 | ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], |
332 | obj_priv->pages[shmem_page_index], | 403 | shmem_page_offset, |
333 | shmem_page_offset, | 404 | user_pages[data_page_index], |
334 | page_length); | 405 | data_page_offset, |
406 | page_length, | ||
407 | 1); | ||
408 | } else { | ||
409 | ret = slow_shmem_copy(user_pages[data_page_index], | ||
410 | data_page_offset, | ||
411 | obj_priv->pages[shmem_page_index], | ||
412 | shmem_page_offset, | ||
413 | page_length); | ||
414 | } | ||
335 | if (ret) | 415 | if (ret) |
336 | goto fail_put_pages; | 416 | goto fail_put_pages; |
337 | 417 | ||
@@ -383,9 +463,14 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
383 | return -EINVAL; | 463 | return -EINVAL; |
384 | } | 464 | } |
385 | 465 | ||
386 | ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv); | 466 | if (i915_gem_object_needs_bit17_swizzle(obj)) { |
387 | if (ret != 0) | ||
388 | ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv); | 467 | ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv); |
468 | } else { | ||
469 | ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv); | ||
470 | if (ret != 0) | ||
471 | ret = i915_gem_shmem_pread_slow(dev, obj, args, | ||
472 | file_priv); | ||
473 | } | ||
389 | 474 | ||
390 | drm_gem_object_unreference(obj); | 475 | drm_gem_object_unreference(obj); |
391 | 476 | ||
@@ -727,6 +812,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
727 | int page_length; | 812 | int page_length; |
728 | int ret; | 813 | int ret; |
729 | uint64_t data_ptr = args->data_ptr; | 814 | uint64_t data_ptr = args->data_ptr; |
815 | int do_bit17_swizzling; | ||
730 | 816 | ||
731 | remain = args->size; | 817 | remain = args->size; |
732 | 818 | ||
@@ -751,6 +837,8 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
751 | goto fail_put_user_pages; | 837 | goto fail_put_user_pages; |
752 | } | 838 | } |
753 | 839 | ||
840 | do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | ||
841 | |||
754 | mutex_lock(&dev->struct_mutex); | 842 | mutex_lock(&dev->struct_mutex); |
755 | 843 | ||
756 | ret = i915_gem_object_get_pages(obj); | 844 | ret = i915_gem_object_get_pages(obj); |
@@ -785,11 +873,20 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
785 | if ((data_page_offset + page_length) > PAGE_SIZE) | 873 | if ((data_page_offset + page_length) > PAGE_SIZE) |
786 | page_length = PAGE_SIZE - data_page_offset; | 874 | page_length = PAGE_SIZE - data_page_offset; |
787 | 875 | ||
788 | ret = slow_shmem_copy(obj_priv->pages[shmem_page_index], | 876 | if (do_bit17_swizzling) { |
789 | shmem_page_offset, | 877 | ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], |
790 | user_pages[data_page_index], | 878 | shmem_page_offset, |
791 | data_page_offset, | 879 | user_pages[data_page_index], |
792 | page_length); | 880 | data_page_offset, |
881 | page_length, | ||
882 | 0); | ||
883 | } else { | ||
884 | ret = slow_shmem_copy(obj_priv->pages[shmem_page_index], | ||
885 | shmem_page_offset, | ||
886 | user_pages[data_page_index], | ||
887 | data_page_offset, | ||
888 | page_length); | ||
889 | } | ||
793 | if (ret) | 890 | if (ret) |
794 | goto fail_put_pages; | 891 | goto fail_put_pages; |
795 | 892 | ||
@@ -854,6 +951,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
854 | ret = i915_gem_gtt_pwrite_slow(dev, obj, args, | 951 | ret = i915_gem_gtt_pwrite_slow(dev, obj, args, |
855 | file_priv); | 952 | file_priv); |
856 | } | 953 | } |
954 | } else if (i915_gem_object_needs_bit17_swizzle(obj)) { | ||
955 | ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file_priv); | ||
857 | } else { | 956 | } else { |
858 | ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file_priv); | 957 | ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file_priv); |
859 | if (ret == -EFAULT) { | 958 | if (ret == -EFAULT) { |
@@ -1285,7 +1384,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1285 | return 0; | 1384 | return 0; |
1286 | } | 1385 | } |
1287 | 1386 | ||
1288 | static void | 1387 | void |
1289 | i915_gem_object_put_pages(struct drm_gem_object *obj) | 1388 | i915_gem_object_put_pages(struct drm_gem_object *obj) |
1290 | { | 1389 | { |
1291 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1390 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
@@ -1297,6 +1396,9 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) | |||
1297 | if (--obj_priv->pages_refcount != 0) | 1396 | if (--obj_priv->pages_refcount != 0) |
1298 | return; | 1397 | return; |
1299 | 1398 | ||
1399 | if (obj_priv->tiling_mode != I915_TILING_NONE) | ||
1400 | i915_gem_object_save_bit_17_swizzle(obj); | ||
1401 | |||
1300 | for (i = 0; i < page_count; i++) | 1402 | for (i = 0; i < page_count; i++) |
1301 | if (obj_priv->pages[i] != NULL) { | 1403 | if (obj_priv->pages[i] != NULL) { |
1302 | if (obj_priv->dirty) | 1404 | if (obj_priv->dirty) |
@@ -1494,8 +1596,19 @@ i915_gem_retire_request(struct drm_device *dev, | |||
1494 | 1596 | ||
1495 | if (obj->write_domain != 0) | 1597 | if (obj->write_domain != 0) |
1496 | i915_gem_object_move_to_flushing(obj); | 1598 | i915_gem_object_move_to_flushing(obj); |
1497 | else | 1599 | else { |
1600 | /* Take a reference on the object so it won't be | ||
1601 | * freed while the spinlock is held. The list | ||
1602 | * protection for this spinlock is safe when breaking | ||
1603 | * the lock like this since the next thing we do | ||
1604 | * is just get the head of the list again. | ||
1605 | */ | ||
1606 | drm_gem_object_reference(obj); | ||
1498 | i915_gem_object_move_to_inactive(obj); | 1607 | i915_gem_object_move_to_inactive(obj); |
1608 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
1609 | drm_gem_object_unreference(obj); | ||
1610 | spin_lock(&dev_priv->mm.active_list_lock); | ||
1611 | } | ||
1499 | } | 1612 | } |
1500 | out: | 1613 | out: |
1501 | spin_unlock(&dev_priv->mm.active_list_lock); | 1614 | spin_unlock(&dev_priv->mm.active_list_lock); |
@@ -1884,7 +1997,7 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
1884 | return ret; | 1997 | return ret; |
1885 | } | 1998 | } |
1886 | 1999 | ||
1887 | static int | 2000 | int |
1888 | i915_gem_object_get_pages(struct drm_gem_object *obj) | 2001 | i915_gem_object_get_pages(struct drm_gem_object *obj) |
1889 | { | 2002 | { |
1890 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 2003 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
@@ -1922,6 +2035,10 @@ i915_gem_object_get_pages(struct drm_gem_object *obj) | |||
1922 | } | 2035 | } |
1923 | obj_priv->pages[i] = page; | 2036 | obj_priv->pages[i] = page; |
1924 | } | 2037 | } |
2038 | |||
2039 | if (obj_priv->tiling_mode != I915_TILING_NONE) | ||
2040 | i915_gem_object_do_bit_17_swizzle(obj); | ||
2041 | |||
1925 | return 0; | 2042 | return 0; |
1926 | } | 2043 | } |
1927 | 2044 | ||
@@ -3002,13 +3119,13 @@ i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list, | |||
3002 | drm_free(*relocs, reloc_count * sizeof(**relocs), | 3119 | drm_free(*relocs, reloc_count * sizeof(**relocs), |
3003 | DRM_MEM_DRIVER); | 3120 | DRM_MEM_DRIVER); |
3004 | *relocs = NULL; | 3121 | *relocs = NULL; |
3005 | return ret; | 3122 | return -EFAULT; |
3006 | } | 3123 | } |
3007 | 3124 | ||
3008 | reloc_index += exec_list[i].relocation_count; | 3125 | reloc_index += exec_list[i].relocation_count; |
3009 | } | 3126 | } |
3010 | 3127 | ||
3011 | return ret; | 3128 | return 0; |
3012 | } | 3129 | } |
3013 | 3130 | ||
3014 | static int | 3131 | static int |
@@ -3017,23 +3134,28 @@ i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list, | |||
3017 | struct drm_i915_gem_relocation_entry *relocs) | 3134 | struct drm_i915_gem_relocation_entry *relocs) |
3018 | { | 3135 | { |
3019 | uint32_t reloc_count = 0, i; | 3136 | uint32_t reloc_count = 0, i; |
3020 | int ret; | 3137 | int ret = 0; |
3021 | 3138 | ||
3022 | for (i = 0; i < buffer_count; i++) { | 3139 | for (i = 0; i < buffer_count; i++) { |
3023 | struct drm_i915_gem_relocation_entry __user *user_relocs; | 3140 | struct drm_i915_gem_relocation_entry __user *user_relocs; |
3141 | int unwritten; | ||
3024 | 3142 | ||
3025 | user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr; | 3143 | user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr; |
3026 | 3144 | ||
3027 | if (ret == 0) { | 3145 | unwritten = copy_to_user(user_relocs, |
3028 | ret = copy_to_user(user_relocs, | 3146 | &relocs[reloc_count], |
3029 | &relocs[reloc_count], | 3147 | exec_list[i].relocation_count * |
3030 | exec_list[i].relocation_count * | 3148 | sizeof(*relocs)); |
3031 | sizeof(*relocs)); | 3149 | |
3150 | if (unwritten) { | ||
3151 | ret = -EFAULT; | ||
3152 | goto err; | ||
3032 | } | 3153 | } |
3033 | 3154 | ||
3034 | reloc_count += exec_list[i].relocation_count; | 3155 | reloc_count += exec_list[i].relocation_count; |
3035 | } | 3156 | } |
3036 | 3157 | ||
3158 | err: | ||
3037 | drm_free(relocs, reloc_count * sizeof(*relocs), DRM_MEM_DRIVER); | 3159 | drm_free(relocs, reloc_count * sizeof(*relocs), DRM_MEM_DRIVER); |
3038 | 3160 | ||
3039 | return ret; | 3161 | return ret; |
@@ -3243,7 +3365,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
3243 | exec_offset = exec_list[args->buffer_count - 1].offset; | 3365 | exec_offset = exec_list[args->buffer_count - 1].offset; |
3244 | 3366 | ||
3245 | #if WATCH_EXEC | 3367 | #if WATCH_EXEC |
3246 | i915_gem_dump_object(object_list[args->buffer_count - 1], | 3368 | i915_gem_dump_object(batch_obj, |
3247 | args->batch_len, | 3369 | args->batch_len, |
3248 | __func__, | 3370 | __func__, |
3249 | ~0); | 3371 | ~0); |
@@ -3308,10 +3430,12 @@ err: | |||
3308 | (uintptr_t) args->buffers_ptr, | 3430 | (uintptr_t) args->buffers_ptr, |
3309 | exec_list, | 3431 | exec_list, |
3310 | sizeof(*exec_list) * args->buffer_count); | 3432 | sizeof(*exec_list) * args->buffer_count); |
3311 | if (ret) | 3433 | if (ret) { |
3434 | ret = -EFAULT; | ||
3312 | DRM_ERROR("failed to copy %d exec entries " | 3435 | DRM_ERROR("failed to copy %d exec entries " |
3313 | "back to user (%d)\n", | 3436 | "back to user (%d)\n", |
3314 | args->buffer_count, ret); | 3437 | args->buffer_count, ret); |
3438 | } | ||
3315 | } | 3439 | } |
3316 | 3440 | ||
3317 | /* Copy the updated relocations out regardless of current error | 3441 | /* Copy the updated relocations out regardless of current error |
@@ -3593,6 +3717,7 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
3593 | i915_gem_free_mmap_offset(obj); | 3717 | i915_gem_free_mmap_offset(obj); |
3594 | 3718 | ||
3595 | drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); | 3719 | drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); |
3720 | kfree(obj_priv->bit_17); | ||
3596 | drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); | 3721 | drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); |
3597 | } | 3722 | } |
3598 | 3723 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c index a1ac0c5e7307..986f1082c596 100644 --- a/drivers/gpu/drm/i915/i915_gem_debugfs.c +++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c | |||
@@ -234,6 +234,96 @@ static int i915_hws_info(struct seq_file *m, void *data) | |||
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
236 | 236 | ||
237 | static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count) | ||
238 | { | ||
239 | int page, i; | ||
240 | uint32_t *mem; | ||
241 | |||
242 | for (page = 0; page < page_count; page++) { | ||
243 | mem = kmap(pages[page]); | ||
244 | for (i = 0; i < PAGE_SIZE; i += 4) | ||
245 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); | ||
246 | kunmap(pages[page]); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | static int i915_batchbuffer_info(struct seq_file *m, void *data) | ||
251 | { | ||
252 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
253 | struct drm_device *dev = node->minor->dev; | ||
254 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
255 | struct drm_gem_object *obj; | ||
256 | struct drm_i915_gem_object *obj_priv; | ||
257 | int ret; | ||
258 | |||
259 | spin_lock(&dev_priv->mm.active_list_lock); | ||
260 | |||
261 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | ||
262 | obj = obj_priv->obj; | ||
263 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { | ||
264 | ret = i915_gem_object_get_pages(obj); | ||
265 | if (ret) { | ||
266 | DRM_ERROR("Failed to get pages: %d\n", ret); | ||
267 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset); | ||
272 | i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE); | ||
273 | |||
274 | i915_gem_object_put_pages(obj); | ||
275 | } | ||
276 | } | ||
277 | |||
278 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int i915_ringbuffer_data(struct seq_file *m, void *data) | ||
284 | { | ||
285 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
286 | struct drm_device *dev = node->minor->dev; | ||
287 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
288 | u8 *virt; | ||
289 | uint32_t *ptr, off; | ||
290 | |||
291 | if (!dev_priv->ring.ring_obj) { | ||
292 | seq_printf(m, "No ringbuffer setup\n"); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | virt = dev_priv->ring.virtual_start; | ||
297 | |||
298 | for (off = 0; off < dev_priv->ring.Size; off += 4) { | ||
299 | ptr = (uint32_t *)(virt + off); | ||
300 | seq_printf(m, "%08x : %08x\n", off, *ptr); | ||
301 | } | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static int i915_ringbuffer_info(struct seq_file *m, void *data) | ||
307 | { | ||
308 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
309 | struct drm_device *dev = node->minor->dev; | ||
310 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
311 | unsigned int head, tail, mask; | ||
312 | |||
313 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
314 | tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | ||
315 | mask = dev_priv->ring.tail_mask; | ||
316 | |||
317 | seq_printf(m, "RingHead : %08x\n", head); | ||
318 | seq_printf(m, "RingTail : %08x\n", tail); | ||
319 | seq_printf(m, "RingMask : %08x\n", mask); | ||
320 | seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); | ||
321 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | |||
237 | static struct drm_info_list i915_gem_debugfs_list[] = { | 327 | static struct drm_info_list i915_gem_debugfs_list[] = { |
238 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 328 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
239 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, | 329 | {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, |
@@ -243,6 +333,9 @@ static struct drm_info_list i915_gem_debugfs_list[] = { | |||
243 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, | 333 | {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, |
244 | {"i915_gem_interrupt", i915_interrupt_info, 0}, | 334 | {"i915_gem_interrupt", i915_interrupt_info, 0}, |
245 | {"i915_gem_hws", i915_hws_info, 0}, | 335 | {"i915_gem_hws", i915_hws_info, 0}, |
336 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, | ||
337 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, | ||
338 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | ||
246 | }; | 339 | }; |
247 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) | 340 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) |
248 | 341 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 6be3f927c86a..f27e523c764f 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -25,6 +25,8 @@ | |||
25 | * | 25 | * |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include "linux/string.h" | ||
29 | #include "linux/bitops.h" | ||
28 | #include "drmP.h" | 30 | #include "drmP.h" |
29 | #include "drm.h" | 31 | #include "drm.h" |
30 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
@@ -127,8 +129,8 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
127 | swizzle_y = I915_BIT_6_SWIZZLE_9_11; | 129 | swizzle_y = I915_BIT_6_SWIZZLE_9_11; |
128 | } else { | 130 | } else { |
129 | /* Bit 17 swizzling by the CPU in addition. */ | 131 | /* Bit 17 swizzling by the CPU in addition. */ |
130 | swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; | 132 | swizzle_x = I915_BIT_6_SWIZZLE_9_10_17; |
131 | swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | 133 | swizzle_y = I915_BIT_6_SWIZZLE_9_17; |
132 | } | 134 | } |
133 | break; | 135 | break; |
134 | } | 136 | } |
@@ -288,6 +290,19 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
288 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; | 290 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; |
289 | else | 291 | else |
290 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; | 292 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y; |
293 | |||
294 | /* Hide bit 17 swizzling from the user. This prevents old Mesa | ||
295 | * from aborting the application on sw fallbacks to bit 17, | ||
296 | * and we use the pread/pwrite bit17 paths to swizzle for it. | ||
297 | * If there was a user that was relying on the swizzle | ||
298 | * information for drm_intel_bo_map()ed reads/writes this would | ||
299 | * break it, but we don't have any of those. | ||
300 | */ | ||
301 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) | ||
302 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9; | ||
303 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) | ||
304 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; | ||
305 | |||
291 | /* If we can't handle the swizzling, make it untiled. */ | 306 | /* If we can't handle the swizzling, make it untiled. */ |
292 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) { | 307 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) { |
293 | args->tiling_mode = I915_TILING_NONE; | 308 | args->tiling_mode = I915_TILING_NONE; |
@@ -354,8 +369,100 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, | |||
354 | DRM_ERROR("unknown tiling mode\n"); | 369 | DRM_ERROR("unknown tiling mode\n"); |
355 | } | 370 | } |
356 | 371 | ||
372 | /* Hide bit 17 from the user -- see comment in i915_gem_set_tiling */ | ||
373 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_17) | ||
374 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9; | ||
375 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) | ||
376 | args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; | ||
377 | |||
357 | drm_gem_object_unreference(obj); | 378 | drm_gem_object_unreference(obj); |
358 | mutex_unlock(&dev->struct_mutex); | 379 | mutex_unlock(&dev->struct_mutex); |
359 | 380 | ||
360 | return 0; | 381 | return 0; |
361 | } | 382 | } |
383 | |||
384 | /** | ||
385 | * Swap every 64 bytes of this page around, to account for it having a new | ||
386 | * bit 17 of its physical address and therefore being interpreted differently | ||
387 | * by the GPU. | ||
388 | */ | ||
389 | static int | ||
390 | i915_gem_swizzle_page(struct page *page) | ||
391 | { | ||
392 | char *vaddr; | ||
393 | int i; | ||
394 | char temp[64]; | ||
395 | |||
396 | vaddr = kmap(page); | ||
397 | if (vaddr == NULL) | ||
398 | return -ENOMEM; | ||
399 | |||
400 | for (i = 0; i < PAGE_SIZE; i += 128) { | ||
401 | memcpy(temp, &vaddr[i], 64); | ||
402 | memcpy(&vaddr[i], &vaddr[i + 64], 64); | ||
403 | memcpy(&vaddr[i + 64], temp, 64); | ||
404 | } | ||
405 | |||
406 | kunmap(page); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | void | ||
412 | i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj) | ||
413 | { | ||
414 | struct drm_device *dev = obj->dev; | ||
415 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
416 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
417 | int page_count = obj->size >> PAGE_SHIFT; | ||
418 | int i; | ||
419 | |||
420 | if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17) | ||
421 | return; | ||
422 | |||
423 | if (obj_priv->bit_17 == NULL) | ||
424 | return; | ||
425 | |||
426 | for (i = 0; i < page_count; i++) { | ||
427 | char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17; | ||
428 | if ((new_bit_17 & 0x1) != | ||
429 | (test_bit(i, obj_priv->bit_17) != 0)) { | ||
430 | int ret = i915_gem_swizzle_page(obj_priv->pages[i]); | ||
431 | if (ret != 0) { | ||
432 | DRM_ERROR("Failed to swizzle page\n"); | ||
433 | return; | ||
434 | } | ||
435 | set_page_dirty(obj_priv->pages[i]); | ||
436 | } | ||
437 | } | ||
438 | } | ||
439 | |||
440 | void | ||
441 | i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj) | ||
442 | { | ||
443 | struct drm_device *dev = obj->dev; | ||
444 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
445 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
446 | int page_count = obj->size >> PAGE_SHIFT; | ||
447 | int i; | ||
448 | |||
449 | if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17) | ||
450 | return; | ||
451 | |||
452 | if (obj_priv->bit_17 == NULL) { | ||
453 | obj_priv->bit_17 = kmalloc(BITS_TO_LONGS(page_count) * | ||
454 | sizeof(long), GFP_KERNEL); | ||
455 | if (obj_priv->bit_17 == NULL) { | ||
456 | DRM_ERROR("Failed to allocate memory for bit 17 " | ||
457 | "record\n"); | ||
458 | return; | ||
459 | } | ||
460 | } | ||
461 | |||
462 | for (i = 0; i < page_count; i++) { | ||
463 | if (page_to_phys(obj_priv->pages[i]) & (1 << 17)) | ||
464 | __set_bit(i, obj_priv->bit_17); | ||
465 | else | ||
466 | __clear_bit(i, obj_priv->bit_17); | ||
467 | } | ||
468 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 64773ce52964..c2c8e95ff14d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -367,6 +367,7 @@ static const intel_limit_t intel_limits[] = { | |||
367 | .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, | 367 | .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, |
368 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 368 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
369 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 369 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
370 | .find_pll = intel_find_best_PLL, | ||
370 | }, | 371 | }, |
371 | { /* INTEL_LIMIT_IGD_LVDS */ | 372 | { /* INTEL_LIMIT_IGD_LVDS */ |
372 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 373 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
@@ -380,6 +381,7 @@ static const intel_limit_t intel_limits[] = { | |||
380 | /* IGD only supports single-channel mode. */ | 381 | /* IGD only supports single-channel mode. */ |
381 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 382 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
382 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, | 383 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, |
384 | .find_pll = intel_find_best_PLL, | ||
383 | }, | 385 | }, |
384 | 386 | ||
385 | }; | 387 | }; |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index b7f0ebe9f810..3e094beecb99 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -864,8 +864,8 @@ static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3) | |||
864 | 864 | ||
865 | static struct sysrq_key_op sysrq_intelfb_restore_op = { | 865 | static struct sysrq_key_op sysrq_intelfb_restore_op = { |
866 | .handler = intelfb_sysrq, | 866 | .handler = intelfb_sysrq, |
867 | .help_msg = "force fb", | 867 | .help_msg = "force-fb(G)", |
868 | .action_msg = "force restore of fb console", | 868 | .action_msg = "Restore framebuffer console", |
869 | }; | 869 | }; |
870 | 870 | ||
871 | int intelfb_probe(struct drm_device *dev) | 871 | int intelfb_probe(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index b06a4a3ff08d..550374225388 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -38,7 +38,7 @@ | |||
38 | struct intel_hdmi_priv { | 38 | struct intel_hdmi_priv { |
39 | u32 sdvox_reg; | 39 | u32 sdvox_reg; |
40 | u32 save_SDVOX; | 40 | u32 save_SDVOX; |
41 | int has_hdmi_sink; | 41 | bool has_hdmi_sink; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 44 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
@@ -128,6 +128,22 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
128 | return true; | 128 | return true; |
129 | } | 129 | } |
130 | 130 | ||
131 | static void | ||
132 | intel_hdmi_sink_detect(struct drm_connector *connector) | ||
133 | { | ||
134 | struct intel_output *intel_output = to_intel_output(connector); | ||
135 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | ||
136 | struct edid *edid = NULL; | ||
137 | |||
138 | edid = drm_get_edid(&intel_output->base, | ||
139 | &intel_output->ddc_bus->adapter); | ||
140 | if (edid != NULL) { | ||
141 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | ||
142 | kfree(edid); | ||
143 | intel_output->base.display_info.raw_edid = NULL; | ||
144 | } | ||
145 | } | ||
146 | |||
131 | static enum drm_connector_status | 147 | static enum drm_connector_status |
132 | intel_hdmi_detect(struct drm_connector *connector) | 148 | intel_hdmi_detect(struct drm_connector *connector) |
133 | { | 149 | { |
@@ -158,9 +174,10 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
158 | return connector_status_unknown; | 174 | return connector_status_unknown; |
159 | } | 175 | } |
160 | 176 | ||
161 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) | 177 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) { |
178 | intel_hdmi_sink_detect(connector); | ||
162 | return connector_status_connected; | 179 | return connector_status_connected; |
163 | else | 180 | } else |
164 | return connector_status_disconnected; | 181 | return connector_status_disconnected; |
165 | } | 182 | } |
166 | 183 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 7b31f55f55c8..9913651c1e17 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1357,6 +1357,23 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | |||
1357 | intel_sdvo_read_response(intel_output, &response, 2); | 1357 | intel_sdvo_read_response(intel_output, &response, 2); |
1358 | } | 1358 | } |
1359 | 1359 | ||
1360 | static void | ||
1361 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | ||
1362 | { | ||
1363 | struct intel_output *intel_output = to_intel_output(connector); | ||
1364 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1365 | struct edid *edid = NULL; | ||
1366 | |||
1367 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1368 | edid = drm_get_edid(&intel_output->base, | ||
1369 | &intel_output->ddc_bus->adapter); | ||
1370 | if (edid != NULL) { | ||
1371 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | ||
1372 | kfree(edid); | ||
1373 | intel_output->base.display_info.raw_edid = NULL; | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1360 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1377 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
1361 | { | 1378 | { |
1362 | u8 response[2]; | 1379 | u8 response[2]; |
@@ -1371,9 +1388,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1371 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1388 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1372 | return connector_status_unknown; | 1389 | return connector_status_unknown; |
1373 | 1390 | ||
1374 | if ((response[0] != 0) || (response[1] != 0)) | 1391 | if ((response[0] != 0) || (response[1] != 0)) { |
1392 | intel_sdvo_hdmi_sink_detect(connector); | ||
1375 | return connector_status_connected; | 1393 | return connector_status_connected; |
1376 | else | 1394 | } else |
1377 | return connector_status_disconnected; | 1395 | return connector_status_disconnected; |
1378 | } | 1396 | } |
1379 | 1397 | ||
diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c index 7a339dba6a69..bfb92d283260 100644 --- a/drivers/gpu/drm/via/via_dma.c +++ b/drivers/gpu/drm/via/via_dma.c | |||
@@ -481,11 +481,13 @@ static int via_wait_idle(drm_via_private_t * dev_priv) | |||
481 | { | 481 | { |
482 | int count = 10000000; | 482 | int count = 10000000; |
483 | 483 | ||
484 | while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && count--); | 484 | while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && --count) |
485 | ; | ||
485 | 486 | ||
486 | while (count-- && (VIA_READ(VIA_REG_STATUS) & | 487 | while (count && (VIA_READ(VIA_REG_STATUS) & |
487 | (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | | 488 | (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | |
488 | VIA_3D_ENG_BUSY))) ; | 489 | VIA_3D_ENG_BUSY))) |
490 | --count; | ||
489 | return count; | 491 | return count; |
490 | } | 492 | } |
491 | 493 | ||
@@ -705,7 +707,7 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * | |||
705 | switch (d_siz->func) { | 707 | switch (d_siz->func) { |
706 | case VIA_CMDBUF_SPACE: | 708 | case VIA_CMDBUF_SPACE: |
707 | while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size) | 709 | while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size) |
708 | && count--) { | 710 | && --count) { |
709 | if (!d_siz->wait) { | 711 | if (!d_siz->wait) { |
710 | break; | 712 | break; |
711 | } | 713 | } |
@@ -717,7 +719,7 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * | |||
717 | break; | 719 | break; |
718 | case VIA_CMDBUF_LAG: | 720 | case VIA_CMDBUF_LAG: |
719 | while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size) | 721 | while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size) |
720 | && count--) { | 722 | && --count) { |
721 | if (!d_siz->wait) { | 723 | if (!d_siz->wait) { |
722 | break; | 724 | break; |
723 | } | 725 | } |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 0e8a9185f676..d73f5f473e38 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -692,6 +692,16 @@ config SENSORS_PCF8591 | |||
692 | These devices are hard to detect and rarely found on mainstream | 692 | These devices are hard to detect and rarely found on mainstream |
693 | hardware. If unsure, say N. | 693 | hardware. If unsure, say N. |
694 | 694 | ||
695 | config SENSORS_SHT15 | ||
696 | tristate "Sensiron humidity and temperature sensors. SHT15 and compat." | ||
697 | depends on GENERIC_GPIO | ||
698 | help | ||
699 | If you say yes here you get support for the Sensiron SHT10, SHT11, | ||
700 | SHT15, SHT71, SHT75 humidity and temperature sensors. | ||
701 | |||
702 | This driver can also be built as a module. If so, the module | ||
703 | will be called sht15. | ||
704 | |||
695 | config SENSORS_SIS5595 | 705 | config SENSORS_SIS5595 |
696 | tristate "Silicon Integrated Systems Corp. SiS5595" | 706 | tristate "Silicon Integrated Systems Corp. SiS5595" |
697 | depends on PCI | 707 | depends on PCI |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 1d3757837b4f..0ae26984ba45 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -76,6 +76,7 @@ obj-$(CONFIG_SENSORS_MAX6650) += max6650.o | |||
76 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | 76 | obj-$(CONFIG_SENSORS_PC87360) += pc87360.o |
77 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o | 77 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o |
78 | obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o | 78 | obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o |
79 | obj-$(CONFIG_SENSORS_SHT15) += sht15.o | ||
79 | obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o | 80 | obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o |
80 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o | 81 | obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o |
81 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o | 82 | obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o |
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index 55d3dc565be6..abca7e9f953b 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/wait.h> | 34 | #include <linux/wait.h> |
35 | #include <linux/poll.h> | 35 | #include <linux/poll.h> |
36 | #include <linux/freezer.h> | 36 | #include <linux/freezer.h> |
37 | #include <linux/version.h> | ||
38 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
39 | #include <linux/leds.h> | 38 | #include <linux/leds.h> |
40 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c new file mode 100644 index 000000000000..6cbdc2fea734 --- /dev/null +++ b/drivers/hwmon/sht15.c | |||
@@ -0,0 +1,692 @@ | |||
1 | /* | ||
2 | * sht15.c - support for the SHT15 Temperature and Humidity Sensor | ||
3 | * | ||
4 | * Copyright (c) 2009 Jonathan Cameron | ||
5 | * | ||
6 | * Copyright (c) 2007 Wouter Horre | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * Currently ignoring checksum on readings. | ||
13 | * Default resolution only (14bit temp, 12bit humidity) | ||
14 | * Ignoring battery status. | ||
15 | * Heater not enabled. | ||
16 | * Timings are all conservative. | ||
17 | * | ||
18 | * Data sheet available (1/2009) at | ||
19 | * http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf | ||
20 | * | ||
21 | * Regulator supply name = vcc | ||
22 | */ | ||
23 | |||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/hwmon.h> | ||
30 | #include <linux/hwmon-sysfs.h> | ||
31 | #include <linux/mutex.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/jiffies.h> | ||
35 | #include <linux/err.h> | ||
36 | #include <linux/sht15.h> | ||
37 | #include <linux/regulator/consumer.h> | ||
38 | #include <asm/atomic.h> | ||
39 | |||
40 | #define SHT15_MEASURE_TEMP 3 | ||
41 | #define SHT15_MEASURE_RH 5 | ||
42 | |||
43 | #define SHT15_READING_NOTHING 0 | ||
44 | #define SHT15_READING_TEMP 1 | ||
45 | #define SHT15_READING_HUMID 2 | ||
46 | |||
47 | /* Min timings in nsecs */ | ||
48 | #define SHT15_TSCKL 100 /* clock low */ | ||
49 | #define SHT15_TSCKH 100 /* clock high */ | ||
50 | #define SHT15_TSU 150 /* data setup time */ | ||
51 | |||
52 | /** | ||
53 | * struct sht15_temppair - elements of voltage dependant temp calc | ||
54 | * @vdd: supply voltage in microvolts | ||
55 | * @d1: see data sheet | ||
56 | */ | ||
57 | struct sht15_temppair { | ||
58 | int vdd; /* microvolts */ | ||
59 | int d1; | ||
60 | }; | ||
61 | |||
62 | /* Table 9 from data sheet - relates temperature calculation | ||
63 | * to supply voltage. | ||
64 | */ | ||
65 | static const struct sht15_temppair temppoints[] = { | ||
66 | { 2500000, -39400 }, | ||
67 | { 3000000, -39600 }, | ||
68 | { 3500000, -39700 }, | ||
69 | { 4000000, -39800 }, | ||
70 | { 5000000, -40100 }, | ||
71 | }; | ||
72 | |||
73 | /** | ||
74 | * struct sht15_data - device instance specific data | ||
75 | * @pdata: platform data (gpio's etc) | ||
76 | * @read_work: bh of interrupt handler | ||
77 | * @wait_queue: wait queue for getting values from device | ||
78 | * @val_temp: last temperature value read from device | ||
79 | * @val_humid: last humidity value read from device | ||
80 | * @flag: status flag used to identify what the last request was | ||
81 | * @valid: are the current stored values valid (start condition) | ||
82 | * @last_updat: time of last update | ||
83 | * @read_lock: mutex to ensure only one read in progress | ||
84 | * at a time. | ||
85 | * @dev: associate device structure | ||
86 | * @hwmon_dev: device associated with hwmon subsystem | ||
87 | * @reg: associated regulator (if specified) | ||
88 | * @nb: notifier block to handle notifications of voltage changes | ||
89 | * @supply_uV: local copy of supply voltage used to allow | ||
90 | * use of regulator consumer if available | ||
91 | * @supply_uV_valid: indicates that an updated value has not yet | ||
92 | * been obtained from the regulator and so any calculations | ||
93 | * based upon it will be invalid. | ||
94 | * @update_supply_work: work struct that is used to update the supply_uV | ||
95 | * @interrupt_handled: flag used to indicate a hander has been scheduled | ||
96 | */ | ||
97 | struct sht15_data { | ||
98 | struct sht15_platform_data *pdata; | ||
99 | struct work_struct read_work; | ||
100 | wait_queue_head_t wait_queue; | ||
101 | uint16_t val_temp; | ||
102 | uint16_t val_humid; | ||
103 | u8 flag; | ||
104 | u8 valid; | ||
105 | unsigned long last_updat; | ||
106 | struct mutex read_lock; | ||
107 | struct device *dev; | ||
108 | struct device *hwmon_dev; | ||
109 | struct regulator *reg; | ||
110 | struct notifier_block nb; | ||
111 | int supply_uV; | ||
112 | int supply_uV_valid; | ||
113 | struct work_struct update_supply_work; | ||
114 | atomic_t interrupt_handled; | ||
115 | }; | ||
116 | |||
117 | /** | ||
118 | * sht15_connection_reset() - reset the comms interface | ||
119 | * @data: sht15 specific data | ||
120 | * | ||
121 | * This implements section 3.4 of the data sheet | ||
122 | */ | ||
123 | static void sht15_connection_reset(struct sht15_data *data) | ||
124 | { | ||
125 | int i; | ||
126 | gpio_direction_output(data->pdata->gpio_data, 1); | ||
127 | ndelay(SHT15_TSCKL); | ||
128 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
129 | ndelay(SHT15_TSCKL); | ||
130 | for (i = 0; i < 9; ++i) { | ||
131 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
132 | ndelay(SHT15_TSCKH); | ||
133 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
134 | ndelay(SHT15_TSCKL); | ||
135 | } | ||
136 | } | ||
137 | /** | ||
138 | * sht15_send_bit() - send an individual bit to the device | ||
139 | * @data: device state data | ||
140 | * @val: value of bit to be sent | ||
141 | **/ | ||
142 | static inline void sht15_send_bit(struct sht15_data *data, int val) | ||
143 | { | ||
144 | |||
145 | gpio_set_value(data->pdata->gpio_data, val); | ||
146 | ndelay(SHT15_TSU); | ||
147 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
148 | ndelay(SHT15_TSCKH); | ||
149 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
150 | ndelay(SHT15_TSCKL); /* clock low time */ | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * sht15_transmission_start() - specific sequence for new transmission | ||
155 | * | ||
156 | * @data: device state data | ||
157 | * Timings for this are not documented on the data sheet, so very | ||
158 | * conservative ones used in implementation. This implements | ||
159 | * figure 12 on the data sheet. | ||
160 | **/ | ||
161 | static void sht15_transmission_start(struct sht15_data *data) | ||
162 | { | ||
163 | /* ensure data is high and output */ | ||
164 | gpio_direction_output(data->pdata->gpio_data, 1); | ||
165 | ndelay(SHT15_TSU); | ||
166 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
167 | ndelay(SHT15_TSCKL); | ||
168 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
169 | ndelay(SHT15_TSCKH); | ||
170 | gpio_set_value(data->pdata->gpio_data, 0); | ||
171 | ndelay(SHT15_TSU); | ||
172 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
173 | ndelay(SHT15_TSCKL); | ||
174 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
175 | ndelay(SHT15_TSCKH); | ||
176 | gpio_set_value(data->pdata->gpio_data, 1); | ||
177 | ndelay(SHT15_TSU); | ||
178 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
179 | ndelay(SHT15_TSCKL); | ||
180 | } | ||
181 | /** | ||
182 | * sht15_send_byte() - send a single byte to the device | ||
183 | * @data: device state | ||
184 | * @byte: value to be sent | ||
185 | **/ | ||
186 | static void sht15_send_byte(struct sht15_data *data, u8 byte) | ||
187 | { | ||
188 | int i; | ||
189 | for (i = 0; i < 8; i++) { | ||
190 | sht15_send_bit(data, !!(byte & 0x80)); | ||
191 | byte <<= 1; | ||
192 | } | ||
193 | } | ||
194 | /** | ||
195 | * sht15_wait_for_response() - checks for ack from device | ||
196 | * @data: device state | ||
197 | **/ | ||
198 | static int sht15_wait_for_response(struct sht15_data *data) | ||
199 | { | ||
200 | gpio_direction_input(data->pdata->gpio_data); | ||
201 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
202 | ndelay(SHT15_TSCKH); | ||
203 | if (gpio_get_value(data->pdata->gpio_data)) { | ||
204 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
205 | dev_err(data->dev, "Command not acknowledged\n"); | ||
206 | sht15_connection_reset(data); | ||
207 | return -EIO; | ||
208 | } | ||
209 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
210 | ndelay(SHT15_TSCKL); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * sht15_send_cmd() - Sends a command to the device. | ||
216 | * @data: device state | ||
217 | * @cmd: command byte to be sent | ||
218 | * | ||
219 | * On entry, sck is output low, data is output pull high | ||
220 | * and the interrupt disabled. | ||
221 | **/ | ||
222 | static int sht15_send_cmd(struct sht15_data *data, u8 cmd) | ||
223 | { | ||
224 | int ret = 0; | ||
225 | sht15_transmission_start(data); | ||
226 | sht15_send_byte(data, cmd); | ||
227 | ret = sht15_wait_for_response(data); | ||
228 | return ret; | ||
229 | } | ||
230 | /** | ||
231 | * sht15_update_single_val() - get a new value from device | ||
232 | * @data: device instance specific data | ||
233 | * @command: command sent to request value | ||
234 | * @timeout_msecs: timeout after which comms are assumed | ||
235 | * to have failed are reset. | ||
236 | **/ | ||
237 | static inline int sht15_update_single_val(struct sht15_data *data, | ||
238 | int command, | ||
239 | int timeout_msecs) | ||
240 | { | ||
241 | int ret; | ||
242 | ret = sht15_send_cmd(data, command); | ||
243 | if (ret) | ||
244 | return ret; | ||
245 | |||
246 | gpio_direction_input(data->pdata->gpio_data); | ||
247 | atomic_set(&data->interrupt_handled, 0); | ||
248 | |||
249 | enable_irq(gpio_to_irq(data->pdata->gpio_data)); | ||
250 | if (gpio_get_value(data->pdata->gpio_data) == 0) { | ||
251 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); | ||
252 | /* Only relevant if the interrupt hasn't occured. */ | ||
253 | if (!atomic_read(&data->interrupt_handled)) | ||
254 | schedule_work(&data->read_work); | ||
255 | } | ||
256 | ret = wait_event_timeout(data->wait_queue, | ||
257 | (data->flag == SHT15_READING_NOTHING), | ||
258 | msecs_to_jiffies(timeout_msecs)); | ||
259 | if (ret == 0) {/* timeout occurred */ | ||
260 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));; | ||
261 | sht15_connection_reset(data); | ||
262 | return -ETIME; | ||
263 | } | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | /** | ||
268 | * sht15_update_vals() - get updated readings from device if too old | ||
269 | * @data: device state | ||
270 | **/ | ||
271 | static int sht15_update_vals(struct sht15_data *data) | ||
272 | { | ||
273 | int ret = 0; | ||
274 | int timeout = HZ; | ||
275 | |||
276 | mutex_lock(&data->read_lock); | ||
277 | if (time_after(jiffies, data->last_updat + timeout) | ||
278 | || !data->valid) { | ||
279 | data->flag = SHT15_READING_HUMID; | ||
280 | ret = sht15_update_single_val(data, SHT15_MEASURE_RH, 160); | ||
281 | if (ret) | ||
282 | goto error_ret; | ||
283 | data->flag = SHT15_READING_TEMP; | ||
284 | ret = sht15_update_single_val(data, SHT15_MEASURE_TEMP, 400); | ||
285 | if (ret) | ||
286 | goto error_ret; | ||
287 | data->valid = 1; | ||
288 | data->last_updat = jiffies; | ||
289 | } | ||
290 | error_ret: | ||
291 | mutex_unlock(&data->read_lock); | ||
292 | |||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * sht15_calc_temp() - convert the raw reading to a temperature | ||
298 | * @data: device state | ||
299 | * | ||
300 | * As per section 4.3 of the data sheet. | ||
301 | **/ | ||
302 | static inline int sht15_calc_temp(struct sht15_data *data) | ||
303 | { | ||
304 | int d1 = 0; | ||
305 | int i; | ||
306 | |||
307 | for (i = 1; i < ARRAY_SIZE(temppoints) - 1; i++) | ||
308 | /* Find pointer to interpolate */ | ||
309 | if (data->supply_uV > temppoints[i - 1].vdd) { | ||
310 | d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd) | ||
311 | * (temppoints[i].d1 - temppoints[i - 1].d1) | ||
312 | / (temppoints[i].vdd - temppoints[i - 1].vdd) | ||
313 | + temppoints[i - 1].d1; | ||
314 | break; | ||
315 | } | ||
316 | |||
317 | return data->val_temp*10 + d1; | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * sht15_calc_humid() - using last temperature convert raw to humid | ||
322 | * @data: device state | ||
323 | * | ||
324 | * This is the temperature compensated version as per section 4.2 of | ||
325 | * the data sheet. | ||
326 | **/ | ||
327 | static inline int sht15_calc_humid(struct sht15_data *data) | ||
328 | { | ||
329 | int RHlinear; /* milli percent */ | ||
330 | int temp = sht15_calc_temp(data); | ||
331 | |||
332 | const int c1 = -4; | ||
333 | const int c2 = 40500; /* x 10 ^ -6 */ | ||
334 | const int c3 = 2800; /* x10 ^ -9 */ | ||
335 | |||
336 | RHlinear = c1*1000 | ||
337 | + c2 * data->val_humid/1000 | ||
338 | + (data->val_humid * data->val_humid * c3)/1000000; | ||
339 | return (temp - 25000) * (10000 + 800 * data->val_humid) | ||
340 | / 1000000 + RHlinear; | ||
341 | } | ||
342 | |||
343 | static ssize_t sht15_show_temp(struct device *dev, | ||
344 | struct device_attribute *attr, | ||
345 | char *buf) | ||
346 | { | ||
347 | int ret; | ||
348 | struct sht15_data *data = dev_get_drvdata(dev); | ||
349 | |||
350 | /* Technically no need to read humidity as well */ | ||
351 | ret = sht15_update_vals(data); | ||
352 | |||
353 | return ret ? ret : sprintf(buf, "%d\n", | ||
354 | sht15_calc_temp(data)); | ||
355 | } | ||
356 | |||
357 | static ssize_t sht15_show_humidity(struct device *dev, | ||
358 | struct device_attribute *attr, | ||
359 | char *buf) | ||
360 | { | ||
361 | int ret; | ||
362 | struct sht15_data *data = dev_get_drvdata(dev); | ||
363 | |||
364 | ret = sht15_update_vals(data); | ||
365 | |||
366 | return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data)); | ||
367 | |||
368 | }; | ||
369 | static ssize_t show_name(struct device *dev, | ||
370 | struct device_attribute *attr, | ||
371 | char *buf) | ||
372 | { | ||
373 | struct platform_device *pdev = to_platform_device(dev); | ||
374 | return sprintf(buf, "%s\n", pdev->name); | ||
375 | } | ||
376 | |||
377 | static SENSOR_DEVICE_ATTR(temp1_input, | ||
378 | S_IRUGO, sht15_show_temp, | ||
379 | NULL, 0); | ||
380 | static SENSOR_DEVICE_ATTR(humidity1_input, | ||
381 | S_IRUGO, sht15_show_humidity, | ||
382 | NULL, 0); | ||
383 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
384 | static struct attribute *sht15_attrs[] = { | ||
385 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
386 | &sensor_dev_attr_humidity1_input.dev_attr.attr, | ||
387 | &dev_attr_name.attr, | ||
388 | NULL, | ||
389 | }; | ||
390 | |||
391 | static const struct attribute_group sht15_attr_group = { | ||
392 | .attrs = sht15_attrs, | ||
393 | }; | ||
394 | |||
395 | static irqreturn_t sht15_interrupt_fired(int irq, void *d) | ||
396 | { | ||
397 | struct sht15_data *data = d; | ||
398 | /* First disable the interrupt */ | ||
399 | disable_irq_nosync(irq); | ||
400 | atomic_inc(&data->interrupt_handled); | ||
401 | /* Then schedule a reading work struct */ | ||
402 | if (data->flag != SHT15_READING_NOTHING) | ||
403 | schedule_work(&data->read_work); | ||
404 | return IRQ_HANDLED; | ||
405 | } | ||
406 | |||
407 | /* Each byte of data is acknowledged by pulling the data line | ||
408 | * low for one clock pulse. | ||
409 | */ | ||
410 | static void sht15_ack(struct sht15_data *data) | ||
411 | { | ||
412 | gpio_direction_output(data->pdata->gpio_data, 0); | ||
413 | ndelay(SHT15_TSU); | ||
414 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
415 | ndelay(SHT15_TSU); | ||
416 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
417 | ndelay(SHT15_TSU); | ||
418 | gpio_set_value(data->pdata->gpio_data, 1); | ||
419 | |||
420 | gpio_direction_input(data->pdata->gpio_data); | ||
421 | } | ||
422 | /** | ||
423 | * sht15_end_transmission() - notify device of end of transmission | ||
424 | * @data: device state | ||
425 | * | ||
426 | * This is basically a NAK. (single clock pulse, data high) | ||
427 | **/ | ||
428 | static void sht15_end_transmission(struct sht15_data *data) | ||
429 | { | ||
430 | gpio_direction_output(data->pdata->gpio_data, 1); | ||
431 | ndelay(SHT15_TSU); | ||
432 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
433 | ndelay(SHT15_TSCKH); | ||
434 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
435 | ndelay(SHT15_TSCKL); | ||
436 | } | ||
437 | |||
438 | static void sht15_bh_read_data(struct work_struct *work_s) | ||
439 | { | ||
440 | int i; | ||
441 | uint16_t val = 0; | ||
442 | struct sht15_data *data | ||
443 | = container_of(work_s, struct sht15_data, | ||
444 | read_work); | ||
445 | /* Firstly, verify the line is low */ | ||
446 | if (gpio_get_value(data->pdata->gpio_data)) { | ||
447 | /* If not, then start the interrupt again - care | ||
448 | here as could have gone low in meantime so verify | ||
449 | it hasn't! | ||
450 | */ | ||
451 | atomic_set(&data->interrupt_handled, 0); | ||
452 | enable_irq(gpio_to_irq(data->pdata->gpio_data)); | ||
453 | /* If still not occured or another handler has been scheduled */ | ||
454 | if (gpio_get_value(data->pdata->gpio_data) | ||
455 | || atomic_read(&data->interrupt_handled)) | ||
456 | return; | ||
457 | } | ||
458 | /* Read the data back from the device */ | ||
459 | for (i = 0; i < 16; ++i) { | ||
460 | val <<= 1; | ||
461 | gpio_set_value(data->pdata->gpio_sck, 1); | ||
462 | ndelay(SHT15_TSCKH); | ||
463 | val |= !!gpio_get_value(data->pdata->gpio_data); | ||
464 | gpio_set_value(data->pdata->gpio_sck, 0); | ||
465 | ndelay(SHT15_TSCKL); | ||
466 | if (i == 7) | ||
467 | sht15_ack(data); | ||
468 | } | ||
469 | /* Tell the device we are done */ | ||
470 | sht15_end_transmission(data); | ||
471 | |||
472 | switch (data->flag) { | ||
473 | case SHT15_READING_TEMP: | ||
474 | data->val_temp = val; | ||
475 | break; | ||
476 | case SHT15_READING_HUMID: | ||
477 | data->val_humid = val; | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | data->flag = SHT15_READING_NOTHING; | ||
482 | wake_up(&data->wait_queue); | ||
483 | } | ||
484 | |||
485 | static void sht15_update_voltage(struct work_struct *work_s) | ||
486 | { | ||
487 | struct sht15_data *data | ||
488 | = container_of(work_s, struct sht15_data, | ||
489 | update_supply_work); | ||
490 | data->supply_uV = regulator_get_voltage(data->reg); | ||
491 | } | ||
492 | |||
493 | /** | ||
494 | * sht15_invalidate_voltage() - mark supply voltage invalid when notified by reg | ||
495 | * @nb: associated notification structure | ||
496 | * @event: voltage regulator state change event code | ||
497 | * @ignored: function parameter - ignored here | ||
498 | * | ||
499 | * Note that as the notification code holds the regulator lock, we have | ||
500 | * to schedule an update of the supply voltage rather than getting it directly. | ||
501 | **/ | ||
502 | static int sht15_invalidate_voltage(struct notifier_block *nb, | ||
503 | unsigned long event, | ||
504 | void *ignored) | ||
505 | { | ||
506 | struct sht15_data *data = container_of(nb, struct sht15_data, nb); | ||
507 | |||
508 | if (event == REGULATOR_EVENT_VOLTAGE_CHANGE) | ||
509 | data->supply_uV_valid = false; | ||
510 | schedule_work(&data->update_supply_work); | ||
511 | |||
512 | return NOTIFY_OK; | ||
513 | } | ||
514 | |||
515 | static int __devinit sht15_probe(struct platform_device *pdev) | ||
516 | { | ||
517 | int ret = 0; | ||
518 | struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
519 | |||
520 | if (!data) { | ||
521 | ret = -ENOMEM; | ||
522 | dev_err(&pdev->dev, "kzalloc failed"); | ||
523 | goto error_ret; | ||
524 | } | ||
525 | |||
526 | INIT_WORK(&data->read_work, sht15_bh_read_data); | ||
527 | INIT_WORK(&data->update_supply_work, sht15_update_voltage); | ||
528 | platform_set_drvdata(pdev, data); | ||
529 | mutex_init(&data->read_lock); | ||
530 | data->dev = &pdev->dev; | ||
531 | init_waitqueue_head(&data->wait_queue); | ||
532 | |||
533 | if (pdev->dev.platform_data == NULL) { | ||
534 | dev_err(&pdev->dev, "no platform data supplied"); | ||
535 | goto err_free_data; | ||
536 | } | ||
537 | data->pdata = pdev->dev.platform_data; | ||
538 | data->supply_uV = data->pdata->supply_mv*1000; | ||
539 | |||
540 | /* If a regulator is available, query what the supply voltage actually is!*/ | ||
541 | data->reg = regulator_get(data->dev, "vcc"); | ||
542 | if (!IS_ERR(data->reg)) { | ||
543 | data->supply_uV = regulator_get_voltage(data->reg); | ||
544 | regulator_enable(data->reg); | ||
545 | /* setup a notifier block to update this if another device | ||
546 | * causes the voltage to change */ | ||
547 | data->nb.notifier_call = &sht15_invalidate_voltage; | ||
548 | ret = regulator_register_notifier(data->reg, &data->nb); | ||
549 | } | ||
550 | /* Try requesting the GPIOs */ | ||
551 | ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck"); | ||
552 | if (ret) { | ||
553 | dev_err(&pdev->dev, "gpio request failed"); | ||
554 | goto err_free_data; | ||
555 | } | ||
556 | gpio_direction_output(data->pdata->gpio_sck, 0); | ||
557 | ret = gpio_request(data->pdata->gpio_data, "SHT15 data"); | ||
558 | if (ret) { | ||
559 | dev_err(&pdev->dev, "gpio request failed"); | ||
560 | goto err_release_gpio_sck; | ||
561 | } | ||
562 | ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); | ||
563 | if (ret) { | ||
564 | dev_err(&pdev->dev, "sysfs create failed"); | ||
565 | goto err_free_data; | ||
566 | } | ||
567 | |||
568 | ret = request_irq(gpio_to_irq(data->pdata->gpio_data), | ||
569 | sht15_interrupt_fired, | ||
570 | IRQF_TRIGGER_FALLING, | ||
571 | "sht15 data", | ||
572 | data); | ||
573 | if (ret) { | ||
574 | dev_err(&pdev->dev, "failed to get irq for data line"); | ||
575 | goto err_release_gpio_data; | ||
576 | } | ||
577 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); | ||
578 | sht15_connection_reset(data); | ||
579 | sht15_send_cmd(data, 0x1E); | ||
580 | |||
581 | data->hwmon_dev = hwmon_device_register(data->dev); | ||
582 | if (IS_ERR(data->hwmon_dev)) { | ||
583 | ret = PTR_ERR(data->hwmon_dev); | ||
584 | goto err_release_gpio_data; | ||
585 | } | ||
586 | return 0; | ||
587 | |||
588 | err_release_gpio_data: | ||
589 | gpio_free(data->pdata->gpio_data); | ||
590 | err_release_gpio_sck: | ||
591 | gpio_free(data->pdata->gpio_sck); | ||
592 | err_free_data: | ||
593 | kfree(data); | ||
594 | error_ret: | ||
595 | |||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | static int __devexit sht15_remove(struct platform_device *pdev) | ||
600 | { | ||
601 | struct sht15_data *data = platform_get_drvdata(pdev); | ||
602 | |||
603 | /* Make sure any reads from the device are done and | ||
604 | * prevent new ones beginnning */ | ||
605 | mutex_lock(&data->read_lock); | ||
606 | hwmon_device_unregister(data->hwmon_dev); | ||
607 | sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); | ||
608 | if (!IS_ERR(data->reg)) { | ||
609 | regulator_unregister_notifier(data->reg, &data->nb); | ||
610 | regulator_disable(data->reg); | ||
611 | regulator_put(data->reg); | ||
612 | } | ||
613 | |||
614 | free_irq(gpio_to_irq(data->pdata->gpio_data), data); | ||
615 | gpio_free(data->pdata->gpio_data); | ||
616 | gpio_free(data->pdata->gpio_sck); | ||
617 | mutex_unlock(&data->read_lock); | ||
618 | kfree(data); | ||
619 | return 0; | ||
620 | } | ||
621 | |||
622 | |||
623 | static struct platform_driver sht_drivers[] = { | ||
624 | { | ||
625 | .driver = { | ||
626 | .name = "sht10", | ||
627 | .owner = THIS_MODULE, | ||
628 | }, | ||
629 | .probe = sht15_probe, | ||
630 | .remove = sht15_remove, | ||
631 | }, { | ||
632 | .driver = { | ||
633 | .name = "sht11", | ||
634 | .owner = THIS_MODULE, | ||
635 | }, | ||
636 | .probe = sht15_probe, | ||
637 | .remove = sht15_remove, | ||
638 | }, { | ||
639 | .driver = { | ||
640 | .name = "sht15", | ||
641 | .owner = THIS_MODULE, | ||
642 | }, | ||
643 | .probe = sht15_probe, | ||
644 | .remove = sht15_remove, | ||
645 | }, { | ||
646 | .driver = { | ||
647 | .name = "sht71", | ||
648 | .owner = THIS_MODULE, | ||
649 | }, | ||
650 | .probe = sht15_probe, | ||
651 | .remove = sht15_remove, | ||
652 | }, { | ||
653 | .driver = { | ||
654 | .name = "sht75", | ||
655 | .owner = THIS_MODULE, | ||
656 | }, | ||
657 | .probe = sht15_probe, | ||
658 | .remove = sht15_remove, | ||
659 | }, | ||
660 | }; | ||
661 | |||
662 | |||
663 | static int __init sht15_init(void) | ||
664 | { | ||
665 | int ret; | ||
666 | int i; | ||
667 | |||
668 | for (i = 0; i < ARRAY_SIZE(sht_drivers); i++) { | ||
669 | ret = platform_driver_register(&sht_drivers[i]); | ||
670 | if (ret) | ||
671 | goto error_unreg; | ||
672 | } | ||
673 | |||
674 | return 0; | ||
675 | |||
676 | error_unreg: | ||
677 | while (--i >= 0) | ||
678 | platform_driver_unregister(&sht_drivers[i]); | ||
679 | |||
680 | return ret; | ||
681 | } | ||
682 | module_init(sht15_init); | ||
683 | |||
684 | static void __exit sht15_exit(void) | ||
685 | { | ||
686 | int i; | ||
687 | for (i = ARRAY_SIZE(sht_drivers) - 1; i >= 0; i--) | ||
688 | platform_driver_unregister(&sht_drivers[i]); | ||
689 | } | ||
690 | module_exit(sht15_exit); | ||
691 | |||
692 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index f68e5f8e23ee..6318f7ddc1d4 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c | |||
@@ -190,7 +190,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, | |||
190 | int completed = 1; | 190 | int completed = 1; |
191 | unsigned long timeout = jiffies + i2c_adap->timeout; | 191 | unsigned long timeout = jiffies + i2c_adap->timeout; |
192 | 192 | ||
193 | while (pca_status(adap) != 0xf8) { | 193 | while ((state = pca_status(adap)) != 0xf8) { |
194 | if (time_before(jiffies, timeout)) { | 194 | if (time_before(jiffies, timeout)) { |
195 | msleep(10); | 195 | msleep(10); |
196 | } else { | 196 | } else { |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 94eae5c3cbc7..a48c8aee0218 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -604,12 +604,14 @@ comment "Graphics adapter I2C/DDC channel drivers" | |||
604 | depends on PCI | 604 | depends on PCI |
605 | 605 | ||
606 | config I2C_VOODOO3 | 606 | config I2C_VOODOO3 |
607 | tristate "Voodoo 3" | 607 | tristate "Voodoo 3 (DEPRECATED)" |
608 | depends on PCI | 608 | depends on PCI |
609 | select I2C_ALGOBIT | 609 | select I2C_ALGOBIT |
610 | help | 610 | help |
611 | If you say yes to this option, support will be included for the | 611 | If you say yes to this option, support will be included for the |
612 | Voodoo 3 I2C interface. | 612 | Voodoo 3 I2C interface. This driver is deprecated and you should |
613 | use the tdfxfb driver instead, which additionally provides | ||
614 | framebuffer support. | ||
613 | 615 | ||
614 | This driver can also be built as a module. If so, the module | 616 | This driver can also be built as a module. If so, the module |
615 | will be called i2c-voodoo3. | 617 | will be called i2c-voodoo3. |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b6f3a0de6ca2..85e2e919d1cd 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -716,8 +716,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
716 | 716 | ||
717 | /* new style driver methods can't mix with legacy ones */ | 717 | /* new style driver methods can't mix with legacy ones */ |
718 | if (is_newstyle_driver(driver)) { | 718 | if (is_newstyle_driver(driver)) { |
719 | if (driver->attach_adapter || driver->detach_adapter | 719 | if (driver->detach_adapter || driver->detach_client) { |
720 | || driver->detach_client) { | ||
721 | printk(KERN_WARNING | 720 | printk(KERN_WARNING |
722 | "i2c-core: driver [%s] is confused\n", | 721 | "i2c-core: driver [%s] is confused\n", |
723 | driver->driver.name); | 722 | driver->driver.name); |
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c index 353a35bbba63..0332a95eefd4 100644 --- a/drivers/ide/cs5536.c +++ b/drivers/ide/cs5536.c | |||
@@ -236,6 +236,7 @@ static const struct ide_dma_ops cs5536_dma_ops = { | |||
236 | .dma_test_irq = ide_dma_test_irq, | 236 | .dma_test_irq = ide_dma_test_irq, |
237 | .dma_lost_irq = ide_dma_lost_irq, | 237 | .dma_lost_irq = ide_dma_lost_irq, |
238 | .dma_timer_expiry = ide_dma_sff_timer_expiry, | 238 | .dma_timer_expiry = ide_dma_sff_timer_expiry, |
239 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
239 | }; | 240 | }; |
240 | 241 | ||
241 | static const struct ide_port_info cs5536_info = { | 242 | static const struct ide_port_info cs5536_info = { |
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index a0eb87f59134..0feb66c720e1 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 3 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
4 | * Portions Copyright (C) 2003 Red Hat Inc | 4 | * Portions Copyright (C) 2003 Red Hat Inc |
5 | * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz | 5 | * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz |
6 | * Portions Copyright (C) 2005-2008 MontaVista Software, Inc. | 6 | * Portions Copyright (C) 2005-2009 MontaVista Software, Inc. |
7 | * | 7 | * |
8 | * Thanks to HighPoint Technologies for their assistance, and hardware. | 8 | * Thanks to HighPoint Technologies for their assistance, and hardware. |
9 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his | 9 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his |
@@ -114,6 +114,8 @@ | |||
114 | * the register setting lists into the table indexed by the clock selected | 114 | * the register setting lists into the table indexed by the clock selected |
115 | * - set the correct hwif->ultra_mask for each individual chip | 115 | * - set the correct hwif->ultra_mask for each individual chip |
116 | * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards | 116 | * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards |
117 | * - stop resetting HPT370's state machine before each DMA transfer as that has | ||
118 | * caused more harm than good | ||
117 | * Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com> | 119 | * Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com> |
118 | */ | 120 | */ |
119 | 121 | ||
@@ -133,7 +135,7 @@ | |||
133 | #define DRV_NAME "hpt366" | 135 | #define DRV_NAME "hpt366" |
134 | 136 | ||
135 | /* various tuning parameters */ | 137 | /* various tuning parameters */ |
136 | #define HPT_RESET_STATE_ENGINE | 138 | #undef HPT_RESET_STATE_ENGINE |
137 | #undef HPT_DELAY_INTERRUPT | 139 | #undef HPT_DELAY_INTERRUPT |
138 | 140 | ||
139 | static const char *quirk_drives[] = { | 141 | static const char *quirk_drives[] = { |
@@ -808,7 +810,7 @@ static void hpt370_irq_timeout(ide_drive_t *drive) | |||
808 | /* get DMA command mode */ | 810 | /* get DMA command mode */ |
809 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); | 811 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); |
810 | /* stop DMA */ | 812 | /* stop DMA */ |
811 | outb(dma_cmd & ~0x1, hwif->dma_base + ATA_DMA_CMD); | 813 | outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); |
812 | hpt370_clear_engine(drive); | 814 | hpt370_clear_engine(drive); |
813 | } | 815 | } |
814 | 816 | ||
@@ -825,11 +827,11 @@ static int hpt370_dma_end(ide_drive_t *drive) | |||
825 | ide_hwif_t *hwif = drive->hwif; | 827 | ide_hwif_t *hwif = drive->hwif; |
826 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | 828 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); |
827 | 829 | ||
828 | if (dma_stat & 0x01) { | 830 | if (dma_stat & ATA_DMA_ACTIVE) { |
829 | /* wait a little */ | 831 | /* wait a little */ |
830 | udelay(20); | 832 | udelay(20); |
831 | dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | 833 | dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); |
832 | if (dma_stat & 0x01) | 834 | if (dma_stat & ATA_DMA_ACTIVE) |
833 | hpt370_irq_timeout(drive); | 835 | hpt370_irq_timeout(drive); |
834 | } | 836 | } |
835 | return ide_dma_end(drive); | 837 | return ide_dma_end(drive); |
@@ -851,7 +853,7 @@ static int hpt374_dma_test_irq(ide_drive_t *drive) | |||
851 | 853 | ||
852 | dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | 854 | dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); |
853 | /* return 1 if INTR asserted */ | 855 | /* return 1 if INTR asserted */ |
854 | if (dma_stat & 4) | 856 | if (dma_stat & ATA_DMA_INTR) |
855 | return 1; | 857 | return 1; |
856 | 858 | ||
857 | return 0; | 859 | return 0; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3aec19d1fdfc..3d4e09969763 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -609,7 +609,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
609 | struct request *rq = hwif->rq; | 609 | struct request *rq = hwif->rq; |
610 | ide_expiry_t *expiry = NULL; | 610 | ide_expiry_t *expiry = NULL; |
611 | int dma_error = 0, dma, thislen, uptodate = 0; | 611 | int dma_error = 0, dma, thislen, uptodate = 0; |
612 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors; | 612 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors; |
613 | int sense = blk_sense_request(rq); | 613 | int sense = blk_sense_request(rq); |
614 | unsigned int timeout; | 614 | unsigned int timeout; |
615 | u16 len; | 615 | u16 len; |
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index 1aebdf1a4f58..4b6b71e2cdf5 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/mutex.h> | 7 | #include <linux/mutex.h> |
8 | #include <linux/ide.h> | 8 | #include <linux/ide.h> |
9 | #include <linux/hdreg.h> | 9 | #include <linux/hdreg.h> |
10 | #include <linux/dmi.h> | ||
10 | 11 | ||
11 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | 12 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) |
12 | #define IDE_DISK_MINORS (1 << PARTN_BITS) | 13 | #define IDE_DISK_MINORS (1 << PARTN_BITS) |
@@ -99,6 +100,19 @@ static void ide_gd_resume(ide_drive_t *drive) | |||
99 | (void)drive->disk_ops->get_capacity(drive); | 100 | (void)drive->disk_ops->get_capacity(drive); |
100 | } | 101 | } |
101 | 102 | ||
103 | static const struct dmi_system_id ide_coldreboot_table[] = { | ||
104 | { | ||
105 | /* Acer TravelMate 66x cuts power during reboot */ | ||
106 | .ident = "Acer TravelMate 660", | ||
107 | .matches = { | ||
108 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
109 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), | ||
110 | }, | ||
111 | }, | ||
112 | |||
113 | { } /* terminate list */ | ||
114 | }; | ||
115 | |||
102 | static void ide_gd_shutdown(ide_drive_t *drive) | 116 | static void ide_gd_shutdown(ide_drive_t *drive) |
103 | { | 117 | { |
104 | #ifdef CONFIG_ALPHA | 118 | #ifdef CONFIG_ALPHA |
@@ -115,7 +129,8 @@ static void ide_gd_shutdown(ide_drive_t *drive) | |||
115 | the disk to expire its write cache. */ | 129 | the disk to expire its write cache. */ |
116 | if (system_state != SYSTEM_POWER_OFF) { | 130 | if (system_state != SYSTEM_POWER_OFF) { |
117 | #else | 131 | #else |
118 | if (system_state == SYSTEM_RESTART) { | 132 | if (system_state == SYSTEM_RESTART && |
133 | !dmi_check_system(ide_coldreboot_table)) { | ||
119 | #endif | 134 | #endif |
120 | drive->disk_ops->flush(drive); | 135 | drive->disk_ops->flush(drive); |
121 | return; | 136 | return; |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 2ae02b8d7f8e..35dc38d3b2c5 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -102,11 +102,14 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) | |||
102 | drive->dev_flags |= IDE_DFLAG_PARKED; | 102 | drive->dev_flags |= IDE_DFLAG_PARKED; |
103 | } | 103 | } |
104 | 104 | ||
105 | if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) | 105 | if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
106 | memcpy(rq->special, cmd, sizeof(*cmd)); | 106 | struct ide_cmd *orig_cmd = rq->special; |
107 | 107 | ||
108 | if (cmd->tf_flags & IDE_TFLAG_DYN) | 108 | if (cmd->tf_flags & IDE_TFLAG_DYN) |
109 | kfree(cmd); | 109 | kfree(orig_cmd); |
110 | else | ||
111 | memcpy(orig_cmd, cmd, sizeof(*cmd)); | ||
112 | } | ||
110 | } | 113 | } |
111 | 114 | ||
112 | /* obsolete, blk_rq_bytes() should be used instead */ | 115 | /* obsolete, blk_rq_bytes() should be used instead */ |
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c index c7acca0b8733..09d813d313f4 100644 --- a/drivers/ide/palm_bk3710.c +++ b/drivers/ide/palm_bk3710.c | |||
@@ -39,27 +39,12 @@ | |||
39 | /* Primary Control Offset */ | 39 | /* Primary Control Offset */ |
40 | #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6 | 40 | #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6 |
41 | 41 | ||
42 | /* | ||
43 | * PalmChip 3710 IDE Controller UDMA timing structure Definition | ||
44 | */ | ||
45 | struct palm_bk3710_udmatiming { | ||
46 | unsigned int rptime; /* Ready to pause time */ | ||
47 | unsigned int cycletime; /* Cycle Time */ | ||
48 | }; | ||
49 | |||
50 | #define BK3710_BMICP 0x00 | 42 | #define BK3710_BMICP 0x00 |
51 | #define BK3710_BMISP 0x02 | 43 | #define BK3710_BMISP 0x02 |
52 | #define BK3710_BMIDTP 0x04 | 44 | #define BK3710_BMIDTP 0x04 |
53 | #define BK3710_BMICS 0x08 | ||
54 | #define BK3710_BMISS 0x0A | ||
55 | #define BK3710_BMIDTS 0x0C | ||
56 | #define BK3710_IDETIMP 0x40 | 45 | #define BK3710_IDETIMP 0x40 |
57 | #define BK3710_IDETIMS 0x42 | ||
58 | #define BK3710_SIDETIM 0x44 | ||
59 | #define BK3710_SLEWCTL 0x45 | ||
60 | #define BK3710_IDESTATUS 0x47 | 46 | #define BK3710_IDESTATUS 0x47 |
61 | #define BK3710_UDMACTL 0x48 | 47 | #define BK3710_UDMACTL 0x48 |
62 | #define BK3710_UDMATIM 0x4A | ||
63 | #define BK3710_MISCCTL 0x50 | 48 | #define BK3710_MISCCTL 0x50 |
64 | #define BK3710_REGSTB 0x54 | 49 | #define BK3710_REGSTB 0x54 |
65 | #define BK3710_REGRCVR 0x58 | 50 | #define BK3710_REGRCVR 0x58 |
@@ -71,17 +56,22 @@ struct palm_bk3710_udmatiming { | |||
71 | #define BK3710_UDMATRP 0x70 | 56 | #define BK3710_UDMATRP 0x70 |
72 | #define BK3710_UDMAENV 0x74 | 57 | #define BK3710_UDMAENV 0x74 |
73 | #define BK3710_IORDYTMP 0x78 | 58 | #define BK3710_IORDYTMP 0x78 |
74 | #define BK3710_IORDYTMS 0x7C | ||
75 | 59 | ||
76 | static unsigned ideclk_period; /* in nanoseconds */ | 60 | static unsigned ideclk_period; /* in nanoseconds */ |
77 | 61 | ||
62 | struct palm_bk3710_udmatiming { | ||
63 | unsigned int rptime; /* tRP -- Ready to pause time (nsec) */ | ||
64 | unsigned int cycletime; /* tCYCTYP2/2 -- avg Cycle Time (nsec) */ | ||
65 | /* tENV is always a minimum of 20 nsec */ | ||
66 | }; | ||
67 | |||
78 | static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { | 68 | static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { |
79 | {160, 240}, /* UDMA Mode 0 */ | 69 | { 160, 240 / 2 }, /* UDMA Mode 0 */ |
80 | {125, 160}, /* UDMA Mode 1 */ | 70 | { 125, 160 / 2 }, /* UDMA Mode 1 */ |
81 | {100, 120}, /* UDMA Mode 2 */ | 71 | { 100, 120 / 2 }, /* UDMA Mode 2 */ |
82 | {100, 90}, /* UDMA Mode 3 */ | 72 | { 100, 90 / 2 }, /* UDMA Mode 3 */ |
83 | {100, 60}, /* UDMA Mode 4 */ | 73 | { 100, 60 / 2 }, /* UDMA Mode 4 */ |
84 | {85, 40}, /* UDMA Mode 5 */ | 74 | { 85, 40 / 2 }, /* UDMA Mode 5 */ |
85 | }; | 75 | }; |
86 | 76 | ||
87 | static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, | 77 | static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, |
@@ -98,11 +88,6 @@ static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, | |||
98 | trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime, | 88 | trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime, |
99 | ideclk_period) - 1; | 89 | ideclk_period) - 1; |
100 | 90 | ||
101 | /* udmatim Register */ | ||
102 | val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0); | ||
103 | val16 |= (mode << (dev ? 4 : 0)); | ||
104 | writew(val16, base + BK3710_UDMATIM); | ||
105 | |||
106 | /* udmastb Ultra DMA Access Strobe Width */ | 91 | /* udmastb Ultra DMA Access Strobe Width */ |
107 | val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8)); | 92 | val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8)); |
108 | val32 |= (t0 << (dev ? 8 : 0)); | 93 | val32 |= (t0 << (dev ? 8 : 0)); |
@@ -163,10 +148,11 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, | |||
163 | u32 val32; | 148 | u32 val32; |
164 | struct ide_timing *t; | 149 | struct ide_timing *t; |
165 | 150 | ||
151 | t = ide_timing_find_mode(XFER_PIO_0 + mode); | ||
152 | |||
166 | /* PIO Data Setup */ | 153 | /* PIO Data Setup */ |
167 | t0 = DIV_ROUND_UP(cycletime, ideclk_period); | 154 | t0 = DIV_ROUND_UP(cycletime, ideclk_period); |
168 | t2 = DIV_ROUND_UP(ide_timing_find_mode(XFER_PIO_0 + mode)->active, | 155 | t2 = DIV_ROUND_UP(t->active, ideclk_period); |
169 | ideclk_period); | ||
170 | 156 | ||
171 | t2i = t0 - t2 - 1; | 157 | t2i = t0 - t2 - 1; |
172 | t2 -= 1; | 158 | t2 -= 1; |
@@ -187,7 +173,6 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, | |||
187 | } | 173 | } |
188 | 174 | ||
189 | /* TASKFILE Setup */ | 175 | /* TASKFILE Setup */ |
190 | t = ide_timing_find_mode(XFER_PIO_0 + mode); | ||
191 | t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period); | 176 | t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period); |
192 | t2 = DIV_ROUND_UP(t->act8b, ideclk_period); | 177 | t2 = DIV_ROUND_UP(t->act8b, ideclk_period); |
193 | 178 | ||
@@ -236,42 +221,23 @@ static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio) | |||
236 | static void __devinit palm_bk3710_chipinit(void __iomem *base) | 221 | static void __devinit palm_bk3710_chipinit(void __iomem *base) |
237 | { | 222 | { |
238 | /* | 223 | /* |
239 | * enable the reset_en of ATA controller so that when ata signals | 224 | * REVISIT: the ATA reset signal needs to be managed through a |
240 | * are brought out, by writing into device config. at that | 225 | * GPIO, which means it should come from platform_data. Until |
241 | * time por_n signal should not be 'Z' and have a stable value. | 226 | * we get and use such information, we have to trust that things |
227 | * have been reset before we get here. | ||
242 | */ | 228 | */ |
243 | writel(0x0300, base + BK3710_MISCCTL); | ||
244 | |||
245 | /* wait for some time and deassert the reset of ATA Device. */ | ||
246 | mdelay(100); | ||
247 | |||
248 | /* Deassert the Reset */ | ||
249 | writel(0x0200, base + BK3710_MISCCTL); | ||
250 | 229 | ||
251 | /* | 230 | /* |
252 | * Program the IDETIMP Register Value based on the following assumptions | 231 | * Program the IDETIMP Register Value based on the following assumptions |
253 | * | 232 | * |
254 | * (ATA_IDETIMP_IDEEN , ENABLE ) | | 233 | * (ATA_IDETIMP_IDEEN , ENABLE ) | |
255 | * (ATA_IDETIMP_SLVTIMEN , DISABLE) | | ||
256 | * (ATA_IDETIMP_RDYSMPL , 70NS) | | ||
257 | * (ATA_IDETIMP_RDYRCVRY , 50NS) | | ||
258 | * (ATA_IDETIMP_DMAFTIM1 , PIOCOMP) | | ||
259 | * (ATA_IDETIMP_PREPOST1 , DISABLE) | | 234 | * (ATA_IDETIMP_PREPOST1 , DISABLE) | |
260 | * (ATA_IDETIMP_RDYSEN1 , DISABLE) | | ||
261 | * (ATA_IDETIMP_PIOFTIM1 , DISABLE) | | ||
262 | * (ATA_IDETIMP_DMAFTIM0 , PIOCOMP) | | ||
263 | * (ATA_IDETIMP_PREPOST0 , DISABLE) | | 235 | * (ATA_IDETIMP_PREPOST0 , DISABLE) | |
264 | * (ATA_IDETIMP_RDYSEN0 , DISABLE) | | 236 | * |
265 | * (ATA_IDETIMP_PIOFTIM0 , DISABLE) | 237 | * DM6446 silicon rev 2.1 and earlier have no observed net benefit |
266 | */ | 238 | * from enabling prefetch/postwrite. |
267 | writew(0xB388, base + BK3710_IDETIMP); | ||
268 | |||
269 | /* | ||
270 | * Configure SIDETIM Register | ||
271 | * (ATA_SIDETIM_RDYSMPS1 ,120NS ) | | ||
272 | * (ATA_SIDETIM_RDYRCYS1 ,120NS ) | ||
273 | */ | 239 | */ |
274 | writeb(0, base + BK3710_SIDETIM); | 240 | writew(BIT(15), base + BK3710_IDETIMP); |
275 | 241 | ||
276 | /* | 242 | /* |
277 | * UDMACTL Ultra-ATA DMA Control | 243 | * UDMACTL Ultra-ATA DMA Control |
@@ -283,11 +249,11 @@ static void __devinit palm_bk3710_chipinit(void __iomem *base) | |||
283 | 249 | ||
284 | /* | 250 | /* |
285 | * MISCCTL Miscellaneous Conrol Register | 251 | * MISCCTL Miscellaneous Conrol Register |
286 | * (ATA_MISCCTL_RSTMODEP , 1) | | 252 | * (ATA_MISCCTL_HWNHLD1P , 1 cycle) |
287 | * (ATA_MISCCTL_RESETP , 0) | | 253 | * (ATA_MISCCTL_HWNHLD0P , 1 cycle) |
288 | * (ATA_MISCCTL_TIMORIDE , 1) | 254 | * (ATA_MISCCTL_TIMORIDE , 1) |
289 | */ | 255 | */ |
290 | writel(0x201, base + BK3710_MISCCTL); | 256 | writel(0x001, base + BK3710_MISCCTL); |
291 | 257 | ||
292 | /* | 258 | /* |
293 | * IORDYTMP IORDY Timer for Primary Register | 259 | * IORDYTMP IORDY Timer for Primary Register |
@@ -357,10 +323,9 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) | |||
357 | 323 | ||
358 | clk_enable(clk); | 324 | clk_enable(clk); |
359 | rate = clk_get_rate(clk); | 325 | rate = clk_get_rate(clk); |
360 | ideclk_period = 1000000000UL / rate; | ||
361 | 326 | ||
362 | /* Register the IDE interface with Linux ATA Interface */ | 327 | /* NOTE: round *down* to meet minimum timings; we count in clocks */ |
363 | memset(&hw, 0, sizeof(hw)); | 328 | ideclk_period = 1000000000UL / rate; |
364 | 329 | ||
365 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 330 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
366 | if (mem == NULL) { | 331 | if (mem == NULL) { |
@@ -390,6 +355,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) | |||
390 | /* Configure the Palm Chip controller */ | 355 | /* Configure the Palm Chip controller */ |
391 | palm_bk3710_chipinit(base); | 356 | palm_bk3710_chipinit(base); |
392 | 357 | ||
358 | memset(&hw, 0, sizeof(hw)); | ||
393 | for (i = 0; i < IDE_NR_PORTS - 2; i++) | 359 | for (i = 0; i < IDE_NR_PORTS - 2; i++) |
394 | hw.io_ports_array[i] = (unsigned long) | 360 | hw.io_ports_array[i] = (unsigned long) |
395 | (base + IDE_PALM_ATA_PRI_REG_OFFSET + i); | 361 | (base + IDE_PALM_ATA_PRI_REG_OFFSET + i); |
@@ -402,6 +368,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev) | |||
402 | palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 : | 368 | palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 : |
403 | ATA_UDMA5; | 369 | ATA_UDMA5; |
404 | 370 | ||
371 | /* Register the IDE interface with Linux */ | ||
405 | rc = ide_host_add(&palm_bk3710_port_info, hws, NULL); | 372 | rc = ide_host_add(&palm_bk3710_port_info, hws, NULL); |
406 | if (rc) | 373 | if (rc) |
407 | goto out; | 374 | goto out; |
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 052b9bf1f8fb..f76e4e6b408f 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c | |||
@@ -1682,7 +1682,7 @@ static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif, | |||
1682 | * The +2 is +1 for the stop command and +1 to allow for | 1682 | * The +2 is +1 for the stop command and +1 to allow for |
1683 | * aligning the start address to a multiple of 16 bytes. | 1683 | * aligning the start address to a multiple of 16 bytes. |
1684 | */ | 1684 | */ |
1685 | pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent( | 1685 | pmif->dma_table_cpu = pci_alloc_consistent( |
1686 | dev, | 1686 | dev, |
1687 | (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), | 1687 | (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), |
1688 | &hwif->dmatable_dma); | 1688 | &hwif->dmatable_dma); |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index ebf4be5b7c4e..2d175b5928ff 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -50,9 +50,8 @@ static LIST_HEAD(gameport_list); | |||
50 | 50 | ||
51 | static struct bus_type gameport_bus; | 51 | static struct bus_type gameport_bus; |
52 | 52 | ||
53 | static void gameport_add_driver(struct gameport_driver *drv); | ||
54 | static void gameport_add_port(struct gameport *gameport); | 53 | static void gameport_add_port(struct gameport *gameport); |
55 | static void gameport_destroy_port(struct gameport *gameport); | 54 | static void gameport_attach_driver(struct gameport_driver *drv); |
56 | static void gameport_reconnect_port(struct gameport *gameport); | 55 | static void gameport_reconnect_port(struct gameport *gameport); |
57 | static void gameport_disconnect_port(struct gameport *gameport); | 56 | static void gameport_disconnect_port(struct gameport *gameport); |
58 | 57 | ||
@@ -230,7 +229,6 @@ static void gameport_find_driver(struct gameport *gameport) | |||
230 | 229 | ||
231 | enum gameport_event_type { | 230 | enum gameport_event_type { |
232 | GAMEPORT_REGISTER_PORT, | 231 | GAMEPORT_REGISTER_PORT, |
233 | GAMEPORT_REGISTER_DRIVER, | ||
234 | GAMEPORT_ATTACH_DRIVER, | 232 | GAMEPORT_ATTACH_DRIVER, |
235 | }; | 233 | }; |
236 | 234 | ||
@@ -374,8 +372,8 @@ static void gameport_handle_event(void) | |||
374 | gameport_add_port(event->object); | 372 | gameport_add_port(event->object); |
375 | break; | 373 | break; |
376 | 374 | ||
377 | case GAMEPORT_REGISTER_DRIVER: | 375 | case GAMEPORT_ATTACH_DRIVER: |
378 | gameport_add_driver(event->object); | 376 | gameport_attach_driver(event->object); |
379 | break; | 377 | break; |
380 | 378 | ||
381 | default: | 379 | default: |
@@ -706,14 +704,14 @@ static int gameport_driver_remove(struct device *dev) | |||
706 | return 0; | 704 | return 0; |
707 | } | 705 | } |
708 | 706 | ||
709 | static void gameport_add_driver(struct gameport_driver *drv) | 707 | static void gameport_attach_driver(struct gameport_driver *drv) |
710 | { | 708 | { |
711 | int error; | 709 | int error; |
712 | 710 | ||
713 | error = driver_register(&drv->driver); | 711 | error = driver_attach(&drv->driver); |
714 | if (error) | 712 | if (error) |
715 | printk(KERN_ERR | 713 | printk(KERN_ERR |
716 | "gameport: driver_register() failed for %s, error: %d\n", | 714 | "gameport: driver_attach() failed for %s, error: %d\n", |
717 | drv->driver.name, error); | 715 | drv->driver.name, error); |
718 | } | 716 | } |
719 | 717 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index ec3db3ade118..935a1835de2d 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -132,6 +132,11 @@ static void input_start_autorepeat(struct input_dev *dev, int code) | |||
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | static void input_stop_autorepeat(struct input_dev *dev) | ||
136 | { | ||
137 | del_timer(&dev->timer); | ||
138 | } | ||
139 | |||
135 | #define INPUT_IGNORE_EVENT 0 | 140 | #define INPUT_IGNORE_EVENT 0 |
136 | #define INPUT_PASS_TO_HANDLERS 1 | 141 | #define INPUT_PASS_TO_HANDLERS 1 |
137 | #define INPUT_PASS_TO_DEVICE 2 | 142 | #define INPUT_PASS_TO_DEVICE 2 |
@@ -167,6 +172,8 @@ static void input_handle_event(struct input_dev *dev, | |||
167 | __change_bit(code, dev->key); | 172 | __change_bit(code, dev->key); |
168 | if (value) | 173 | if (value) |
169 | input_start_autorepeat(dev, code); | 174 | input_start_autorepeat(dev, code); |
175 | else | ||
176 | input_stop_autorepeat(dev); | ||
170 | } | 177 | } |
171 | 178 | ||
172 | disposition = INPUT_PASS_TO_HANDLERS; | 179 | disposition = INPUT_PASS_TO_HANDLERS; |
@@ -737,11 +744,11 @@ static inline void input_wakeup_procfs_readers(void) | |||
737 | 744 | ||
738 | static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) | 745 | static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) |
739 | { | 746 | { |
740 | int state = input_devices_state; | ||
741 | |||
742 | poll_wait(file, &input_devices_poll_wait, wait); | 747 | poll_wait(file, &input_devices_poll_wait, wait); |
743 | if (state != input_devices_state) | 748 | if (file->f_version != input_devices_state) { |
749 | file->f_version = input_devices_state; | ||
744 | return POLLIN | POLLRDNORM; | 750 | return POLLIN | POLLRDNORM; |
751 | } | ||
745 | 752 | ||
746 | return 0; | 753 | return 0; |
747 | } | 754 | } |
@@ -1542,7 +1549,6 @@ int input_register_handle(struct input_handle *handle) | |||
1542 | return error; | 1549 | return error; |
1543 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | 1550 | list_add_tail_rcu(&handle->d_node, &dev->h_list); |
1544 | mutex_unlock(&dev->mutex); | 1551 | mutex_unlock(&dev->mutex); |
1545 | synchronize_rcu(); | ||
1546 | 1552 | ||
1547 | /* | 1553 | /* |
1548 | * Since we are supposed to be called from ->connect() | 1554 | * Since we are supposed to be called from ->connect() |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 45470f18d7e9..444dec07e5d8 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -229,7 +229,8 @@ struct atkbd { | |||
229 | /* | 229 | /* |
230 | * System-specific ketymap fixup routine | 230 | * System-specific ketymap fixup routine |
231 | */ | 231 | */ |
232 | static void (*atkbd_platform_fixup)(struct atkbd *); | 232 | static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); |
233 | static void *atkbd_platform_fixup_data; | ||
233 | 234 | ||
234 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | 235 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, |
235 | ssize_t (*handler)(struct atkbd *, char *)); | 236 | ssize_t (*handler)(struct atkbd *, char *)); |
@@ -834,87 +835,64 @@ static void atkbd_disconnect(struct serio *serio) | |||
834 | } | 835 | } |
835 | 836 | ||
836 | /* | 837 | /* |
837 | * Most special keys (Fn+F?) on Dell laptops do not generate release | 838 | * generate release events for the keycodes given in data |
838 | * events so we have to do it ourselves. | ||
839 | */ | 839 | */ |
840 | static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd) | 840 | static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd, |
841 | const void *data) | ||
841 | { | 842 | { |
842 | static const unsigned int forced_release_keys[] = { | 843 | const unsigned int *keys = data; |
843 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, | 844 | unsigned int i; |
844 | }; | ||
845 | int i; | ||
846 | 845 | ||
847 | if (atkbd->set == 2) | 846 | if (atkbd->set == 2) |
848 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | 847 | for (i = 0; keys[i] != -1U; i++) |
849 | __set_bit(forced_release_keys[i], | 848 | __set_bit(keys[i], atkbd->force_release_mask); |
850 | atkbd->force_release_mask); | ||
851 | } | 849 | } |
852 | 850 | ||
853 | /* | 851 | /* |
852 | * Most special keys (Fn+F?) on Dell laptops do not generate release | ||
853 | * events so we have to do it ourselves. | ||
854 | */ | ||
855 | static unsigned int atkbd_dell_laptop_forced_release_keys[] = { | ||
856 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U | ||
857 | }; | ||
858 | |||
859 | /* | ||
854 | * Perform fixup for HP system that doesn't generate release | 860 | * Perform fixup for HP system that doesn't generate release |
855 | * for its video switch | 861 | * for its video switch |
856 | */ | 862 | */ |
857 | static void atkbd_hp_keymap_fixup(struct atkbd *atkbd) | 863 | static unsigned int atkbd_hp_forced_release_keys[] = { |
858 | { | 864 | 0x94, -1U |
859 | static const unsigned int forced_release_keys[] = { | 865 | }; |
860 | 0x94, | ||
861 | }; | ||
862 | int i; | ||
863 | |||
864 | if (atkbd->set == 2) | ||
865 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | ||
866 | __set_bit(forced_release_keys[i], | ||
867 | atkbd->force_release_mask); | ||
868 | } | ||
869 | 866 | ||
870 | /* | 867 | /* |
871 | * Inventec system with broken key release on volume keys | 868 | * Inventec system with broken key release on volume keys |
872 | */ | 869 | */ |
873 | static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd) | 870 | static unsigned int atkbd_inventec_forced_release_keys[] = { |
874 | { | 871 | 0xae, 0xb0, -1U |
875 | const unsigned int forced_release_keys[] = { | 872 | }; |
876 | 0xae, 0xb0, | ||
877 | }; | ||
878 | int i; | ||
879 | |||
880 | if (atkbd->set == 2) | ||
881 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | ||
882 | __set_bit(forced_release_keys[i], | ||
883 | atkbd->force_release_mask); | ||
884 | } | ||
885 | 873 | ||
886 | /* | 874 | /* |
887 | * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release | 875 | * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release |
888 | * for its volume buttons | 876 | * for its volume buttons |
889 | */ | 877 | */ |
890 | static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd) | 878 | static unsigned int atkbd_hp_zv6100_forced_release_keys[] = { |
891 | { | 879 | 0xae, 0xb0, -1U |
892 | const unsigned int forced_release_keys[] = { | 880 | }; |
893 | 0xae, 0xb0, | ||
894 | }; | ||
895 | int i; | ||
896 | |||
897 | if (atkbd->set == 2) | ||
898 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | ||
899 | __set_bit(forced_release_keys[i], | ||
900 | atkbd->force_release_mask); | ||
901 | } | ||
902 | 881 | ||
903 | /* | 882 | /* |
904 | * Samsung NC10 with Fn+F? key release not working | 883 | * Samsung NC10,NC20 with Fn+F? key release not working |
905 | */ | 884 | */ |
906 | static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd) | 885 | static unsigned int atkbd_samsung_forced_release_keys[] = { |
907 | { | 886 | 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U |
908 | const unsigned int forced_release_keys[] = { | 887 | }; |
909 | 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, | ||
910 | }; | ||
911 | int i; | ||
912 | 888 | ||
913 | if (atkbd->set == 2) | 889 | /* |
914 | for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) | 890 | * The volume up and volume down special keys on a Fujitsu Amilo PA 1510 laptop |
915 | __set_bit(forced_release_keys[i], | 891 | * do not generate release events so we have to do it ourselves. |
916 | atkbd->force_release_mask); | 892 | */ |
917 | } | 893 | static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { |
894 | 0xb0, 0xae, -1U | ||
895 | }; | ||
918 | 896 | ||
919 | /* | 897 | /* |
920 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 898 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
@@ -967,7 +945,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd) | |||
967 | * Perform additional fixups | 945 | * Perform additional fixups |
968 | */ | 946 | */ |
969 | if (atkbd_platform_fixup) | 947 | if (atkbd_platform_fixup) |
970 | atkbd_platform_fixup(atkbd); | 948 | atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data); |
971 | } | 949 | } |
972 | 950 | ||
973 | /* | 951 | /* |
@@ -1492,9 +1470,11 @@ static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) | |||
1492 | return sprintf(buf, "%lu\n", atkbd->err_count); | 1470 | return sprintf(buf, "%lu\n", atkbd->err_count); |
1493 | } | 1471 | } |
1494 | 1472 | ||
1495 | static int __init atkbd_setup_fixup(const struct dmi_system_id *id) | 1473 | static int __init atkbd_setup_forced_release(const struct dmi_system_id *id) |
1496 | { | 1474 | { |
1497 | atkbd_platform_fixup = id->driver_data; | 1475 | atkbd_platform_fixup = atkbd_apply_forced_release_keylist; |
1476 | atkbd_platform_fixup_data = id->driver_data; | ||
1477 | |||
1498 | return 0; | 1478 | return 0; |
1499 | } | 1479 | } |
1500 | 1480 | ||
@@ -1505,8 +1485,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1505 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 1485 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
1506 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1486 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
1507 | }, | 1487 | }, |
1508 | .callback = atkbd_setup_fixup, | 1488 | .callback = atkbd_setup_forced_release, |
1509 | .driver_data = atkbd_dell_laptop_keymap_fixup, | 1489 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1510 | }, | 1490 | }, |
1511 | { | 1491 | { |
1512 | .ident = "Dell Laptop", | 1492 | .ident = "Dell Laptop", |
@@ -1514,8 +1494,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1514 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | 1494 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
1515 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 1495 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ |
1516 | }, | 1496 | }, |
1517 | .callback = atkbd_setup_fixup, | 1497 | .callback = atkbd_setup_forced_release, |
1518 | .driver_data = atkbd_dell_laptop_keymap_fixup, | 1498 | .driver_data = atkbd_dell_laptop_forced_release_keys, |
1519 | }, | 1499 | }, |
1520 | { | 1500 | { |
1521 | .ident = "HP 2133", | 1501 | .ident = "HP 2133", |
@@ -1523,8 +1503,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1523 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1503 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1524 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), | 1504 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), |
1525 | }, | 1505 | }, |
1526 | .callback = atkbd_setup_fixup, | 1506 | .callback = atkbd_setup_forced_release, |
1527 | .driver_data = atkbd_hp_keymap_fixup, | 1507 | .driver_data = atkbd_hp_forced_release_keys, |
1528 | }, | 1508 | }, |
1529 | { | 1509 | { |
1530 | .ident = "HP Pavilion ZV6100", | 1510 | .ident = "HP Pavilion ZV6100", |
@@ -1532,8 +1512,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1532 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 1512 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1533 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), | 1513 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), |
1534 | }, | 1514 | }, |
1535 | .callback = atkbd_setup_fixup, | 1515 | .callback = atkbd_setup_forced_release, |
1536 | .driver_data = atkbd_hp_zv6100_keymap_fixup, | 1516 | .driver_data = atkbd_hp_zv6100_forced_release_keys, |
1537 | }, | 1517 | }, |
1538 | { | 1518 | { |
1539 | .ident = "Inventec Symphony", | 1519 | .ident = "Inventec Symphony", |
@@ -1541,8 +1521,8 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1541 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | 1521 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), |
1542 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), | 1522 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), |
1543 | }, | 1523 | }, |
1544 | .callback = atkbd_setup_fixup, | 1524 | .callback = atkbd_setup_forced_release, |
1545 | .driver_data = atkbd_inventec_keymap_fixup, | 1525 | .driver_data = atkbd_inventec_forced_release_keys, |
1546 | }, | 1526 | }, |
1547 | { | 1527 | { |
1548 | .ident = "Samsung NC10", | 1528 | .ident = "Samsung NC10", |
@@ -1550,8 +1530,35 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1550 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 1530 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), |
1551 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), | 1531 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), |
1552 | }, | 1532 | }, |
1553 | .callback = atkbd_setup_fixup, | 1533 | .callback = atkbd_setup_forced_release, |
1554 | .driver_data = atkbd_samsung_keymap_fixup, | 1534 | .driver_data = atkbd_samsung_forced_release_keys, |
1535 | }, | ||
1536 | { | ||
1537 | .ident = "Samsung NC20", | ||
1538 | .matches = { | ||
1539 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
1540 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), | ||
1541 | }, | ||
1542 | .callback = atkbd_setup_forced_release, | ||
1543 | .driver_data = atkbd_samsung_forced_release_keys, | ||
1544 | }, | ||
1545 | { | ||
1546 | .ident = "Samsung SQ45S70S", | ||
1547 | .matches = { | ||
1548 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
1549 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), | ||
1550 | }, | ||
1551 | .callback = atkbd_setup_forced_release, | ||
1552 | .driver_data = atkbd_samsung_forced_release_keys, | ||
1553 | }, | ||
1554 | { | ||
1555 | .ident = "Fujitsu Amilo PA 1510", | ||
1556 | .matches = { | ||
1557 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
1558 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), | ||
1559 | }, | ||
1560 | .callback = atkbd_setup_forced_release, | ||
1561 | .driver_data = atkbd_amilo_pa1510_forced_release_keys, | ||
1555 | }, | 1562 | }, |
1556 | { } | 1563 | { } |
1557 | }; | 1564 | }; |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index ee855c5202e8..d427f322e207 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -211,8 +211,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
211 | 211 | ||
212 | if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || | 212 | if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT || |
213 | !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { | 213 | !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) { |
214 | printk(KERN_ERR DRV_NAME | 214 | printk(KERN_WARNING DRV_NAME |
215 | ": Invalid Debounce/Columdrive Time from pdata\n"); | 215 | ": Invalid Debounce/Columndrive Time in platform data\n"); |
216 | bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ | 216 | bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */ |
217 | } else { | 217 | } else { |
218 | bfin_write_KPAD_MSEL( | 218 | bfin_write_KPAD_MSEL( |
@@ -252,7 +252,7 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev) | |||
252 | } | 252 | } |
253 | 253 | ||
254 | error = request_irq(bf54x_kpad->irq, bfin_kpad_isr, | 254 | error = request_irq(bf54x_kpad->irq, bfin_kpad_isr, |
255 | IRQF_SAMPLE_RANDOM, DRV_NAME, pdev); | 255 | 0, DRV_NAME, pdev); |
256 | if (error) { | 256 | if (error) { |
257 | printk(KERN_ERR DRV_NAME | 257 | printk(KERN_ERR DRV_NAME |
258 | ": unable to claim irq %d; error %d\n", | 258 | ": unable to claim irq %d; error %d\n", |
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index aacf71f3cd44..e9d639ec283d 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c | |||
@@ -198,45 +198,28 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) | |||
198 | } | 198 | } |
199 | 199 | ||
200 | 200 | ||
201 | /* initialise HIL */ | 201 | /* initialize HIL */ |
202 | static int __init | 202 | static int __devinit hil_keyb_init(void) |
203 | hil_keyb_init(void) | ||
204 | { | 203 | { |
205 | unsigned char c; | 204 | unsigned char c; |
206 | unsigned int i, kbid; | 205 | unsigned int i, kbid; |
207 | wait_queue_head_t hil_wait; | 206 | wait_queue_head_t hil_wait; |
208 | int err; | 207 | int err; |
209 | 208 | ||
210 | if (hil_dev.dev) { | 209 | if (hil_dev.dev) |
211 | return -ENODEV; /* already initialized */ | 210 | return -ENODEV; /* already initialized */ |
212 | } | ||
213 | 211 | ||
212 | init_waitqueue_head(&hil_wait); | ||
214 | spin_lock_init(&hil_dev.lock); | 213 | spin_lock_init(&hil_dev.lock); |
214 | |||
215 | hil_dev.dev = input_allocate_device(); | 215 | hil_dev.dev = input_allocate_device(); |
216 | if (!hil_dev.dev) | 216 | if (!hil_dev.dev) |
217 | return -ENOMEM; | 217 | return -ENOMEM; |
218 | 218 | ||
219 | #if defined(CONFIG_HP300) | ||
220 | if (!MACH_IS_HP300) { | ||
221 | err = -ENODEV; | ||
222 | goto err1; | ||
223 | } | ||
224 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { | ||
225 | printk(KERN_ERR "HIL: hardware register was not found\n"); | ||
226 | err = -ENODEV; | ||
227 | goto err1; | ||
228 | } | ||
229 | if (!request_region(HILBASE + HIL_DATA, 2, "hil")) { | ||
230 | printk(KERN_ERR "HIL: IOPORT region already used\n"); | ||
231 | err = -EIO; | ||
232 | goto err1; | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); | 219 | err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); |
237 | if (err) { | 220 | if (err) { |
238 | printk(KERN_ERR "HIL: Can't get IRQ\n"); | 221 | printk(KERN_ERR "HIL: Can't get IRQ\n"); |
239 | goto err2; | 222 | goto err1; |
240 | } | 223 | } |
241 | 224 | ||
242 | /* Turn on interrupts */ | 225 | /* Turn on interrupts */ |
@@ -246,11 +229,9 @@ hil_keyb_init(void) | |||
246 | hil_dev.valid = 0; /* clear any pending data */ | 229 | hil_dev.valid = 0; /* clear any pending data */ |
247 | hil_do(HIL_READKBDSADR, NULL, 0); | 230 | hil_do(HIL_READKBDSADR, NULL, 0); |
248 | 231 | ||
249 | init_waitqueue_head(&hil_wait); | 232 | wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3 * HZ); |
250 | wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ); | 233 | if (!hil_dev.valid) |
251 | if (!hil_dev.valid) { | ||
252 | printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n"); | 234 | printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n"); |
253 | } | ||
254 | 235 | ||
255 | c = hil_dev.c; | 236 | c = hil_dev.c; |
256 | hil_dev.valid = 0; | 237 | hil_dev.valid = 0; |
@@ -268,7 +249,7 @@ hil_keyb_init(void) | |||
268 | 249 | ||
269 | for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) | 250 | for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) |
270 | if (hphilkeyb_keycode[i] != KEY_RESERVED) | 251 | if (hphilkeyb_keycode[i] != KEY_RESERVED) |
271 | set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); | 252 | __set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); |
272 | 253 | ||
273 | hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | 254 | hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); |
274 | hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | | 255 | hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | |
@@ -287,34 +268,45 @@ hil_keyb_init(void) | |||
287 | err = input_register_device(hil_dev.dev); | 268 | err = input_register_device(hil_dev.dev); |
288 | if (err) { | 269 | if (err) { |
289 | printk(KERN_ERR "HIL: Can't register device\n"); | 270 | printk(KERN_ERR "HIL: Can't register device\n"); |
290 | goto err3; | 271 | goto err2; |
291 | } | 272 | } |
273 | |||
292 | printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", | 274 | printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", |
293 | hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); | 275 | hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); |
294 | 276 | ||
295 | return 0; | 277 | return 0; |
296 | 278 | ||
297 | err3: | 279 | err2: |
298 | hil_do(HIL_INTOFF, NULL, 0); | 280 | hil_do(HIL_INTOFF, NULL, 0); |
299 | disable_irq(HIL_IRQ); | ||
300 | free_irq(HIL_IRQ, hil_dev.dev_id); | 281 | free_irq(HIL_IRQ, hil_dev.dev_id); |
301 | err2: | ||
302 | #if defined(CONFIG_HP300) | ||
303 | release_region(HILBASE + HIL_DATA, 2); | ||
304 | err1: | 282 | err1: |
305 | #endif | ||
306 | input_free_device(hil_dev.dev); | 283 | input_free_device(hil_dev.dev); |
307 | hil_dev.dev = NULL; | 284 | hil_dev.dev = NULL; |
308 | return err; | 285 | return err; |
309 | } | 286 | } |
310 | 287 | ||
288 | static void __devexit hil_keyb_exit(void) | ||
289 | { | ||
290 | if (HIL_IRQ) | ||
291 | free_irq(HIL_IRQ, hil_dev.dev_id); | ||
292 | |||
293 | /* Turn off interrupts */ | ||
294 | hil_do(HIL_INTOFF, NULL, 0); | ||
295 | |||
296 | input_unregister_device(hil_dev.dev); | ||
297 | hil_dev.dev = NULL; | ||
298 | } | ||
311 | 299 | ||
312 | #if defined(CONFIG_PARISC) | 300 | #if defined(CONFIG_PARISC) |
313 | static int __init | 301 | static int __devinit hil_probe_chip(struct parisc_device *dev) |
314 | hil_init_chip(struct parisc_device *dev) | ||
315 | { | 302 | { |
303 | /* Only allow one HIL keyboard */ | ||
304 | if (hil_dev.dev) | ||
305 | return -ENODEV; | ||
306 | |||
316 | if (!dev->irq) { | 307 | if (!dev->irq) { |
317 | printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start); | 308 | printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%p\n", |
309 | (void *)dev->hpa.start); | ||
318 | return -ENODEV; | 310 | return -ENODEV; |
319 | } | 311 | } |
320 | 312 | ||
@@ -327,51 +319,79 @@ hil_init_chip(struct parisc_device *dev) | |||
327 | return hil_keyb_init(); | 319 | return hil_keyb_init(); |
328 | } | 320 | } |
329 | 321 | ||
322 | static int __devexit hil_remove_chip(struct parisc_device *dev) | ||
323 | { | ||
324 | hil_keyb_exit(); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
330 | static struct parisc_device_id hil_tbl[] = { | 329 | static struct parisc_device_id hil_tbl[] = { |
331 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 }, | 330 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 }, |
332 | { 0, } | 331 | { 0, } |
333 | }; | 332 | }; |
334 | 333 | ||
334 | #if 0 | ||
335 | /* Disabled to avoid conflicts with the HP SDC HIL drivers */ | ||
335 | MODULE_DEVICE_TABLE(parisc, hil_tbl); | 336 | MODULE_DEVICE_TABLE(parisc, hil_tbl); |
337 | #endif | ||
336 | 338 | ||
337 | static struct parisc_driver hil_driver = { | 339 | static struct parisc_driver hil_driver = { |
338 | .name = "hil", | 340 | .name = "hil", |
339 | .id_table = hil_tbl, | 341 | .id_table = hil_tbl, |
340 | .probe = hil_init_chip, | 342 | .probe = hil_probe_chip, |
343 | .remove = __devexit_p(hil_remove_chip), | ||
341 | }; | 344 | }; |
342 | #endif /* CONFIG_PARISC */ | ||
343 | |||
344 | 345 | ||
345 | static int __init hil_init(void) | 346 | static int __init hil_init(void) |
346 | { | 347 | { |
347 | #if defined(CONFIG_PARISC) | ||
348 | return register_parisc_driver(&hil_driver); | 348 | return register_parisc_driver(&hil_driver); |
349 | #else | ||
350 | return hil_keyb_init(); | ||
351 | #endif | ||
352 | } | 349 | } |
353 | 350 | ||
354 | |||
355 | static void __exit hil_exit(void) | 351 | static void __exit hil_exit(void) |
356 | { | 352 | { |
357 | if (HIL_IRQ) { | 353 | unregister_parisc_driver(&hil_driver); |
358 | disable_irq(HIL_IRQ); | 354 | } |
359 | free_irq(HIL_IRQ, hil_dev.dev_id); | 355 | |
356 | #else /* !CONFIG_PARISC */ | ||
357 | |||
358 | static int __init hil_init(void) | ||
359 | { | ||
360 | int error; | ||
361 | |||
362 | /* Only allow one HIL keyboard */ | ||
363 | if (hil_dev.dev) | ||
364 | return -EBUSY; | ||
365 | |||
366 | if (!MACH_IS_HP300) | ||
367 | return -ENODEV; | ||
368 | |||
369 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { | ||
370 | printk(KERN_ERR "HIL: hardware register was not found\n"); | ||
371 | return -ENODEV; | ||
360 | } | 372 | } |
361 | 373 | ||
362 | /* Turn off interrupts */ | 374 | if (!request_region(HILBASE + HIL_DATA, 2, "hil")) { |
363 | hil_do(HIL_INTOFF, NULL, 0); | 375 | printk(KERN_ERR "HIL: IOPORT region already used\n"); |
376 | return -EIO; | ||
377 | } | ||
364 | 378 | ||
365 | input_unregister_device(hil_dev.dev); | 379 | error = hil_keyb_init(); |
380 | if (error) { | ||
381 | release_region(HILBASE + HIL_DATA, 2); | ||
382 | return error; | ||
383 | } | ||
366 | 384 | ||
367 | hil_dev.dev = NULL; | 385 | return 0; |
386 | } | ||
368 | 387 | ||
369 | #if defined(CONFIG_PARISC) | 388 | static void __exit hil_exit(void) |
370 | unregister_parisc_driver(&hil_driver); | 389 | { |
371 | #else | 390 | hil_keyb_exit(); |
372 | release_region(HILBASE+HIL_DATA, 2); | 391 | release_region(HILBASE + HIL_DATA, 2); |
373 | #endif | ||
374 | } | 392 | } |
375 | 393 | ||
394 | #endif /* CONFIG_PARISC */ | ||
395 | |||
376 | module_init(hil_init); | 396 | module_init(hil_init); |
377 | module_exit(hil_exit); | 397 | module_exit(hil_exit); |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 67e5553f699a..5c0a631d1455 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -214,7 +214,7 @@ config INPUT_SGI_BTNS | |||
214 | 214 | ||
215 | config HP_SDC_RTC | 215 | config HP_SDC_RTC |
216 | tristate "HP SDC Real Time Clock" | 216 | tristate "HP SDC Real Time Clock" |
217 | depends on GSC || HP300 | 217 | depends on (GSC || HP300) && SERIO |
218 | select HP_SDC | 218 | select HP_SDC |
219 | help | 219 | help |
220 | Say Y here if you want to support the built-in real time clock | 220 | Say Y here if you want to support the built-in real time clock |
@@ -227,4 +227,27 @@ config INPUT_PCF50633_PMU | |||
227 | Say Y to include support for delivering PMU events via input | 227 | Say Y to include support for delivering PMU events via input |
228 | layer on NXP PCF50633. | 228 | layer on NXP PCF50633. |
229 | 229 | ||
230 | config INPUT_GPIO_ROTARY_ENCODER | ||
231 | tristate "Rotary encoders connected to GPIO pins" | ||
232 | depends on GPIOLIB && GENERIC_GPIO | ||
233 | help | ||
234 | Say Y here to add support for rotary encoders connected to GPIO lines. | ||
235 | Check file:Documentation/incput/rotary_encoder.txt for more | ||
236 | information. | ||
237 | |||
238 | To compile this driver as a module, choose M here: the | ||
239 | module will be called rotary_encoder. | ||
240 | |||
241 | config INPUT_RB532_BUTTON | ||
242 | tristate "Mikrotik Routerboard 532 button interface" | ||
243 | depends on MIKROTIK_RB532 | ||
244 | depends on GPIOLIB && GENERIC_GPIO | ||
245 | select INPUT_POLLDEV | ||
246 | help | ||
247 | Say Y here if you want support for the S1 button built into | ||
248 | Mikrotik's Routerboard 532. | ||
249 | |||
250 | To compile this driver as a module, choose M here: the | ||
251 | module will be called rb532_button. | ||
252 | |||
230 | endif | 253 | endif |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index bb62e6efacf3..eb3f407baedf 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -4,21 +4,23 @@ | |||
4 | 4 | ||
5 | # Each configuration option enables a list of files. | 5 | # Each configuration option enables a list of files. |
6 | 6 | ||
7 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | 7 | obj-$(CONFIG_INPUT_APANEL) += apanel.o |
8 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o | ||
9 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | ||
10 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o | ||
11 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o | ||
12 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | ||
13 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o | ||
14 | obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o | 8 | obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o |
15 | obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o | 9 | obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o |
16 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o | 10 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o |
17 | obj-$(CONFIG_INPUT_POWERMATE) += powermate.o | ||
18 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o | ||
19 | obj-$(CONFIG_INPUT_CM109) += cm109.o | 11 | obj-$(CONFIG_INPUT_CM109) += cm109.o |
12 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o | ||
20 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 13 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
21 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 14 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o |
22 | obj-$(CONFIG_INPUT_APANEL) += apanel.o | 15 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o |
23 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | 16 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
24 | obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o | 17 | obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o |
18 | obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o | ||
19 | obj-$(CONFIG_INPUT_POWERMATE) += powermate.o | ||
20 | obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o | ||
21 | obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o | ||
22 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | ||
23 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | ||
24 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | ||
25 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | ||
26 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o | ||
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 3c9988dc0e9f..922c05141585 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -31,12 +31,73 @@ MODULE_LICENSE("GPL"); | |||
31 | * newly configured "channel". | 31 | * newly configured "channel". |
32 | */ | 32 | */ |
33 | 33 | ||
34 | static unsigned int channel_mask = 0xFFFF; | 34 | enum { |
35 | module_param(channel_mask, uint, 0644); | 35 | ATI_REMOTE2_MAX_CHANNEL_MASK = 0xFFFF, |
36 | ATI_REMOTE2_MAX_MODE_MASK = 0x1F, | ||
37 | }; | ||
38 | |||
39 | static int ati_remote2_set_mask(const char *val, | ||
40 | struct kernel_param *kp, unsigned int max) | ||
41 | { | ||
42 | unsigned long mask; | ||
43 | int ret; | ||
44 | |||
45 | if (!val) | ||
46 | return -EINVAL; | ||
47 | |||
48 | ret = strict_strtoul(val, 0, &mask); | ||
49 | if (ret) | ||
50 | return ret; | ||
51 | |||
52 | if (mask & ~max) | ||
53 | return -EINVAL; | ||
54 | |||
55 | *(unsigned int *)kp->arg = mask; | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int ati_remote2_set_channel_mask(const char *val, | ||
61 | struct kernel_param *kp) | ||
62 | { | ||
63 | pr_debug("%s()\n", __func__); | ||
64 | |||
65 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK); | ||
66 | } | ||
67 | |||
68 | static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp) | ||
69 | { | ||
70 | pr_debug("%s()\n", __func__); | ||
71 | |||
72 | return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); | ||
73 | } | ||
74 | |||
75 | static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp) | ||
76 | { | ||
77 | pr_debug("%s()\n", __func__); | ||
78 | |||
79 | return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK); | ||
80 | } | ||
81 | |||
82 | static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) | ||
83 | { | ||
84 | pr_debug("%s()\n", __func__); | ||
85 | |||
86 | return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg); | ||
87 | } | ||
88 | |||
89 | static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; | ||
90 | #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int) | ||
91 | #define param_set_channel_mask ati_remote2_set_channel_mask | ||
92 | #define param_get_channel_mask ati_remote2_get_channel_mask | ||
93 | module_param(channel_mask, channel_mask, 0644); | ||
36 | MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); | 94 | MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); |
37 | 95 | ||
38 | static unsigned int mode_mask = 0x1F; | 96 | static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK; |
39 | module_param(mode_mask, uint, 0644); | 97 | #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int) |
98 | #define param_set_mode_mask ati_remote2_set_mode_mask | ||
99 | #define param_get_mode_mask ati_remote2_get_mode_mask | ||
100 | module_param(mode_mask, mode_mask, 0644); | ||
40 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); | 101 | MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); |
41 | 102 | ||
42 | static struct usb_device_id ati_remote2_id_table[] = { | 103 | static struct usb_device_id ati_remote2_id_table[] = { |
@@ -133,12 +194,18 @@ struct ati_remote2 { | |||
133 | u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)]; | 194 | u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)]; |
134 | 195 | ||
135 | unsigned int flags; | 196 | unsigned int flags; |
197 | |||
198 | unsigned int channel_mask; | ||
199 | unsigned int mode_mask; | ||
136 | }; | 200 | }; |
137 | 201 | ||
138 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id); | 202 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id); |
139 | static void ati_remote2_disconnect(struct usb_interface *interface); | 203 | static void ati_remote2_disconnect(struct usb_interface *interface); |
140 | static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message); | 204 | static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message); |
141 | static int ati_remote2_resume(struct usb_interface *interface); | 205 | static int ati_remote2_resume(struct usb_interface *interface); |
206 | static int ati_remote2_reset_resume(struct usb_interface *interface); | ||
207 | static int ati_remote2_pre_reset(struct usb_interface *interface); | ||
208 | static int ati_remote2_post_reset(struct usb_interface *interface); | ||
142 | 209 | ||
143 | static struct usb_driver ati_remote2_driver = { | 210 | static struct usb_driver ati_remote2_driver = { |
144 | .name = "ati_remote2", | 211 | .name = "ati_remote2", |
@@ -147,6 +214,9 @@ static struct usb_driver ati_remote2_driver = { | |||
147 | .id_table = ati_remote2_id_table, | 214 | .id_table = ati_remote2_id_table, |
148 | .suspend = ati_remote2_suspend, | 215 | .suspend = ati_remote2_suspend, |
149 | .resume = ati_remote2_resume, | 216 | .resume = ati_remote2_resume, |
217 | .reset_resume = ati_remote2_reset_resume, | ||
218 | .pre_reset = ati_remote2_pre_reset, | ||
219 | .post_reset = ati_remote2_post_reset, | ||
150 | .supports_autosuspend = 1, | 220 | .supports_autosuspend = 1, |
151 | }; | 221 | }; |
152 | 222 | ||
@@ -238,7 +308,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2) | |||
238 | 308 | ||
239 | channel = data[0] >> 4; | 309 | channel = data[0] >> 4; |
240 | 310 | ||
241 | if (!((1 << channel) & channel_mask)) | 311 | if (!((1 << channel) & ar2->channel_mask)) |
242 | return; | 312 | return; |
243 | 313 | ||
244 | mode = data[0] & 0x0F; | 314 | mode = data[0] & 0x0F; |
@@ -250,7 +320,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2) | |||
250 | return; | 320 | return; |
251 | } | 321 | } |
252 | 322 | ||
253 | if (!((1 << mode) & mode_mask)) | 323 | if (!((1 << mode) & ar2->mode_mask)) |
254 | return; | 324 | return; |
255 | 325 | ||
256 | input_event(idev, EV_REL, REL_X, (s8) data[1]); | 326 | input_event(idev, EV_REL, REL_X, (s8) data[1]); |
@@ -277,7 +347,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) | |||
277 | 347 | ||
278 | channel = data[0] >> 4; | 348 | channel = data[0] >> 4; |
279 | 349 | ||
280 | if (!((1 << channel) & channel_mask)) | 350 | if (!((1 << channel) & ar2->channel_mask)) |
281 | return; | 351 | return; |
282 | 352 | ||
283 | mode = data[0] & 0x0F; | 353 | mode = data[0] & 0x0F; |
@@ -305,7 +375,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2) | |||
305 | ar2->mode = mode; | 375 | ar2->mode = mode; |
306 | } | 376 | } |
307 | 377 | ||
308 | if (!((1 << mode) & mode_mask)) | 378 | if (!((1 << mode) & ar2->mode_mask)) |
309 | return; | 379 | return; |
310 | 380 | ||
311 | index = ati_remote2_lookup(hw_code); | 381 | index = ati_remote2_lookup(hw_code); |
@@ -410,7 +480,7 @@ static int ati_remote2_getkeycode(struct input_dev *idev, | |||
410 | int index, mode; | 480 | int index, mode; |
411 | 481 | ||
412 | mode = scancode >> 8; | 482 | mode = scancode >> 8; |
413 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask)) | 483 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) |
414 | return -EINVAL; | 484 | return -EINVAL; |
415 | 485 | ||
416 | index = ati_remote2_lookup(scancode & 0xFF); | 486 | index = ati_remote2_lookup(scancode & 0xFF); |
@@ -427,7 +497,7 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc | |||
427 | int index, mode, old_keycode; | 497 | int index, mode, old_keycode; |
428 | 498 | ||
429 | mode = scancode >> 8; | 499 | mode = scancode >> 8; |
430 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask)) | 500 | if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) |
431 | return -EINVAL; | 501 | return -EINVAL; |
432 | 502 | ||
433 | index = ati_remote2_lookup(scancode & 0xFF); | 503 | index = ati_remote2_lookup(scancode & 0xFF); |
@@ -550,7 +620,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2) | |||
550 | } | 620 | } |
551 | } | 621 | } |
552 | 622 | ||
553 | static int ati_remote2_setup(struct ati_remote2 *ar2) | 623 | static int ati_remote2_setup(struct ati_remote2 *ar2, unsigned int ch_mask) |
554 | { | 624 | { |
555 | int r, i, channel; | 625 | int r, i, channel; |
556 | 626 | ||
@@ -565,8 +635,8 @@ static int ati_remote2_setup(struct ati_remote2 *ar2) | |||
565 | 635 | ||
566 | channel = 0; | 636 | channel = 0; |
567 | for (i = 0; i < 16; i++) { | 637 | for (i = 0; i < 16; i++) { |
568 | if ((1 << i) & channel_mask) { | 638 | if ((1 << i) & ch_mask) { |
569 | if (!(~(1 << i) & 0xFFFF & channel_mask)) | 639 | if (!(~(1 << i) & ch_mask)) |
570 | channel = i + 1; | 640 | channel = i + 1; |
571 | break; | 641 | break; |
572 | } | 642 | } |
@@ -585,6 +655,99 @@ static int ati_remote2_setup(struct ati_remote2 *ar2) | |||
585 | return 0; | 655 | return 0; |
586 | } | 656 | } |
587 | 657 | ||
658 | static ssize_t ati_remote2_show_channel_mask(struct device *dev, | ||
659 | struct device_attribute *attr, | ||
660 | char *buf) | ||
661 | { | ||
662 | struct usb_device *udev = to_usb_device(dev); | ||
663 | struct usb_interface *intf = usb_ifnum_to_if(udev, 0); | ||
664 | struct ati_remote2 *ar2 = usb_get_intfdata(intf); | ||
665 | |||
666 | return sprintf(buf, "0x%04x\n", ar2->channel_mask); | ||
667 | } | ||
668 | |||
669 | static ssize_t ati_remote2_store_channel_mask(struct device *dev, | ||
670 | struct device_attribute *attr, | ||
671 | const char *buf, size_t count) | ||
672 | { | ||
673 | struct usb_device *udev = to_usb_device(dev); | ||
674 | struct usb_interface *intf = usb_ifnum_to_if(udev, 0); | ||
675 | struct ati_remote2 *ar2 = usb_get_intfdata(intf); | ||
676 | unsigned long mask; | ||
677 | int r; | ||
678 | |||
679 | if (strict_strtoul(buf, 0, &mask)) | ||
680 | return -EINVAL; | ||
681 | |||
682 | if (mask & ~ATI_REMOTE2_MAX_CHANNEL_MASK) | ||
683 | return -EINVAL; | ||
684 | |||
685 | r = usb_autopm_get_interface(ar2->intf[0]); | ||
686 | if (r) { | ||
687 | dev_err(&ar2->intf[0]->dev, | ||
688 | "%s(): usb_autopm_get_interface() = %d\n", __func__, r); | ||
689 | return r; | ||
690 | } | ||
691 | |||
692 | mutex_lock(&ati_remote2_mutex); | ||
693 | |||
694 | if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask)) | ||
695 | ar2->channel_mask = mask; | ||
696 | |||
697 | mutex_unlock(&ati_remote2_mutex); | ||
698 | |||
699 | usb_autopm_put_interface(ar2->intf[0]); | ||
700 | |||
701 | return count; | ||
702 | } | ||
703 | |||
704 | static ssize_t ati_remote2_show_mode_mask(struct device *dev, | ||
705 | struct device_attribute *attr, | ||
706 | char *buf) | ||
707 | { | ||
708 | struct usb_device *udev = to_usb_device(dev); | ||
709 | struct usb_interface *intf = usb_ifnum_to_if(udev, 0); | ||
710 | struct ati_remote2 *ar2 = usb_get_intfdata(intf); | ||
711 | |||
712 | return sprintf(buf, "0x%02x\n", ar2->mode_mask); | ||
713 | } | ||
714 | |||
715 | static ssize_t ati_remote2_store_mode_mask(struct device *dev, | ||
716 | struct device_attribute *attr, | ||
717 | const char *buf, size_t count) | ||
718 | { | ||
719 | struct usb_device *udev = to_usb_device(dev); | ||
720 | struct usb_interface *intf = usb_ifnum_to_if(udev, 0); | ||
721 | struct ati_remote2 *ar2 = usb_get_intfdata(intf); | ||
722 | unsigned long mask; | ||
723 | |||
724 | if (strict_strtoul(buf, 0, &mask)) | ||
725 | return -EINVAL; | ||
726 | |||
727 | if (mask & ~ATI_REMOTE2_MAX_MODE_MASK) | ||
728 | return -EINVAL; | ||
729 | |||
730 | ar2->mode_mask = mask; | ||
731 | |||
732 | return count; | ||
733 | } | ||
734 | |||
735 | static DEVICE_ATTR(channel_mask, 0644, ati_remote2_show_channel_mask, | ||
736 | ati_remote2_store_channel_mask); | ||
737 | |||
738 | static DEVICE_ATTR(mode_mask, 0644, ati_remote2_show_mode_mask, | ||
739 | ati_remote2_store_mode_mask); | ||
740 | |||
741 | static struct attribute *ati_remote2_attrs[] = { | ||
742 | &dev_attr_channel_mask.attr, | ||
743 | &dev_attr_mode_mask.attr, | ||
744 | NULL, | ||
745 | }; | ||
746 | |||
747 | static struct attribute_group ati_remote2_attr_group = { | ||
748 | .attrs = ati_remote2_attrs, | ||
749 | }; | ||
750 | |||
588 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) | 751 | static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) |
589 | { | 752 | { |
590 | struct usb_device *udev = interface_to_usbdev(interface); | 753 | struct usb_device *udev = interface_to_usbdev(interface); |
@@ -615,7 +778,10 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d | |||
615 | if (r) | 778 | if (r) |
616 | goto fail2; | 779 | goto fail2; |
617 | 780 | ||
618 | r = ati_remote2_setup(ar2); | 781 | ar2->channel_mask = channel_mask; |
782 | ar2->mode_mask = mode_mask; | ||
783 | |||
784 | r = ati_remote2_setup(ar2, ar2->channel_mask); | ||
619 | if (r) | 785 | if (r) |
620 | goto fail2; | 786 | goto fail2; |
621 | 787 | ||
@@ -624,19 +790,24 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d | |||
624 | 790 | ||
625 | strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name)); | 791 | strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name)); |
626 | 792 | ||
627 | r = ati_remote2_input_init(ar2); | 793 | r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); |
628 | if (r) | 794 | if (r) |
629 | goto fail2; | 795 | goto fail2; |
630 | 796 | ||
797 | r = ati_remote2_input_init(ar2); | ||
798 | if (r) | ||
799 | goto fail3; | ||
800 | |||
631 | usb_set_intfdata(interface, ar2); | 801 | usb_set_intfdata(interface, ar2); |
632 | 802 | ||
633 | interface->needs_remote_wakeup = 1; | 803 | interface->needs_remote_wakeup = 1; |
634 | 804 | ||
635 | return 0; | 805 | return 0; |
636 | 806 | ||
807 | fail3: | ||
808 | sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); | ||
637 | fail2: | 809 | fail2: |
638 | ati_remote2_urb_cleanup(ar2); | 810 | ati_remote2_urb_cleanup(ar2); |
639 | |||
640 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | 811 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); |
641 | fail1: | 812 | fail1: |
642 | kfree(ar2); | 813 | kfree(ar2); |
@@ -657,6 +828,8 @@ static void ati_remote2_disconnect(struct usb_interface *interface) | |||
657 | 828 | ||
658 | input_unregister_device(ar2->idev); | 829 | input_unregister_device(ar2->idev); |
659 | 830 | ||
831 | sysfs_remove_group(&ar2->udev->dev.kobj, &ati_remote2_attr_group); | ||
832 | |||
660 | ati_remote2_urb_cleanup(ar2); | 833 | ati_remote2_urb_cleanup(ar2); |
661 | 834 | ||
662 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | 835 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); |
@@ -715,6 +888,78 @@ static int ati_remote2_resume(struct usb_interface *interface) | |||
715 | return r; | 888 | return r; |
716 | } | 889 | } |
717 | 890 | ||
891 | static int ati_remote2_reset_resume(struct usb_interface *interface) | ||
892 | { | ||
893 | struct ati_remote2 *ar2; | ||
894 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
895 | int r = 0; | ||
896 | |||
897 | if (alt->desc.bInterfaceNumber) | ||
898 | return 0; | ||
899 | |||
900 | ar2 = usb_get_intfdata(interface); | ||
901 | |||
902 | dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__); | ||
903 | |||
904 | mutex_lock(&ati_remote2_mutex); | ||
905 | |||
906 | r = ati_remote2_setup(ar2, ar2->channel_mask); | ||
907 | if (r) | ||
908 | goto out; | ||
909 | |||
910 | if (ar2->flags & ATI_REMOTE2_OPENED) | ||
911 | r = ati_remote2_submit_urbs(ar2); | ||
912 | |||
913 | if (!r) | ||
914 | ar2->flags &= ~ATI_REMOTE2_SUSPENDED; | ||
915 | |||
916 | out: | ||
917 | mutex_unlock(&ati_remote2_mutex); | ||
918 | |||
919 | return r; | ||
920 | } | ||
921 | |||
922 | static int ati_remote2_pre_reset(struct usb_interface *interface) | ||
923 | { | ||
924 | struct ati_remote2 *ar2; | ||
925 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
926 | |||
927 | if (alt->desc.bInterfaceNumber) | ||
928 | return 0; | ||
929 | |||
930 | ar2 = usb_get_intfdata(interface); | ||
931 | |||
932 | dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__); | ||
933 | |||
934 | mutex_lock(&ati_remote2_mutex); | ||
935 | |||
936 | if (ar2->flags == ATI_REMOTE2_OPENED) | ||
937 | ati_remote2_kill_urbs(ar2); | ||
938 | |||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | static int ati_remote2_post_reset(struct usb_interface *interface) | ||
943 | { | ||
944 | struct ati_remote2 *ar2; | ||
945 | struct usb_host_interface *alt = interface->cur_altsetting; | ||
946 | int r = 0; | ||
947 | |||
948 | if (alt->desc.bInterfaceNumber) | ||
949 | return 0; | ||
950 | |||
951 | ar2 = usb_get_intfdata(interface); | ||
952 | |||
953 | dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__); | ||
954 | |||
955 | if (ar2->flags == ATI_REMOTE2_OPENED) | ||
956 | r = ati_remote2_submit_urbs(ar2); | ||
957 | |||
958 | mutex_unlock(&ati_remote2_mutex); | ||
959 | |||
960 | return r; | ||
961 | } | ||
962 | |||
718 | static int __init ati_remote2_init(void) | 963 | static int __init ati_remote2_init(void) |
719 | { | 964 | { |
720 | int r; | 965 | int r; |
diff --git a/drivers/input/misc/rb532_button.c b/drivers/input/misc/rb532_button.c new file mode 100644 index 000000000000..e2c7f622a0b5 --- /dev/null +++ b/drivers/input/misc/rb532_button.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * Support for the S1 button on Routerboard 532 | ||
3 | * | ||
4 | * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org> | ||
5 | */ | ||
6 | |||
7 | #include <linux/input-polldev.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/platform_device.h> | ||
10 | |||
11 | #include <asm/mach-rc32434/gpio.h> | ||
12 | #include <asm/mach-rc32434/rb.h> | ||
13 | |||
14 | #define DRV_NAME "rb532-button" | ||
15 | |||
16 | #define RB532_BTN_RATE 100 /* msec */ | ||
17 | #define RB532_BTN_KSYM BTN_0 | ||
18 | |||
19 | /* The S1 button state is provided by GPIO pin 1. But as this | ||
20 | * pin is also used for uart input as alternate function, the | ||
21 | * operational modes must be switched first: | ||
22 | * 1) disable uart using set_latch_u5() | ||
23 | * 2) turn off alternate function implicitly through | ||
24 | * gpio_direction_input() | ||
25 | * 3) read the GPIO's current value | ||
26 | * 4) undo step 2 by enabling alternate function (in this | ||
27 | * mode the GPIO direction is fixed, so no change needed) | ||
28 | * 5) turn on uart again | ||
29 | * The GPIO value occurs to be inverted, so pin high means | ||
30 | * button is not pressed. | ||
31 | */ | ||
32 | static bool rb532_button_pressed(void) | ||
33 | { | ||
34 | int val; | ||
35 | |||
36 | set_latch_u5(0, LO_FOFF); | ||
37 | gpio_direction_input(GPIO_BTN_S1); | ||
38 | |||
39 | val = gpio_get_value(GPIO_BTN_S1); | ||
40 | |||
41 | rb532_gpio_set_func(GPIO_BTN_S1); | ||
42 | set_latch_u5(LO_FOFF, 0); | ||
43 | |||
44 | return !val; | ||
45 | } | ||
46 | |||
47 | static void rb532_button_poll(struct input_polled_dev *poll_dev) | ||
48 | { | ||
49 | input_report_key(poll_dev->input, RB532_BTN_KSYM, | ||
50 | rb532_button_pressed()); | ||
51 | input_sync(poll_dev->input); | ||
52 | } | ||
53 | |||
54 | static int __devinit rb532_button_probe(struct platform_device *pdev) | ||
55 | { | ||
56 | struct input_polled_dev *poll_dev; | ||
57 | int error; | ||
58 | |||
59 | poll_dev = input_allocate_polled_device(); | ||
60 | if (!poll_dev) | ||
61 | return -ENOMEM; | ||
62 | |||
63 | poll_dev->poll = rb532_button_poll; | ||
64 | poll_dev->poll_interval = RB532_BTN_RATE; | ||
65 | |||
66 | poll_dev->input->name = "rb532 button"; | ||
67 | poll_dev->input->phys = "rb532/button0"; | ||
68 | poll_dev->input->id.bustype = BUS_HOST; | ||
69 | poll_dev->input->dev.parent = &pdev->dev; | ||
70 | |||
71 | dev_set_drvdata(&pdev->dev, poll_dev); | ||
72 | |||
73 | input_set_capability(poll_dev->input, EV_KEY, RB532_BTN_KSYM); | ||
74 | |||
75 | error = input_register_polled_device(poll_dev); | ||
76 | if (error) { | ||
77 | input_free_polled_device(poll_dev); | ||
78 | return error; | ||
79 | } | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | static int __devexit rb532_button_remove(struct platform_device *pdev) | ||
85 | { | ||
86 | struct input_polled_dev *poll_dev = dev_get_drvdata(&pdev->dev); | ||
87 | |||
88 | input_unregister_polled_device(poll_dev); | ||
89 | input_free_polled_device(poll_dev); | ||
90 | dev_set_drvdata(&pdev->dev, NULL); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static struct platform_driver rb532_button_driver = { | ||
96 | .probe = rb532_button_probe, | ||
97 | .remove = __devexit_p(rb532_button_remove), | ||
98 | .driver = { | ||
99 | .name = DRV_NAME, | ||
100 | .owner = THIS_MODULE, | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static int __init rb532_button_init(void) | ||
105 | { | ||
106 | return platform_driver_register(&rb532_button_driver); | ||
107 | } | ||
108 | |||
109 | static void __exit rb532_button_exit(void) | ||
110 | { | ||
111 | platform_driver_unregister(&rb532_button_driver); | ||
112 | } | ||
113 | |||
114 | module_init(rb532_button_init); | ||
115 | module_exit(rb532_button_exit); | ||
116 | |||
117 | MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>"); | ||
118 | MODULE_LICENSE("GPL"); | ||
119 | MODULE_DESCRIPTION("Support for S1 button on Routerboard 532"); | ||
120 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c new file mode 100644 index 000000000000..5bb3ab51b8c6 --- /dev/null +++ b/drivers/input/misc/rotary_encoder.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * rotary_encoder.c | ||
3 | * | ||
4 | * (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
5 | * | ||
6 | * state machine code inspired by code from Tim Ruetz | ||
7 | * | ||
8 | * A generic driver for rotary encoders connected to GPIO lines. | ||
9 | * See file:Documentation/input/rotary_encoder.txt for more information | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/rotary_encoder.h> | ||
25 | |||
26 | #define DRV_NAME "rotary-encoder" | ||
27 | |||
28 | struct rotary_encoder { | ||
29 | unsigned int irq_a; | ||
30 | unsigned int irq_b; | ||
31 | unsigned int pos; | ||
32 | unsigned int armed; | ||
33 | unsigned int dir; | ||
34 | struct input_dev *input; | ||
35 | struct rotary_encoder_platform_data *pdata; | ||
36 | }; | ||
37 | |||
38 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | ||
39 | { | ||
40 | struct rotary_encoder *encoder = dev_id; | ||
41 | struct rotary_encoder_platform_data *pdata = encoder->pdata; | ||
42 | int a = !!gpio_get_value(pdata->gpio_a); | ||
43 | int b = !!gpio_get_value(pdata->gpio_b); | ||
44 | int state; | ||
45 | |||
46 | a ^= pdata->inverted_a; | ||
47 | b ^= pdata->inverted_b; | ||
48 | state = (a << 1) | b; | ||
49 | |||
50 | switch (state) { | ||
51 | |||
52 | case 0x0: | ||
53 | if (!encoder->armed) | ||
54 | break; | ||
55 | |||
56 | if (encoder->dir) { | ||
57 | /* turning counter-clockwise */ | ||
58 | encoder->pos += pdata->steps; | ||
59 | encoder->pos--; | ||
60 | encoder->pos %= pdata->steps; | ||
61 | } else { | ||
62 | /* turning clockwise */ | ||
63 | encoder->pos++; | ||
64 | encoder->pos %= pdata->steps; | ||
65 | } | ||
66 | |||
67 | input_report_abs(encoder->input, pdata->axis, encoder->pos); | ||
68 | input_sync(encoder->input); | ||
69 | |||
70 | encoder->armed = 0; | ||
71 | break; | ||
72 | |||
73 | case 0x1: | ||
74 | case 0x2: | ||
75 | if (encoder->armed) | ||
76 | encoder->dir = state - 1; | ||
77 | break; | ||
78 | |||
79 | case 0x3: | ||
80 | encoder->armed = 1; | ||
81 | break; | ||
82 | } | ||
83 | |||
84 | return IRQ_HANDLED; | ||
85 | } | ||
86 | |||
87 | static int __devinit rotary_encoder_probe(struct platform_device *pdev) | ||
88 | { | ||
89 | struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; | ||
90 | struct rotary_encoder *encoder; | ||
91 | struct input_dev *input; | ||
92 | int err; | ||
93 | |||
94 | if (!pdata || !pdata->steps) { | ||
95 | dev_err(&pdev->dev, "invalid platform data\n"); | ||
96 | return -ENOENT; | ||
97 | } | ||
98 | |||
99 | encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL); | ||
100 | input = input_allocate_device(); | ||
101 | if (!encoder || !input) { | ||
102 | dev_err(&pdev->dev, "failed to allocate memory for device\n"); | ||
103 | err = -ENOMEM; | ||
104 | goto exit_free_mem; | ||
105 | } | ||
106 | |||
107 | encoder->input = input; | ||
108 | encoder->pdata = pdata; | ||
109 | encoder->irq_a = gpio_to_irq(pdata->gpio_a); | ||
110 | encoder->irq_b = gpio_to_irq(pdata->gpio_b); | ||
111 | |||
112 | /* create and register the input driver */ | ||
113 | input->name = pdev->name; | ||
114 | input->id.bustype = BUS_HOST; | ||
115 | input->dev.parent = &pdev->dev; | ||
116 | input->evbit[0] = BIT_MASK(EV_ABS); | ||
117 | input_set_abs_params(encoder->input, | ||
118 | pdata->axis, 0, pdata->steps, 0, 1); | ||
119 | |||
120 | err = input_register_device(input); | ||
121 | if (err) { | ||
122 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
123 | goto exit_free_mem; | ||
124 | } | ||
125 | |||
126 | /* request the GPIOs */ | ||
127 | err = gpio_request(pdata->gpio_a, DRV_NAME); | ||
128 | if (err) { | ||
129 | dev_err(&pdev->dev, "unable to request GPIO %d\n", | ||
130 | pdata->gpio_a); | ||
131 | goto exit_unregister_input; | ||
132 | } | ||
133 | |||
134 | err = gpio_request(pdata->gpio_b, DRV_NAME); | ||
135 | if (err) { | ||
136 | dev_err(&pdev->dev, "unable to request GPIO %d\n", | ||
137 | pdata->gpio_b); | ||
138 | goto exit_free_gpio_a; | ||
139 | } | ||
140 | |||
141 | /* request the IRQs */ | ||
142 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, | ||
143 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | ||
144 | DRV_NAME, encoder); | ||
145 | if (err) { | ||
146 | dev_err(&pdev->dev, "unable to request IRQ %d\n", | ||
147 | encoder->irq_a); | ||
148 | goto exit_free_gpio_b; | ||
149 | } | ||
150 | |||
151 | err = request_irq(encoder->irq_b, &rotary_encoder_irq, | ||
152 | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | ||
153 | DRV_NAME, encoder); | ||
154 | if (err) { | ||
155 | dev_err(&pdev->dev, "unable to request IRQ %d\n", | ||
156 | encoder->irq_b); | ||
157 | goto exit_free_irq_a; | ||
158 | } | ||
159 | |||
160 | platform_set_drvdata(pdev, encoder); | ||
161 | |||
162 | return 0; | ||
163 | |||
164 | exit_free_irq_a: | ||
165 | free_irq(encoder->irq_a, encoder); | ||
166 | exit_free_gpio_b: | ||
167 | gpio_free(pdata->gpio_b); | ||
168 | exit_free_gpio_a: | ||
169 | gpio_free(pdata->gpio_a); | ||
170 | exit_unregister_input: | ||
171 | input_unregister_device(input); | ||
172 | input = NULL; /* so we don't try to free it */ | ||
173 | exit_free_mem: | ||
174 | input_free_device(input); | ||
175 | kfree(encoder); | ||
176 | return err; | ||
177 | } | ||
178 | |||
179 | static int __devexit rotary_encoder_remove(struct platform_device *pdev) | ||
180 | { | ||
181 | struct rotary_encoder *encoder = platform_get_drvdata(pdev); | ||
182 | struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; | ||
183 | |||
184 | free_irq(encoder->irq_a, encoder); | ||
185 | free_irq(encoder->irq_b, encoder); | ||
186 | gpio_free(pdata->gpio_a); | ||
187 | gpio_free(pdata->gpio_b); | ||
188 | input_unregister_device(encoder->input); | ||
189 | platform_set_drvdata(pdev, NULL); | ||
190 | kfree(encoder); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static struct platform_driver rotary_encoder_driver = { | ||
196 | .probe = rotary_encoder_probe, | ||
197 | .remove = __devexit_p(rotary_encoder_remove), | ||
198 | .driver = { | ||
199 | .name = DRV_NAME, | ||
200 | .owner = THIS_MODULE, | ||
201 | } | ||
202 | }; | ||
203 | |||
204 | static int __init rotary_encoder_init(void) | ||
205 | { | ||
206 | return platform_driver_register(&rotary_encoder_driver); | ||
207 | } | ||
208 | |||
209 | static void __exit rotary_encoder_exit(void) | ||
210 | { | ||
211 | platform_driver_unregister(&rotary_encoder_driver); | ||
212 | } | ||
213 | |||
214 | module_init(rotary_encoder_init); | ||
215 | module_exit(rotary_encoder_exit); | ||
216 | |||
217 | MODULE_ALIAS("platform:" DRV_NAME); | ||
218 | MODULE_DESCRIPTION("GPIO rotary encoder driver"); | ||
219 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | ||
220 | MODULE_LICENSE("GPL v2"); | ||
221 | |||
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 4f38e6f7dfdd..c66cc3d08c2f 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -292,4 +292,15 @@ config MOUSE_PXA930_TRKBALL | |||
292 | help | 292 | help |
293 | Say Y here to support PXA930 Trackball mouse. | 293 | Say Y here to support PXA930 Trackball mouse. |
294 | 294 | ||
295 | config MOUSE_MAPLE | ||
296 | tristate "Maple mouse (for the Dreamcast)" | ||
297 | depends on MAPLE | ||
298 | help | ||
299 | This driver supports the Maple mouse on the SEGA Dreamcast. | ||
300 | |||
301 | Most Dreamcast users, who have a mouse, will say Y here. | ||
302 | |||
303 | To compile this driver as a module choose M here: the module will be | ||
304 | called maplemouse. | ||
305 | |||
295 | endif | 306 | endif |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 8c8a1f236e28..472189468d67 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
@@ -6,18 +6,19 @@ | |||
6 | 6 | ||
7 | obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o | 7 | obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o |
8 | obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o | 8 | obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o |
9 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o | ||
10 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o | 9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o |
11 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o | 10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o |
11 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o | ||
12 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o | ||
12 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 13 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
13 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o | 14 | obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o |
15 | obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o | ||
14 | obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o | 16 | obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o |
15 | obj-$(CONFIG_MOUSE_PS2) += psmouse.o | 17 | obj-$(CONFIG_MOUSE_PS2) += psmouse.o |
16 | obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o | 18 | obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o |
19 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o | ||
17 | obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o | 20 | obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o |
18 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o | ||
19 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o | 21 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o |
20 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o | ||
21 | 22 | ||
22 | psmouse-objs := psmouse-base.o synaptics.o | 23 | psmouse-objs := psmouse-base.o synaptics.o |
23 | 24 | ||
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 55cd0fa68339..a1ad2f1a7bb3 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -472,7 +472,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse) | |||
472 | return -EIO; | 472 | return -EIO; |
473 | } | 473 | } |
474 | 474 | ||
475 | hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]); | 475 | hgpk_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]); |
476 | 476 | ||
477 | /* HGPK signature: 0x67, 0x00, 0x<model> */ | 477 | /* HGPK signature: 0x67, 0x00, 0x<model> */ |
478 | if (param[0] != 0x67 || param[1] != 0x00) | 478 | if (param[0] != 0x67 || param[1] != 0x00) |
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c new file mode 100644 index 000000000000..d196abfb68bc --- /dev/null +++ b/drivers/input/mouse/maplemouse.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /* | ||
2 | * SEGA Dreamcast mouse driver | ||
3 | * Based on drivers/usb/usbmouse.c | ||
4 | * | ||
5 | * Copyright Yaegashi Takeshi, 2001 | ||
6 | * Adrian McMenamin, 2008 | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/slab.h> | ||
11 | #include <linux/input.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/timer.h> | ||
15 | #include <linux/maple.h> | ||
16 | |||
17 | MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>"); | ||
18 | MODULE_DESCRIPTION("SEGA Dreamcast mouse driver"); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
21 | struct dc_mouse { | ||
22 | struct input_dev *dev; | ||
23 | struct maple_device *mdev; | ||
24 | }; | ||
25 | |||
26 | static void dc_mouse_callback(struct mapleq *mq) | ||
27 | { | ||
28 | int buttons, relx, rely, relz; | ||
29 | struct maple_device *mapledev = mq->dev; | ||
30 | struct dc_mouse *mse = maple_get_drvdata(mapledev); | ||
31 | struct input_dev *dev = mse->dev; | ||
32 | unsigned char *res = mq->recvbuf; | ||
33 | |||
34 | buttons = ~res[8]; | ||
35 | relx = *(unsigned short *)(res + 12) - 512; | ||
36 | rely = *(unsigned short *)(res + 14) - 512; | ||
37 | relz = *(unsigned short *)(res + 16) - 512; | ||
38 | |||
39 | input_report_key(dev, BTN_LEFT, buttons & 4); | ||
40 | input_report_key(dev, BTN_MIDDLE, buttons & 9); | ||
41 | input_report_key(dev, BTN_RIGHT, buttons & 2); | ||
42 | input_report_rel(dev, REL_X, relx); | ||
43 | input_report_rel(dev, REL_Y, rely); | ||
44 | input_report_rel(dev, REL_WHEEL, relz); | ||
45 | input_sync(dev); | ||
46 | } | ||
47 | |||
48 | static int dc_mouse_open(struct input_dev *dev) | ||
49 | { | ||
50 | struct dc_mouse *mse = dev->dev.platform_data; | ||
51 | |||
52 | maple_getcond_callback(mse->mdev, dc_mouse_callback, HZ/50, | ||
53 | MAPLE_FUNC_MOUSE); | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static void dc_mouse_close(struct input_dev *dev) | ||
59 | { | ||
60 | struct dc_mouse *mse = dev->dev.platform_data; | ||
61 | |||
62 | maple_getcond_callback(mse->mdev, dc_mouse_callback, 0, | ||
63 | MAPLE_FUNC_MOUSE); | ||
64 | } | ||
65 | |||
66 | |||
67 | static int __devinit probe_maple_mouse(struct device *dev) | ||
68 | { | ||
69 | struct maple_device *mdev = to_maple_dev(dev); | ||
70 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | ||
71 | struct input_dev *input_dev; | ||
72 | struct dc_mouse *mse; | ||
73 | int error; | ||
74 | |||
75 | mse = kzalloc(sizeof(struct dc_mouse), GFP_KERNEL); | ||
76 | input_dev = input_allocate_device(); | ||
77 | |||
78 | if (!mse || !input_dev) { | ||
79 | error = -ENOMEM; | ||
80 | goto fail; | ||
81 | } | ||
82 | |||
83 | mse->dev = input_dev; | ||
84 | mse->mdev = mdev; | ||
85 | |||
86 | input_set_drvdata(input_dev, mse); | ||
87 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | ||
88 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | | ||
89 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | ||
90 | input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) | | ||
91 | BIT_MASK(REL_WHEEL); | ||
92 | input_dev->name = mdev->product_name; | ||
93 | input_dev->id.bustype = BUS_HOST; | ||
94 | input_dev->open = dc_mouse_open; | ||
95 | input_dev->close = dc_mouse_close; | ||
96 | |||
97 | mdev->driver = mdrv; | ||
98 | maple_set_drvdata(mdev, mse); | ||
99 | |||
100 | error = input_register_device(input_dev); | ||
101 | if (error) | ||
102 | goto fail; | ||
103 | |||
104 | return 0; | ||
105 | |||
106 | fail: | ||
107 | input_free_device(input_dev); | ||
108 | maple_set_drvdata(mdev, NULL); | ||
109 | kfree(mse); | ||
110 | mdev->driver = NULL; | ||
111 | return error; | ||
112 | } | ||
113 | |||
114 | static int __devexit remove_maple_mouse(struct device *dev) | ||
115 | { | ||
116 | struct maple_device *mdev = to_maple_dev(dev); | ||
117 | struct dc_mouse *mse = maple_get_drvdata(mdev); | ||
118 | |||
119 | mdev->callback = NULL; | ||
120 | input_unregister_device(mse->dev); | ||
121 | maple_set_drvdata(mdev, NULL); | ||
122 | kfree(mse); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static struct maple_driver dc_mouse_driver = { | ||
128 | .function = MAPLE_FUNC_MOUSE, | ||
129 | .drv = { | ||
130 | .name = "Dreamcast_mouse", | ||
131 | .probe = probe_maple_mouse, | ||
132 | .remove = __devexit_p(remove_maple_mouse), | ||
133 | }, | ||
134 | }; | ||
135 | |||
136 | static int __init dc_mouse_init(void) | ||
137 | { | ||
138 | return maple_driver_register(&dc_mouse_driver); | ||
139 | } | ||
140 | |||
141 | static void __exit dc_mouse_exit(void) | ||
142 | { | ||
143 | maple_driver_unregister(&dc_mouse_driver); | ||
144 | } | ||
145 | |||
146 | module_init(dc_mouse_init); | ||
147 | module_exit(dc_mouse_exit); | ||
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index fd09c8df81f2..3941f97cfa60 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c | |||
@@ -108,14 +108,10 @@ static int pc110pad_open(struct input_dev *dev) | |||
108 | */ | 108 | */ |
109 | static int __init pc110pad_init(void) | 109 | static int __init pc110pad_init(void) |
110 | { | 110 | { |
111 | struct pci_dev *dev; | ||
112 | int err; | 111 | int err; |
113 | 112 | ||
114 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); | 113 | if (!no_pci_devices()) |
115 | if (dev) { | ||
116 | pci_dev_put(dev); | ||
117 | return -ENODEV; | 114 | return -ENODEV; |
118 | } | ||
119 | 115 | ||
120 | if (!request_region(pc110pad_io, 4, "pc110pad")) { | 116 | if (!request_region(pc110pad_io, 4, "pc110pad")) { |
121 | printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n", | 117 | printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n", |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index bfe49243f38b..1c9410d1822c 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -819,6 +819,7 @@ static const struct parisc_device_id hp_sdc_tbl[] = { | |||
819 | MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); | 819 | MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); |
820 | 820 | ||
821 | static int __init hp_sdc_init_hppa(struct parisc_device *d); | 821 | static int __init hp_sdc_init_hppa(struct parisc_device *d); |
822 | static struct delayed_work moduleloader_work; | ||
822 | 823 | ||
823 | static struct parisc_driver hp_sdc_driver = { | 824 | static struct parisc_driver hp_sdc_driver = { |
824 | .name = "hp_sdc", | 825 | .name = "hp_sdc", |
@@ -930,8 +931,15 @@ static int __init hp_sdc_init(void) | |||
930 | 931 | ||
931 | #if defined(__hppa__) | 932 | #if defined(__hppa__) |
932 | 933 | ||
934 | static void request_module_delayed(struct work_struct *work) | ||
935 | { | ||
936 | request_module("hp_sdc_mlc"); | ||
937 | } | ||
938 | |||
933 | static int __init hp_sdc_init_hppa(struct parisc_device *d) | 939 | static int __init hp_sdc_init_hppa(struct parisc_device *d) |
934 | { | 940 | { |
941 | int ret; | ||
942 | |||
935 | if (!d) | 943 | if (!d) |
936 | return 1; | 944 | return 1; |
937 | if (hp_sdc.dev != NULL) | 945 | if (hp_sdc.dev != NULL) |
@@ -944,13 +952,26 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d) | |||
944 | hp_sdc.data_io = d->hpa.start + 0x800; | 952 | hp_sdc.data_io = d->hpa.start + 0x800; |
945 | hp_sdc.status_io = d->hpa.start + 0x801; | 953 | hp_sdc.status_io = d->hpa.start + 0x801; |
946 | 954 | ||
947 | return hp_sdc_init(); | 955 | INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); |
956 | |||
957 | ret = hp_sdc_init(); | ||
958 | /* after sucessfull initialization give SDC some time to settle | ||
959 | * and then load the hp_sdc_mlc upper layer driver */ | ||
960 | if (!ret) | ||
961 | schedule_delayed_work(&moduleloader_work, | ||
962 | msecs_to_jiffies(2000)); | ||
963 | |||
964 | return ret; | ||
948 | } | 965 | } |
949 | 966 | ||
950 | #endif /* __hppa__ */ | 967 | #endif /* __hppa__ */ |
951 | 968 | ||
952 | static void hp_sdc_exit(void) | 969 | static void hp_sdc_exit(void) |
953 | { | 970 | { |
971 | /* do nothing if we don't have a SDC */ | ||
972 | if (!hp_sdc.dev) | ||
973 | return; | ||
974 | |||
954 | write_lock_irq(&hp_sdc.lock); | 975 | write_lock_irq(&hp_sdc.lock); |
955 | 976 | ||
956 | /* Turn off all maskable "sub-function" irq's. */ | 977 | /* Turn off all maskable "sub-function" irq's. */ |
@@ -969,6 +990,7 @@ static void hp_sdc_exit(void) | |||
969 | tasklet_kill(&hp_sdc.task); | 990 | tasklet_kill(&hp_sdc.task); |
970 | 991 | ||
971 | #if defined(__hppa__) | 992 | #if defined(__hppa__) |
993 | cancel_delayed_work_sync(&moduleloader_work); | ||
972 | if (unregister_parisc_driver(&hp_sdc_driver)) | 994 | if (unregister_parisc_driver(&hp_sdc_driver)) |
973 | printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); | 995 | printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); |
974 | #endif | 996 | #endif |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 6fa2deff7446..fb8a3cd3ffd0 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -151,6 +151,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
151 | DMI_MATCH(DMI_PRODUCT_VERSION, "01"), | 151 | DMI_MATCH(DMI_PRODUCT_VERSION, "01"), |
152 | }, | 152 | }, |
153 | }, | 153 | }, |
154 | { | ||
155 | .ident = "HP DV9700", | ||
156 | .matches = { | ||
157 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
158 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), | ||
159 | DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"), | ||
160 | }, | ||
161 | }, | ||
154 | { } | 162 | { } |
155 | }; | 163 | }; |
156 | 164 | ||
@@ -369,6 +377,24 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
369 | { } | 377 | { } |
370 | }; | 378 | }; |
371 | 379 | ||
380 | static struct dmi_system_id __initdata i8042_dmi_reset_table[] = { | ||
381 | { | ||
382 | .ident = "MSI Wind U-100", | ||
383 | .matches = { | ||
384 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), | ||
385 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), | ||
386 | }, | ||
387 | }, | ||
388 | { | ||
389 | .ident = "LG Electronics X110", | ||
390 | .matches = { | ||
391 | DMI_MATCH(DMI_BOARD_NAME, "X110"), | ||
392 | DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), | ||
393 | }, | ||
394 | }, | ||
395 | { } | ||
396 | }; | ||
397 | |||
372 | #ifdef CONFIG_PNP | 398 | #ifdef CONFIG_PNP |
373 | static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | 399 | static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { |
374 | { | 400 | { |
@@ -378,6 +404,13 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | |||
378 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | 404 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), |
379 | }, | 405 | }, |
380 | }, | 406 | }, |
407 | { | ||
408 | .ident = "MSI Wind U-100", | ||
409 | .matches = { | ||
410 | DMI_MATCH(DMI_BOARD_NAME, "U-100"), | ||
411 | DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), | ||
412 | }, | ||
413 | }, | ||
381 | { } | 414 | { } |
382 | }; | 415 | }; |
383 | #endif | 416 | #endif |
@@ -690,6 +723,9 @@ static int __init i8042_platform_init(void) | |||
690 | #endif | 723 | #endif |
691 | 724 | ||
692 | #ifdef CONFIG_X86 | 725 | #ifdef CONFIG_X86 |
726 | if (dmi_check_system(i8042_dmi_reset_table)) | ||
727 | i8042_reset = 1; | ||
728 | |||
693 | if (dmi_check_system(i8042_dmi_noloop_table)) | 729 | if (dmi_check_system(i8042_dmi_noloop_table)) |
694 | i8042_noloop = 1; | 730 | i8042_noloop = 1; |
695 | 731 | ||
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 170f71ee5772..3cffb704e374 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -712,22 +712,43 @@ static int i8042_controller_check(void) | |||
712 | static int i8042_controller_selftest(void) | 712 | static int i8042_controller_selftest(void) |
713 | { | 713 | { |
714 | unsigned char param; | 714 | unsigned char param; |
715 | int i = 0; | ||
715 | 716 | ||
716 | if (!i8042_reset) | 717 | if (!i8042_reset) |
717 | return 0; | 718 | return 0; |
718 | 719 | ||
719 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | 720 | /* |
720 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | 721 | * We try this 5 times; on some really fragile systems this does not |
721 | return -ENODEV; | 722 | * take the first time... |
722 | } | 723 | */ |
724 | do { | ||
725 | |||
726 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | ||
727 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | ||
728 | return -ENODEV; | ||
729 | } | ||
730 | |||
731 | if (param == I8042_RET_CTL_TEST) | ||
732 | return 0; | ||
723 | 733 | ||
724 | if (param != I8042_RET_CTL_TEST) { | ||
725 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | 734 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", |
726 | param, I8042_RET_CTL_TEST); | 735 | param, I8042_RET_CTL_TEST); |
727 | return -EIO; | 736 | msleep(50); |
728 | } | 737 | } while (i++ < 5); |
729 | 738 | ||
739 | #ifdef CONFIG_X86 | ||
740 | /* | ||
741 | * On x86, we don't fail entire i8042 initialization if controller | ||
742 | * reset fails in hopes that keyboard port will still be functional | ||
743 | * and user will still get a working keyboard. This is especially | ||
744 | * important on netbooks. On other arches we trust hardware more. | ||
745 | */ | ||
746 | printk(KERN_INFO | ||
747 | "i8042: giving up on controller selftest, continuing anyway...\n"); | ||
730 | return 0; | 748 | return 0; |
749 | #else | ||
750 | return -EIO; | ||
751 | #endif | ||
731 | } | 752 | } |
732 | 753 | ||
733 | /* | 754 | /* |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index bb6486a8c070..b01fd61dadcc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -29,6 +29,51 @@ config TOUCHSCREEN_ADS7846 | |||
29 | To compile this driver as a module, choose M here: the | 29 | To compile this driver as a module, choose M here: the |
30 | module will be called ads7846. | 30 | module will be called ads7846. |
31 | 31 | ||
32 | config TOUCHSCREEN_AD7877 | ||
33 | tristate "AD7877 based touchscreens" | ||
34 | depends on SPI_MASTER | ||
35 | help | ||
36 | Say Y here if you have a touchscreen interface using the | ||
37 | AD7877 controller, and your board-specific initialization | ||
38 | code includes that in its table of SPI devices. | ||
39 | |||
40 | If unsure, say N (but it's safe to say "Y"). | ||
41 | |||
42 | To compile this driver as a module, choose M here: the | ||
43 | module will be called ad7877. | ||
44 | |||
45 | config TOUCHSCREEN_AD7879_I2C | ||
46 | tristate "AD7879 based touchscreens: AD7879-1 I2C Interface" | ||
47 | depends on I2C | ||
48 | select TOUCHSCREEN_AD7879 | ||
49 | help | ||
50 | Say Y here if you have a touchscreen interface using the | ||
51 | AD7879-1 controller, and your board-specific initialization | ||
52 | code includes that in its table of I2C devices. | ||
53 | |||
54 | If unsure, say N (but it's safe to say "Y"). | ||
55 | |||
56 | To compile this driver as a module, choose M here: the | ||
57 | module will be called ad7879. | ||
58 | |||
59 | config TOUCHSCREEN_AD7879_SPI | ||
60 | tristate "AD7879 based touchscreens: AD7879 SPI Interface" | ||
61 | depends on SPI_MASTER && TOUCHSCREEN_AD7879_I2C = n | ||
62 | select TOUCHSCREEN_AD7879 | ||
63 | help | ||
64 | Say Y here if you have a touchscreen interface using the | ||
65 | AD7879 controller, and your board-specific initialization | ||
66 | code includes that in its table of SPI devices. | ||
67 | |||
68 | If unsure, say N (but it's safe to say "Y"). | ||
69 | |||
70 | To compile this driver as a module, choose M here: the | ||
71 | module will be called ad7879. | ||
72 | |||
73 | config TOUCHSCREEN_AD7879 | ||
74 | tristate | ||
75 | default n | ||
76 | |||
32 | config TOUCHSCREEN_BITSY | 77 | config TOUCHSCREEN_BITSY |
33 | tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" | 78 | tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" |
34 | depends on SA1100_BITSY | 79 | depends on SA1100_BITSY |
@@ -308,6 +353,19 @@ config TOUCHSCREEN_WM97XX_MAINSTONE | |||
308 | To compile this driver as a module, choose M here: the | 353 | To compile this driver as a module, choose M here: the |
309 | module will be called mainstone-wm97xx. | 354 | module will be called mainstone-wm97xx. |
310 | 355 | ||
356 | config TOUCHSCREEN_WM97XX_ZYLONITE | ||
357 | tristate "Zylonite accelerated touch" | ||
358 | depends on TOUCHSCREEN_WM97XX && MACH_ZYLONITE | ||
359 | select TOUCHSCREEN_WM9713 | ||
360 | help | ||
361 | Say Y here for support for streaming mode with the touchscreen | ||
362 | on Zylonite systems. | ||
363 | |||
364 | If unsure, say N. | ||
365 | |||
366 | To compile this driver as a module, choose M here: the | ||
367 | module will be called zylonite-wm97xx. | ||
368 | |||
311 | config TOUCHSCREEN_USB_COMPOSITE | 369 | config TOUCHSCREEN_USB_COMPOSITE |
312 | tristate "USB Touchscreen Driver" | 370 | tristate "USB Touchscreen Driver" |
313 | depends on USB_ARCH_HAS_HCD | 371 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index d3375aff46fe..6700f7b9d165 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -6,6 +6,8 @@ | |||
6 | 6 | ||
7 | wm97xx-ts-y := wm97xx-core.o | 7 | wm97xx-ts-y := wm97xx-core.o |
8 | 8 | ||
9 | obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o | ||
10 | obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o | ||
9 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | 11 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o |
10 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o | 12 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o |
11 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 13 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
@@ -34,3 +36,4 @@ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o | |||
34 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o | 36 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o |
35 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o | 37 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o |
36 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o | 38 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o |
39 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o | ||
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c new file mode 100644 index 000000000000..ecaeb7e8e75e --- /dev/null +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -0,0 +1,844 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-2008 Michael Hennerich, Analog Devices Inc. | ||
3 | * | ||
4 | * Description: AD7877 based touchscreen, sensor (ADCs), DAC and GPIO driver | ||
5 | * Based on: ads7846.c | ||
6 | * | ||
7 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, see the file COPYING, or write | ||
21 | * to the Free Software Foundation, Inc., | ||
22 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
23 | * | ||
24 | * History: | ||
25 | * Copyright (c) 2005 David Brownell | ||
26 | * Copyright (c) 2006 Nokia Corporation | ||
27 | * Various changes: Imre Deak <imre.deak@nokia.com> | ||
28 | * | ||
29 | * Using code from: | ||
30 | * - corgi_ts.c | ||
31 | * Copyright (C) 2004-2005 Richard Purdie | ||
32 | * - omap_ts.[hc], ads7846.h, ts_osk.c | ||
33 | * Copyright (C) 2002 MontaVista Software | ||
34 | * Copyright (C) 2004 Texas Instruments | ||
35 | * Copyright (C) 2005 Dirk Behme | ||
36 | */ | ||
37 | |||
38 | |||
39 | #include <linux/device.h> | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/delay.h> | ||
42 | #include <linux/input.h> | ||
43 | #include <linux/interrupt.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <linux/spi/spi.h> | ||
46 | #include <linux/spi/ad7877.h> | ||
47 | #include <asm/irq.h> | ||
48 | |||
49 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) | ||
50 | |||
51 | #define MAX_SPI_FREQ_HZ 20000000 | ||
52 | #define MAX_12BIT ((1<<12)-1) | ||
53 | |||
54 | #define AD7877_REG_ZEROS 0 | ||
55 | #define AD7877_REG_CTRL1 1 | ||
56 | #define AD7877_REG_CTRL2 2 | ||
57 | #define AD7877_REG_ALERT 3 | ||
58 | #define AD7877_REG_AUX1HIGH 4 | ||
59 | #define AD7877_REG_AUX1LOW 5 | ||
60 | #define AD7877_REG_BAT1HIGH 6 | ||
61 | #define AD7877_REG_BAT1LOW 7 | ||
62 | #define AD7877_REG_BAT2HIGH 8 | ||
63 | #define AD7877_REG_BAT2LOW 9 | ||
64 | #define AD7877_REG_TEMP1HIGH 10 | ||
65 | #define AD7877_REG_TEMP1LOW 11 | ||
66 | #define AD7877_REG_SEQ0 12 | ||
67 | #define AD7877_REG_SEQ1 13 | ||
68 | #define AD7877_REG_DAC 14 | ||
69 | #define AD7877_REG_NONE1 15 | ||
70 | #define AD7877_REG_EXTWRITE 15 | ||
71 | #define AD7877_REG_XPLUS 16 | ||
72 | #define AD7877_REG_YPLUS 17 | ||
73 | #define AD7877_REG_Z2 18 | ||
74 | #define AD7877_REG_aux1 19 | ||
75 | #define AD7877_REG_aux2 20 | ||
76 | #define AD7877_REG_aux3 21 | ||
77 | #define AD7877_REG_bat1 22 | ||
78 | #define AD7877_REG_bat2 23 | ||
79 | #define AD7877_REG_temp1 24 | ||
80 | #define AD7877_REG_temp2 25 | ||
81 | #define AD7877_REG_Z1 26 | ||
82 | #define AD7877_REG_GPIOCTRL1 27 | ||
83 | #define AD7877_REG_GPIOCTRL2 28 | ||
84 | #define AD7877_REG_GPIODATA 29 | ||
85 | #define AD7877_REG_NONE2 30 | ||
86 | #define AD7877_REG_NONE3 31 | ||
87 | |||
88 | #define AD7877_SEQ_YPLUS_BIT (1<<11) | ||
89 | #define AD7877_SEQ_XPLUS_BIT (1<<10) | ||
90 | #define AD7877_SEQ_Z2_BIT (1<<9) | ||
91 | #define AD7877_SEQ_AUX1_BIT (1<<8) | ||
92 | #define AD7877_SEQ_AUX2_BIT (1<<7) | ||
93 | #define AD7877_SEQ_AUX3_BIT (1<<6) | ||
94 | #define AD7877_SEQ_BAT1_BIT (1<<5) | ||
95 | #define AD7877_SEQ_BAT2_BIT (1<<4) | ||
96 | #define AD7877_SEQ_TEMP1_BIT (1<<3) | ||
97 | #define AD7877_SEQ_TEMP2_BIT (1<<2) | ||
98 | #define AD7877_SEQ_Z1_BIT (1<<1) | ||
99 | |||
100 | enum { | ||
101 | AD7877_SEQ_YPOS = 0, | ||
102 | AD7877_SEQ_XPOS = 1, | ||
103 | AD7877_SEQ_Z2 = 2, | ||
104 | AD7877_SEQ_AUX1 = 3, | ||
105 | AD7877_SEQ_AUX2 = 4, | ||
106 | AD7877_SEQ_AUX3 = 5, | ||
107 | AD7877_SEQ_BAT1 = 6, | ||
108 | AD7877_SEQ_BAT2 = 7, | ||
109 | AD7877_SEQ_TEMP1 = 8, | ||
110 | AD7877_SEQ_TEMP2 = 9, | ||
111 | AD7877_SEQ_Z1 = 10, | ||
112 | AD7877_NR_SENSE = 11, | ||
113 | }; | ||
114 | |||
115 | /* DAC Register Default RANGE 0 to Vcc, Volatge Mode, DAC On */ | ||
116 | #define AD7877_DAC_CONF 0x1 | ||
117 | |||
118 | /* If gpio3 is set AUX3/GPIO3 acts as GPIO Output */ | ||
119 | #define AD7877_EXTW_GPIO_3_CONF 0x1C4 | ||
120 | #define AD7877_EXTW_GPIO_DATA 0x200 | ||
121 | |||
122 | /* Control REG 2 */ | ||
123 | #define AD7877_TMR(x) ((x & 0x3) << 0) | ||
124 | #define AD7877_REF(x) ((x & 0x1) << 2) | ||
125 | #define AD7877_POL(x) ((x & 0x1) << 3) | ||
126 | #define AD7877_FCD(x) ((x & 0x3) << 4) | ||
127 | #define AD7877_PM(x) ((x & 0x3) << 6) | ||
128 | #define AD7877_ACQ(x) ((x & 0x3) << 8) | ||
129 | #define AD7877_AVG(x) ((x & 0x3) << 10) | ||
130 | |||
131 | /* Control REG 1 */ | ||
132 | #define AD7877_SER (1 << 11) /* non-differential */ | ||
133 | #define AD7877_DFR (0 << 11) /* differential */ | ||
134 | |||
135 | #define AD7877_MODE_NOC (0) /* Do not convert */ | ||
136 | #define AD7877_MODE_SCC (1) /* Single channel conversion */ | ||
137 | #define AD7877_MODE_SEQ0 (2) /* Sequence 0 in Slave Mode */ | ||
138 | #define AD7877_MODE_SEQ1 (3) /* Sequence 1 in Master Mode */ | ||
139 | |||
140 | #define AD7877_CHANADD(x) ((x&0xF)<<7) | ||
141 | #define AD7877_READADD(x) ((x)<<2) | ||
142 | #define AD7877_WRITEADD(x) ((x)<<12) | ||
143 | |||
144 | #define AD7877_READ_CHAN(x) (AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_SER | \ | ||
145 | AD7877_MODE_SCC | AD7877_CHANADD(AD7877_REG_ ## x) | \ | ||
146 | AD7877_READADD(AD7877_REG_ ## x)) | ||
147 | |||
148 | #define AD7877_MM_SEQUENCE (AD7877_SEQ_YPLUS_BIT | AD7877_SEQ_XPLUS_BIT | \ | ||
149 | AD7877_SEQ_Z2_BIT | AD7877_SEQ_Z1_BIT) | ||
150 | |||
151 | /* | ||
152 | * Non-touchscreen sensors only use single-ended conversions. | ||
153 | */ | ||
154 | |||
155 | struct ser_req { | ||
156 | u16 reset; | ||
157 | u16 ref_on; | ||
158 | u16 command; | ||
159 | u16 sample; | ||
160 | struct spi_message msg; | ||
161 | struct spi_transfer xfer[6]; | ||
162 | }; | ||
163 | |||
164 | struct ad7877 { | ||
165 | struct input_dev *input; | ||
166 | char phys[32]; | ||
167 | |||
168 | struct spi_device *spi; | ||
169 | u16 model; | ||
170 | u16 vref_delay_usecs; | ||
171 | u16 x_plate_ohms; | ||
172 | u16 pressure_max; | ||
173 | |||
174 | u16 cmd_crtl1; | ||
175 | u16 cmd_crtl2; | ||
176 | u16 cmd_dummy; | ||
177 | u16 dac; | ||
178 | |||
179 | u8 stopacq_polarity; | ||
180 | u8 first_conversion_delay; | ||
181 | u8 acquisition_time; | ||
182 | u8 averaging; | ||
183 | u8 pen_down_acc_interval; | ||
184 | |||
185 | u16 conversion_data[AD7877_NR_SENSE]; | ||
186 | |||
187 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; | ||
188 | struct spi_message msg; | ||
189 | |||
190 | struct mutex mutex; | ||
191 | unsigned disabled:1; /* P: mutex */ | ||
192 | unsigned gpio3:1; /* P: mutex */ | ||
193 | unsigned gpio4:1; /* P: mutex */ | ||
194 | |||
195 | spinlock_t lock; | ||
196 | struct timer_list timer; /* P: lock */ | ||
197 | unsigned pending:1; /* P: lock */ | ||
198 | }; | ||
199 | |||
200 | static int gpio3; | ||
201 | module_param(gpio3, int, 0); | ||
202 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); | ||
203 | |||
204 | /* | ||
205 | * ad7877_read/write are only used for initial setup and for sysfs controls. | ||
206 | * The main traffic is done using spi_async() in the interrupt handler. | ||
207 | */ | ||
208 | |||
209 | static int ad7877_read(struct spi_device *spi, u16 reg) | ||
210 | { | ||
211 | struct ser_req *req; | ||
212 | int status, ret; | ||
213 | |||
214 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
215 | if (!req) | ||
216 | return -ENOMEM; | ||
217 | |||
218 | spi_message_init(&req->msg); | ||
219 | |||
220 | req->command = (u16) (AD7877_WRITEADD(AD7877_REG_CTRL1) | | ||
221 | AD7877_READADD(reg)); | ||
222 | req->xfer[0].tx_buf = &req->command; | ||
223 | req->xfer[0].len = 2; | ||
224 | |||
225 | req->xfer[1].rx_buf = &req->sample; | ||
226 | req->xfer[1].len = 2; | ||
227 | |||
228 | spi_message_add_tail(&req->xfer[0], &req->msg); | ||
229 | spi_message_add_tail(&req->xfer[1], &req->msg); | ||
230 | |||
231 | status = spi_sync(spi, &req->msg); | ||
232 | ret = status ? : req->sample; | ||
233 | |||
234 | kfree(req); | ||
235 | |||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | static int ad7877_write(struct spi_device *spi, u16 reg, u16 val) | ||
240 | { | ||
241 | struct ser_req *req; | ||
242 | int status; | ||
243 | |||
244 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
245 | if (!req) | ||
246 | return -ENOMEM; | ||
247 | |||
248 | spi_message_init(&req->msg); | ||
249 | |||
250 | req->command = (u16) (AD7877_WRITEADD(reg) | (val & MAX_12BIT)); | ||
251 | req->xfer[0].tx_buf = &req->command; | ||
252 | req->xfer[0].len = 2; | ||
253 | |||
254 | spi_message_add_tail(&req->xfer[0], &req->msg); | ||
255 | |||
256 | status = spi_sync(spi, &req->msg); | ||
257 | |||
258 | kfree(req); | ||
259 | |||
260 | return status; | ||
261 | } | ||
262 | |||
263 | static int ad7877_read_adc(struct spi_device *spi, unsigned command) | ||
264 | { | ||
265 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | ||
266 | struct ser_req *req; | ||
267 | int status; | ||
268 | int sample; | ||
269 | int i; | ||
270 | |||
271 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
272 | if (!req) | ||
273 | return -ENOMEM; | ||
274 | |||
275 | spi_message_init(&req->msg); | ||
276 | |||
277 | /* activate reference, so it has time to settle; */ | ||
278 | req->ref_on = AD7877_WRITEADD(AD7877_REG_CTRL2) | | ||
279 | AD7877_POL(ts->stopacq_polarity) | | ||
280 | AD7877_AVG(0) | AD7877_PM(2) | AD7877_TMR(0) | | ||
281 | AD7877_ACQ(ts->acquisition_time) | AD7877_FCD(0); | ||
282 | |||
283 | req->reset = AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_MODE_NOC; | ||
284 | |||
285 | req->command = (u16) command; | ||
286 | |||
287 | req->xfer[0].tx_buf = &req->reset; | ||
288 | req->xfer[0].len = 2; | ||
289 | |||
290 | req->xfer[1].tx_buf = &req->ref_on; | ||
291 | req->xfer[1].len = 2; | ||
292 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | ||
293 | |||
294 | req->xfer[2].tx_buf = &req->command; | ||
295 | req->xfer[2].len = 2; | ||
296 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; | ||
297 | |||
298 | req->xfer[3].rx_buf = &req->sample; | ||
299 | req->xfer[3].len = 2; | ||
300 | |||
301 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ | ||
302 | req->xfer[4].len = 2; | ||
303 | |||
304 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ | ||
305 | req->xfer[5].len = 2; | ||
306 | |||
307 | /* group all the transfers together, so we can't interfere with | ||
308 | * reading touchscreen state; disable penirq while sampling | ||
309 | */ | ||
310 | for (i = 0; i < 6; i++) | ||
311 | spi_message_add_tail(&req->xfer[i], &req->msg); | ||
312 | |||
313 | status = spi_sync(spi, &req->msg); | ||
314 | sample = req->sample; | ||
315 | |||
316 | kfree(req); | ||
317 | |||
318 | return status ? : sample; | ||
319 | } | ||
320 | |||
321 | static void ad7877_rx(struct ad7877 *ts) | ||
322 | { | ||
323 | struct input_dev *input_dev = ts->input; | ||
324 | unsigned Rt; | ||
325 | u16 x, y, z1, z2; | ||
326 | |||
327 | x = ts->conversion_data[AD7877_SEQ_XPOS] & MAX_12BIT; | ||
328 | y = ts->conversion_data[AD7877_SEQ_YPOS] & MAX_12BIT; | ||
329 | z1 = ts->conversion_data[AD7877_SEQ_Z1] & MAX_12BIT; | ||
330 | z2 = ts->conversion_data[AD7877_SEQ_Z2] & MAX_12BIT; | ||
331 | |||
332 | /* | ||
333 | * The samples processed here are already preprocessed by the AD7877. | ||
334 | * The preprocessing function consists of an averaging filter. | ||
335 | * The combination of 'first conversion delay' and averaging provides a robust solution, | ||
336 | * discarding the spurious noise in the signal and keeping only the data of interest. | ||
337 | * The size of the averaging filter is programmable. (dev.platform_data, see linux/spi/ad7877.h) | ||
338 | * Other user-programmable conversion controls include variable acquisition time, | ||
339 | * and first conversion delay. Up to 16 averages can be taken per conversion. | ||
340 | */ | ||
341 | |||
342 | if (likely(x && z1)) { | ||
343 | /* compute touch pressure resistance using equation #1 */ | ||
344 | Rt = (z2 - z1) * x * ts->x_plate_ohms; | ||
345 | Rt /= z1; | ||
346 | Rt = (Rt + 2047) >> 12; | ||
347 | |||
348 | input_report_abs(input_dev, ABS_X, x); | ||
349 | input_report_abs(input_dev, ABS_Y, y); | ||
350 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | ||
351 | input_sync(input_dev); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | static inline void ad7877_ts_event_release(struct ad7877 *ts) | ||
356 | { | ||
357 | struct input_dev *input_dev = ts->input; | ||
358 | |||
359 | input_report_abs(input_dev, ABS_PRESSURE, 0); | ||
360 | input_sync(input_dev); | ||
361 | } | ||
362 | |||
363 | static void ad7877_timer(unsigned long handle) | ||
364 | { | ||
365 | struct ad7877 *ts = (void *)handle; | ||
366 | |||
367 | ad7877_ts_event_release(ts); | ||
368 | } | ||
369 | |||
370 | static irqreturn_t ad7877_irq(int irq, void *handle) | ||
371 | { | ||
372 | struct ad7877 *ts = handle; | ||
373 | unsigned long flags; | ||
374 | int status; | ||
375 | |||
376 | /* | ||
377 | * The repeated conversion sequencer controlled by TMR kicked off | ||
378 | * too fast. We ignore the last and process the sample sequence | ||
379 | * currently in the queue. It can't be older than 9.4ms, and we | ||
380 | * need to avoid that ts->msg doesn't get issued twice while in work. | ||
381 | */ | ||
382 | |||
383 | spin_lock_irqsave(&ts->lock, flags); | ||
384 | if (!ts->pending) { | ||
385 | ts->pending = 1; | ||
386 | |||
387 | status = spi_async(ts->spi, &ts->msg); | ||
388 | if (status) | ||
389 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", status); | ||
390 | } | ||
391 | spin_unlock_irqrestore(&ts->lock, flags); | ||
392 | |||
393 | return IRQ_HANDLED; | ||
394 | } | ||
395 | |||
396 | static void ad7877_callback(void *_ts) | ||
397 | { | ||
398 | struct ad7877 *ts = _ts; | ||
399 | |||
400 | spin_lock_irq(&ts->lock); | ||
401 | |||
402 | ad7877_rx(ts); | ||
403 | ts->pending = 0; | ||
404 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | ||
405 | |||
406 | spin_unlock_irq(&ts->lock); | ||
407 | } | ||
408 | |||
409 | static void ad7877_disable(struct ad7877 *ts) | ||
410 | { | ||
411 | mutex_lock(&ts->mutex); | ||
412 | |||
413 | if (!ts->disabled) { | ||
414 | ts->disabled = 1; | ||
415 | disable_irq(ts->spi->irq); | ||
416 | |||
417 | /* Wait for spi_async callback */ | ||
418 | while (ts->pending) | ||
419 | msleep(1); | ||
420 | |||
421 | if (del_timer_sync(&ts->timer)) | ||
422 | ad7877_ts_event_release(ts); | ||
423 | } | ||
424 | |||
425 | /* we know the chip's in lowpower mode since we always | ||
426 | * leave it that way after every request | ||
427 | */ | ||
428 | |||
429 | mutex_unlock(&ts->mutex); | ||
430 | } | ||
431 | |||
432 | static void ad7877_enable(struct ad7877 *ts) | ||
433 | { | ||
434 | mutex_lock(&ts->mutex); | ||
435 | |||
436 | if (ts->disabled) { | ||
437 | ts->disabled = 0; | ||
438 | enable_irq(ts->spi->irq); | ||
439 | } | ||
440 | |||
441 | mutex_unlock(&ts->mutex); | ||
442 | } | ||
443 | |||
444 | #define SHOW(name) static ssize_t \ | ||
445 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | ||
446 | { \ | ||
447 | struct ad7877 *ts = dev_get_drvdata(dev); \ | ||
448 | ssize_t v = ad7877_read_adc(ts->spi, \ | ||
449 | AD7877_READ_CHAN(name)); \ | ||
450 | if (v < 0) \ | ||
451 | return v; \ | ||
452 | return sprintf(buf, "%u\n", (unsigned) v); \ | ||
453 | } \ | ||
454 | static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); | ||
455 | |||
456 | SHOW(aux1) | ||
457 | SHOW(aux2) | ||
458 | SHOW(aux3) | ||
459 | SHOW(bat1) | ||
460 | SHOW(bat2) | ||
461 | SHOW(temp1) | ||
462 | SHOW(temp2) | ||
463 | |||
464 | static ssize_t ad7877_disable_show(struct device *dev, | ||
465 | struct device_attribute *attr, char *buf) | ||
466 | { | ||
467 | struct ad7877 *ts = dev_get_drvdata(dev); | ||
468 | |||
469 | return sprintf(buf, "%u\n", ts->disabled); | ||
470 | } | ||
471 | |||
472 | static ssize_t ad7877_disable_store(struct device *dev, | ||
473 | struct device_attribute *attr, | ||
474 | const char *buf, size_t count) | ||
475 | { | ||
476 | struct ad7877 *ts = dev_get_drvdata(dev); | ||
477 | unsigned long val; | ||
478 | int error; | ||
479 | |||
480 | error = strict_strtoul(buf, 10, &val); | ||
481 | if (error) | ||
482 | return error; | ||
483 | |||
484 | if (val) | ||
485 | ad7877_disable(ts); | ||
486 | else | ||
487 | ad7877_enable(ts); | ||
488 | |||
489 | return count; | ||
490 | } | ||
491 | |||
492 | static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store); | ||
493 | |||
494 | static ssize_t ad7877_dac_show(struct device *dev, | ||
495 | struct device_attribute *attr, char *buf) | ||
496 | { | ||
497 | struct ad7877 *ts = dev_get_drvdata(dev); | ||
498 | |||
499 | return sprintf(buf, "%u\n", ts->dac); | ||
500 | } | ||
501 | |||
502 | static ssize_t ad7877_dac_store(struct device *dev, | ||
503 | struct device_attribute *attr, | ||
504 | const char *buf, size_t count) | ||
505 | { | ||
506 | struct ad7877 *ts = dev_get_drvdata(dev); | ||
507 | unsigned long val; | ||
508 | int error; | ||
509 | |||
510 | error = strict_strtoul(buf, 10, &val); | ||
511 | if (error) | ||
512 | return error; | ||
513 | |||
514 | mutex_lock(&ts->mutex); | ||
515 | ts->dac = val & 0xFF; | ||
516 | ad7877_write(ts->spi, AD7877_REG_DAC, (ts->dac << 4) | AD7877_DAC_CONF); | ||
517 | mutex_unlock(&ts->mutex); | ||
518 | |||
519 | return count; | ||
520 | } | ||
521 | |||
522 | static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store); | ||
523 | |||
524 | static ssize_t ad7877_gpio3_show(struct device *dev, | ||
525 | struct device_attribute *attr, char *buf) | ||
526 | { | ||
527 | struct ad7877 *ts = dev_get_drvdata(dev); | ||
528 | |||
529 | return sprintf(buf, "%u\n", ts->gpio3); | ||
530 | } | ||
531 | |||
532 | static ssize_t ad7877_gpio3_store(struct device *dev, | ||
533 | struct device_attribute *attr, | ||
534 | const char *buf, size_t count) | ||
535 | { | ||
536 | struct ad7877 *ts = dev_get_drvdata(dev); | ||
537 | unsigned long val; | ||
538 | int error; | ||
539 | |||
540 | error = strict_strtoul(buf, 10, &val); | ||
541 | if (error) | ||
542 | return error; | ||
543 | |||
544 | mutex_lock(&ts->mutex); | ||
545 | ts->gpio3 = !!val; | ||
546 | ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA | | ||
547 | (ts->gpio4 << 4) | (ts->gpio3 << 5)); | ||
548 | mutex_unlock(&ts->mutex); | ||
549 | |||
550 | return count; | ||
551 | } | ||
552 | |||
553 | static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store); | ||
554 | |||
555 | static ssize_t ad7877_gpio4_show(struct device *dev, | ||
556 | struct device_attribute *attr, char *buf) | ||
557 | { | ||
558 | struct ad7877 *ts = dev_get_drvdata(dev); | ||
559 | |||
560 | return sprintf(buf, "%u\n", ts->gpio4); | ||
561 | } | ||
562 | |||
563 | static ssize_t ad7877_gpio4_store(struct device *dev, | ||
564 | struct device_attribute *attr, | ||
565 | const char *buf, size_t count) | ||
566 | { | ||
567 | struct ad7877 *ts = dev_get_drvdata(dev); | ||
568 | unsigned long val; | ||
569 | int error; | ||
570 | |||
571 | error = strict_strtoul(buf, 10, &val); | ||
572 | if (error) | ||
573 | return error; | ||
574 | |||
575 | mutex_lock(&ts->mutex); | ||
576 | ts->gpio4 = !!val; | ||
577 | ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA | | ||
578 | (ts->gpio4 << 4) | (ts->gpio3 << 5)); | ||
579 | mutex_unlock(&ts->mutex); | ||
580 | |||
581 | return count; | ||
582 | } | ||
583 | |||
584 | static DEVICE_ATTR(gpio4, 0664, ad7877_gpio4_show, ad7877_gpio4_store); | ||
585 | |||
586 | static struct attribute *ad7877_attributes[] = { | ||
587 | &dev_attr_temp1.attr, | ||
588 | &dev_attr_temp2.attr, | ||
589 | &dev_attr_aux1.attr, | ||
590 | &dev_attr_aux2.attr, | ||
591 | &dev_attr_bat1.attr, | ||
592 | &dev_attr_bat2.attr, | ||
593 | &dev_attr_disable.attr, | ||
594 | &dev_attr_dac.attr, | ||
595 | &dev_attr_gpio4.attr, | ||
596 | NULL | ||
597 | }; | ||
598 | |||
599 | static const struct attribute_group ad7877_attr_group = { | ||
600 | .attrs = ad7877_attributes, | ||
601 | }; | ||
602 | |||
603 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | ||
604 | { | ||
605 | struct spi_message *m; | ||
606 | int i; | ||
607 | |||
608 | ts->cmd_crtl2 = AD7877_WRITEADD(AD7877_REG_CTRL2) | | ||
609 | AD7877_POL(ts->stopacq_polarity) | | ||
610 | AD7877_AVG(ts->averaging) | AD7877_PM(1) | | ||
611 | AD7877_TMR(ts->pen_down_acc_interval) | | ||
612 | AD7877_ACQ(ts->acquisition_time) | | ||
613 | AD7877_FCD(ts->first_conversion_delay); | ||
614 | |||
615 | ad7877_write(spi, AD7877_REG_CTRL2, ts->cmd_crtl2); | ||
616 | |||
617 | ts->cmd_crtl1 = AD7877_WRITEADD(AD7877_REG_CTRL1) | | ||
618 | AD7877_READADD(AD7877_REG_XPLUS-1) | | ||
619 | AD7877_MODE_SEQ1 | AD7877_DFR; | ||
620 | |||
621 | ad7877_write(spi, AD7877_REG_CTRL1, ts->cmd_crtl1); | ||
622 | |||
623 | ts->cmd_dummy = 0; | ||
624 | |||
625 | m = &ts->msg; | ||
626 | |||
627 | spi_message_init(m); | ||
628 | |||
629 | m->complete = ad7877_callback; | ||
630 | m->context = ts; | ||
631 | |||
632 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; | ||
633 | ts->xfer[0].len = 2; | ||
634 | |||
635 | spi_message_add_tail(&ts->xfer[0], m); | ||
636 | |||
637 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ | ||
638 | ts->xfer[1].len = 2; | ||
639 | |||
640 | spi_message_add_tail(&ts->xfer[1], m); | ||
641 | |||
642 | for (i = 0; i < 11; i++) { | ||
643 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; | ||
644 | ts->xfer[i + 2].len = 2; | ||
645 | spi_message_add_tail(&ts->xfer[i + 2], m); | ||
646 | } | ||
647 | } | ||
648 | |||
649 | static int __devinit ad7877_probe(struct spi_device *spi) | ||
650 | { | ||
651 | struct ad7877 *ts; | ||
652 | struct input_dev *input_dev; | ||
653 | struct ad7877_platform_data *pdata = spi->dev.platform_data; | ||
654 | int err; | ||
655 | u16 verify; | ||
656 | |||
657 | if (!spi->irq) { | ||
658 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
659 | return -ENODEV; | ||
660 | } | ||
661 | |||
662 | if (!pdata) { | ||
663 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
664 | return -ENODEV; | ||
665 | } | ||
666 | |||
667 | /* don't exceed max specified SPI CLK frequency */ | ||
668 | if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) { | ||
669 | dev_dbg(&spi->dev, "SPI CLK %d Hz?\n",spi->max_speed_hz); | ||
670 | return -EINVAL; | ||
671 | } | ||
672 | |||
673 | ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL); | ||
674 | input_dev = input_allocate_device(); | ||
675 | if (!ts || !input_dev) { | ||
676 | err = -ENOMEM; | ||
677 | goto err_free_mem; | ||
678 | } | ||
679 | |||
680 | dev_set_drvdata(&spi->dev, ts); | ||
681 | ts->spi = spi; | ||
682 | ts->input = input_dev; | ||
683 | |||
684 | setup_timer(&ts->timer, ad7877_timer, (unsigned long) ts); | ||
685 | mutex_init(&ts->mutex); | ||
686 | spin_lock_init(&ts->lock); | ||
687 | |||
688 | ts->model = pdata->model ? : 7877; | ||
689 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
690 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
691 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
692 | |||
693 | ts->stopacq_polarity = pdata->stopacq_polarity; | ||
694 | ts->first_conversion_delay = pdata->first_conversion_delay; | ||
695 | ts->acquisition_time = pdata->acquisition_time; | ||
696 | ts->averaging = pdata->averaging; | ||
697 | ts->pen_down_acc_interval = pdata->pen_down_acc_interval; | ||
698 | |||
699 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
700 | |||
701 | input_dev->name = "AD7877 Touchscreen"; | ||
702 | input_dev->phys = ts->phys; | ||
703 | input_dev->dev.parent = &spi->dev; | ||
704 | |||
705 | __set_bit(EV_ABS, input_dev->evbit); | ||
706 | __set_bit(ABS_X, input_dev->absbit); | ||
707 | __set_bit(ABS_Y, input_dev->absbit); | ||
708 | __set_bit(ABS_PRESSURE, input_dev->absbit); | ||
709 | |||
710 | input_set_abs_params(input_dev, ABS_X, | ||
711 | pdata->x_min ? : 0, | ||
712 | pdata->x_max ? : MAX_12BIT, | ||
713 | 0, 0); | ||
714 | input_set_abs_params(input_dev, ABS_Y, | ||
715 | pdata->y_min ? : 0, | ||
716 | pdata->y_max ? : MAX_12BIT, | ||
717 | 0, 0); | ||
718 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
719 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
720 | |||
721 | ad7877_write(spi, AD7877_REG_SEQ1, AD7877_MM_SEQUENCE); | ||
722 | |||
723 | verify = ad7877_read(spi, AD7877_REG_SEQ1); | ||
724 | |||
725 | if (verify != AD7877_MM_SEQUENCE){ | ||
726 | dev_err(&spi->dev, "%s: Failed to probe %s\n", | ||
727 | dev_name(&spi->dev), input_dev->name); | ||
728 | err = -ENODEV; | ||
729 | goto err_free_mem; | ||
730 | } | ||
731 | |||
732 | if (gpio3) | ||
733 | ad7877_write(spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_3_CONF); | ||
734 | |||
735 | ad7877_setup_ts_def_msg(spi, ts); | ||
736 | |||
737 | /* Request AD7877 /DAV GPIO interrupt */ | ||
738 | |||
739 | err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING, | ||
740 | spi->dev.driver->name, ts); | ||
741 | if (err) { | ||
742 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | ||
743 | goto err_free_mem; | ||
744 | } | ||
745 | |||
746 | err = sysfs_create_group(&spi->dev.kobj, &ad7877_attr_group); | ||
747 | if (err) | ||
748 | goto err_free_irq; | ||
749 | |||
750 | err = device_create_file(&spi->dev, | ||
751 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
752 | if (err) | ||
753 | goto err_remove_attr_group; | ||
754 | |||
755 | err = input_register_device(input_dev); | ||
756 | if (err) | ||
757 | goto err_remove_attr; | ||
758 | |||
759 | return 0; | ||
760 | |||
761 | err_remove_attr: | ||
762 | device_remove_file(&spi->dev, | ||
763 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
764 | err_remove_attr_group: | ||
765 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | ||
766 | err_free_irq: | ||
767 | free_irq(spi->irq, ts); | ||
768 | err_free_mem: | ||
769 | input_free_device(input_dev); | ||
770 | kfree(ts); | ||
771 | dev_set_drvdata(&spi->dev, NULL); | ||
772 | return err; | ||
773 | } | ||
774 | |||
775 | static int __devexit ad7877_remove(struct spi_device *spi) | ||
776 | { | ||
777 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | ||
778 | |||
779 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | ||
780 | device_remove_file(&spi->dev, | ||
781 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
782 | |||
783 | ad7877_disable(ts); | ||
784 | free_irq(ts->spi->irq, ts); | ||
785 | |||
786 | input_unregister_device(ts->input); | ||
787 | kfree(ts); | ||
788 | |||
789 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | ||
790 | dev_set_drvdata(&spi->dev, NULL); | ||
791 | |||
792 | return 0; | ||
793 | } | ||
794 | |||
795 | #ifdef CONFIG_PM | ||
796 | static int ad7877_suspend(struct spi_device *spi, pm_message_t message) | ||
797 | { | ||
798 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | ||
799 | |||
800 | ad7877_disable(ts); | ||
801 | |||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | static int ad7877_resume(struct spi_device *spi) | ||
806 | { | ||
807 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | ||
808 | |||
809 | ad7877_enable(ts); | ||
810 | |||
811 | return 0; | ||
812 | } | ||
813 | #else | ||
814 | #define ad7877_suspend NULL | ||
815 | #define ad7877_resume NULL | ||
816 | #endif | ||
817 | |||
818 | static struct spi_driver ad7877_driver = { | ||
819 | .driver = { | ||
820 | .name = "ad7877", | ||
821 | .bus = &spi_bus_type, | ||
822 | .owner = THIS_MODULE, | ||
823 | }, | ||
824 | .probe = ad7877_probe, | ||
825 | .remove = __devexit_p(ad7877_remove), | ||
826 | .suspend = ad7877_suspend, | ||
827 | .resume = ad7877_resume, | ||
828 | }; | ||
829 | |||
830 | static int __init ad7877_init(void) | ||
831 | { | ||
832 | return spi_register_driver(&ad7877_driver); | ||
833 | } | ||
834 | module_init(ad7877_init); | ||
835 | |||
836 | static void __exit ad7877_exit(void) | ||
837 | { | ||
838 | spi_unregister_driver(&ad7877_driver); | ||
839 | } | ||
840 | module_exit(ad7877_exit); | ||
841 | |||
842 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
843 | MODULE_DESCRIPTION("AD7877 touchscreen Driver"); | ||
844 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c new file mode 100644 index 000000000000..5d8a70398807 --- /dev/null +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -0,0 +1,781 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michael Hennerich, Analog Devices Inc. | ||
3 | * | ||
4 | * Description: AD7879 based touchscreen, and GPIO driver (I2C/SPI Interface) | ||
5 | * | ||
6 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, see the file COPYING, or write | ||
20 | * to the Free Software Foundation, Inc., | ||
21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | * | ||
23 | * History: | ||
24 | * Copyright (c) 2005 David Brownell | ||
25 | * Copyright (c) 2006 Nokia Corporation | ||
26 | * Various changes: Imre Deak <imre.deak@nokia.com> | ||
27 | * | ||
28 | * Using code from: | ||
29 | * - corgi_ts.c | ||
30 | * Copyright (C) 2004-2005 Richard Purdie | ||
31 | * - omap_ts.[hc], ads7846.h, ts_osk.c | ||
32 | * Copyright (C) 2002 MontaVista Software | ||
33 | * Copyright (C) 2004 Texas Instruments | ||
34 | * Copyright (C) 2005 Dirk Behme | ||
35 | * - ad7877.c | ||
36 | * Copyright (C) 2006-2008 Analog Devices Inc. | ||
37 | */ | ||
38 | |||
39 | #include <linux/device.h> | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/delay.h> | ||
42 | #include <linux/input.h> | ||
43 | #include <linux/interrupt.h> | ||
44 | #include <linux/irq.h> | ||
45 | #include <linux/slab.h> | ||
46 | #include <linux/workqueue.h> | ||
47 | #include <linux/spi/spi.h> | ||
48 | #include <linux/i2c.h> | ||
49 | |||
50 | #include <linux/spi/ad7879.h> | ||
51 | |||
52 | #define AD7879_REG_ZEROS 0 | ||
53 | #define AD7879_REG_CTRL1 1 | ||
54 | #define AD7879_REG_CTRL2 2 | ||
55 | #define AD7879_REG_CTRL3 3 | ||
56 | #define AD7879_REG_AUX1HIGH 4 | ||
57 | #define AD7879_REG_AUX1LOW 5 | ||
58 | #define AD7879_REG_TEMP1HIGH 6 | ||
59 | #define AD7879_REG_TEMP1LOW 7 | ||
60 | #define AD7879_REG_XPLUS 8 | ||
61 | #define AD7879_REG_YPLUS 9 | ||
62 | #define AD7879_REG_Z1 10 | ||
63 | #define AD7879_REG_Z2 11 | ||
64 | #define AD7879_REG_AUXVBAT 12 | ||
65 | #define AD7879_REG_TEMP 13 | ||
66 | #define AD7879_REG_REVID 14 | ||
67 | |||
68 | /* Control REG 1 */ | ||
69 | #define AD7879_TMR(x) ((x & 0xFF) << 0) | ||
70 | #define AD7879_ACQ(x) ((x & 0x3) << 8) | ||
71 | #define AD7879_MODE_NOC (0 << 10) /* Do not convert */ | ||
72 | #define AD7879_MODE_SCC (1 << 10) /* Single channel conversion */ | ||
73 | #define AD7879_MODE_SEQ0 (2 << 10) /* Sequence 0 in Slave Mode */ | ||
74 | #define AD7879_MODE_SEQ1 (3 << 10) /* Sequence 1 in Master Mode */ | ||
75 | #define AD7879_MODE_INT (1 << 15) /* PENIRQ disabled INT enabled */ | ||
76 | |||
77 | /* Control REG 2 */ | ||
78 | #define AD7879_FCD(x) ((x & 0x3) << 0) | ||
79 | #define AD7879_RESET (1 << 4) | ||
80 | #define AD7879_MFS(x) ((x & 0x3) << 5) | ||
81 | #define AD7879_AVG(x) ((x & 0x3) << 7) | ||
82 | #define AD7879_SER (1 << 9) /* non-differential */ | ||
83 | #define AD7879_DFR (0 << 9) /* differential */ | ||
84 | #define AD7879_GPIOPOL (1 << 10) | ||
85 | #define AD7879_GPIODIR (1 << 11) | ||
86 | #define AD7879_GPIO_DATA (1 << 12) | ||
87 | #define AD7879_GPIO_EN (1 << 13) | ||
88 | #define AD7879_PM(x) ((x & 0x3) << 14) | ||
89 | #define AD7879_PM_SHUTDOWN (0) | ||
90 | #define AD7879_PM_DYN (1) | ||
91 | #define AD7879_PM_FULLON (2) | ||
92 | |||
93 | /* Control REG 3 */ | ||
94 | #define AD7879_TEMPMASK_BIT (1<<15) | ||
95 | #define AD7879_AUXVBATMASK_BIT (1<<14) | ||
96 | #define AD7879_INTMODE_BIT (1<<13) | ||
97 | #define AD7879_GPIOALERTMASK_BIT (1<<12) | ||
98 | #define AD7879_AUXLOW_BIT (1<<11) | ||
99 | #define AD7879_AUXHIGH_BIT (1<<10) | ||
100 | #define AD7879_TEMPLOW_BIT (1<<9) | ||
101 | #define AD7879_TEMPHIGH_BIT (1<<8) | ||
102 | #define AD7879_YPLUS_BIT (1<<7) | ||
103 | #define AD7879_XPLUS_BIT (1<<6) | ||
104 | #define AD7879_Z1_BIT (1<<5) | ||
105 | #define AD7879_Z2_BIT (1<<4) | ||
106 | #define AD7879_AUX_BIT (1<<3) | ||
107 | #define AD7879_VBAT_BIT (1<<2) | ||
108 | #define AD7879_TEMP_BIT (1<<1) | ||
109 | |||
110 | enum { | ||
111 | AD7879_SEQ_XPOS = 0, | ||
112 | AD7879_SEQ_YPOS = 1, | ||
113 | AD7879_SEQ_Z1 = 2, | ||
114 | AD7879_SEQ_Z2 = 3, | ||
115 | AD7879_NR_SENSE = 4, | ||
116 | }; | ||
117 | |||
118 | #define MAX_12BIT ((1<<12)-1) | ||
119 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) | ||
120 | |||
121 | #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) | ||
122 | #define AD7879_DEVID 0x7A | ||
123 | typedef struct spi_device bus_device; | ||
124 | #elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE) | ||
125 | #define AD7879_DEVID 0x79 | ||
126 | typedef struct i2c_client bus_device; | ||
127 | #endif | ||
128 | |||
129 | struct ad7879 { | ||
130 | bus_device *bus; | ||
131 | struct input_dev *input; | ||
132 | struct work_struct work; | ||
133 | struct timer_list timer; | ||
134 | |||
135 | struct mutex mutex; | ||
136 | unsigned disabled:1; /* P: mutex */ | ||
137 | |||
138 | #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) | ||
139 | struct spi_message msg; | ||
140 | struct spi_transfer xfer[AD7879_NR_SENSE + 1]; | ||
141 | u16 cmd; | ||
142 | #endif | ||
143 | u16 conversion_data[AD7879_NR_SENSE]; | ||
144 | char phys[32]; | ||
145 | u8 first_conversion_delay; | ||
146 | u8 acquisition_time; | ||
147 | u8 averaging; | ||
148 | u8 pen_down_acc_interval; | ||
149 | u8 median; | ||
150 | u16 x_plate_ohms; | ||
151 | u16 pressure_max; | ||
152 | u16 gpio_init; | ||
153 | u16 cmd_crtl1; | ||
154 | u16 cmd_crtl2; | ||
155 | u16 cmd_crtl3; | ||
156 | unsigned gpio:1; | ||
157 | }; | ||
158 | |||
159 | static int ad7879_read(bus_device *, u8); | ||
160 | static int ad7879_write(bus_device *, u8, u16); | ||
161 | static void ad7879_collect(struct ad7879 *); | ||
162 | |||
163 | static void ad7879_report(struct ad7879 *ts) | ||
164 | { | ||
165 | struct input_dev *input_dev = ts->input; | ||
166 | unsigned Rt; | ||
167 | u16 x, y, z1, z2; | ||
168 | |||
169 | x = ts->conversion_data[AD7879_SEQ_XPOS] & MAX_12BIT; | ||
170 | y = ts->conversion_data[AD7879_SEQ_YPOS] & MAX_12BIT; | ||
171 | z1 = ts->conversion_data[AD7879_SEQ_Z1] & MAX_12BIT; | ||
172 | z2 = ts->conversion_data[AD7879_SEQ_Z2] & MAX_12BIT; | ||
173 | |||
174 | /* | ||
175 | * The samples processed here are already preprocessed by the AD7879. | ||
176 | * The preprocessing function consists of a median and an averaging filter. | ||
177 | * The combination of these two techniques provides a robust solution, | ||
178 | * discarding the spurious noise in the signal and keeping only the data of interest. | ||
179 | * The size of both filters is programmable. (dev.platform_data, see linux/spi/ad7879.h) | ||
180 | * Other user-programmable conversion controls include variable acquisition time, | ||
181 | * and first conversion delay. Up to 16 averages can be taken per conversion. | ||
182 | */ | ||
183 | |||
184 | if (likely(x && z1)) { | ||
185 | /* compute touch pressure resistance using equation #1 */ | ||
186 | Rt = (z2 - z1) * x * ts->x_plate_ohms; | ||
187 | Rt /= z1; | ||
188 | Rt = (Rt + 2047) >> 12; | ||
189 | |||
190 | input_report_abs(input_dev, ABS_X, x); | ||
191 | input_report_abs(input_dev, ABS_Y, y); | ||
192 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | ||
193 | input_sync(input_dev); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | static void ad7879_work(struct work_struct *work) | ||
198 | { | ||
199 | struct ad7879 *ts = container_of(work, struct ad7879, work); | ||
200 | |||
201 | /* use keventd context to read the result registers */ | ||
202 | ad7879_collect(ts); | ||
203 | ad7879_report(ts); | ||
204 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | ||
205 | } | ||
206 | |||
207 | static void ad7879_ts_event_release(struct ad7879 *ts) | ||
208 | { | ||
209 | struct input_dev *input_dev = ts->input; | ||
210 | |||
211 | input_report_abs(input_dev, ABS_PRESSURE, 0); | ||
212 | input_sync(input_dev); | ||
213 | } | ||
214 | |||
215 | static void ad7879_timer(unsigned long handle) | ||
216 | { | ||
217 | struct ad7879 *ts = (void *)handle; | ||
218 | |||
219 | ad7879_ts_event_release(ts); | ||
220 | } | ||
221 | |||
222 | static irqreturn_t ad7879_irq(int irq, void *handle) | ||
223 | { | ||
224 | struct ad7879 *ts = handle; | ||
225 | |||
226 | /* The repeated conversion sequencer controlled by TMR kicked off too fast. | ||
227 | * We ignore the last and process the sample sequence currently in the queue. | ||
228 | * It can't be older than 9.4ms | ||
229 | */ | ||
230 | |||
231 | if (!work_pending(&ts->work)) | ||
232 | schedule_work(&ts->work); | ||
233 | |||
234 | return IRQ_HANDLED; | ||
235 | } | ||
236 | |||
237 | static void ad7879_setup(struct ad7879 *ts) | ||
238 | { | ||
239 | ts->cmd_crtl3 = AD7879_YPLUS_BIT | | ||
240 | AD7879_XPLUS_BIT | | ||
241 | AD7879_Z2_BIT | | ||
242 | AD7879_Z1_BIT | | ||
243 | AD7879_TEMPMASK_BIT | | ||
244 | AD7879_AUXVBATMASK_BIT | | ||
245 | AD7879_GPIOALERTMASK_BIT; | ||
246 | |||
247 | ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR | | ||
248 | AD7879_AVG(ts->averaging) | | ||
249 | AD7879_MFS(ts->median) | | ||
250 | AD7879_FCD(ts->first_conversion_delay) | | ||
251 | ts->gpio_init; | ||
252 | |||
253 | ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 | | ||
254 | AD7879_ACQ(ts->acquisition_time) | | ||
255 | AD7879_TMR(ts->pen_down_acc_interval); | ||
256 | |||
257 | ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); | ||
258 | ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3); | ||
259 | ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1); | ||
260 | } | ||
261 | |||
262 | static void ad7879_disable(struct ad7879 *ts) | ||
263 | { | ||
264 | mutex_lock(&ts->mutex); | ||
265 | |||
266 | if (!ts->disabled) { | ||
267 | |||
268 | ts->disabled = 1; | ||
269 | disable_irq(ts->bus->irq); | ||
270 | |||
271 | cancel_work_sync(&ts->work); | ||
272 | |||
273 | if (del_timer_sync(&ts->timer)) | ||
274 | ad7879_ts_event_release(ts); | ||
275 | |||
276 | ad7879_write(ts->bus, AD7879_REG_CTRL2, | ||
277 | AD7879_PM(AD7879_PM_SHUTDOWN)); | ||
278 | } | ||
279 | |||
280 | mutex_unlock(&ts->mutex); | ||
281 | } | ||
282 | |||
283 | static void ad7879_enable(struct ad7879 *ts) | ||
284 | { | ||
285 | mutex_lock(&ts->mutex); | ||
286 | |||
287 | if (ts->disabled) { | ||
288 | ad7879_setup(ts); | ||
289 | ts->disabled = 0; | ||
290 | enable_irq(ts->bus->irq); | ||
291 | } | ||
292 | |||
293 | mutex_unlock(&ts->mutex); | ||
294 | } | ||
295 | |||
296 | static ssize_t ad7879_disable_show(struct device *dev, | ||
297 | struct device_attribute *attr, char *buf) | ||
298 | { | ||
299 | struct ad7879 *ts = dev_get_drvdata(dev); | ||
300 | |||
301 | return sprintf(buf, "%u\n", ts->disabled); | ||
302 | } | ||
303 | |||
304 | static ssize_t ad7879_disable_store(struct device *dev, | ||
305 | struct device_attribute *attr, | ||
306 | const char *buf, size_t count) | ||
307 | { | ||
308 | struct ad7879 *ts = dev_get_drvdata(dev); | ||
309 | unsigned long val; | ||
310 | int error; | ||
311 | |||
312 | error = strict_strtoul(buf, 10, &val); | ||
313 | if (error) | ||
314 | return error; | ||
315 | |||
316 | if (val) | ||
317 | ad7879_disable(ts); | ||
318 | else | ||
319 | ad7879_enable(ts); | ||
320 | |||
321 | return count; | ||
322 | } | ||
323 | |||
324 | static DEVICE_ATTR(disable, 0664, ad7879_disable_show, ad7879_disable_store); | ||
325 | |||
326 | static ssize_t ad7879_gpio_show(struct device *dev, | ||
327 | struct device_attribute *attr, char *buf) | ||
328 | { | ||
329 | struct ad7879 *ts = dev_get_drvdata(dev); | ||
330 | |||
331 | return sprintf(buf, "%u\n", ts->gpio); | ||
332 | } | ||
333 | |||
334 | static ssize_t ad7879_gpio_store(struct device *dev, | ||
335 | struct device_attribute *attr, | ||
336 | const char *buf, size_t count) | ||
337 | { | ||
338 | struct ad7879 *ts = dev_get_drvdata(dev); | ||
339 | unsigned long val; | ||
340 | int error; | ||
341 | |||
342 | error = strict_strtoul(buf, 10, &val); | ||
343 | if (error) | ||
344 | return error; | ||
345 | |||
346 | mutex_lock(&ts->mutex); | ||
347 | ts->gpio = !!val; | ||
348 | error = ad7879_write(ts->bus, AD7879_REG_CTRL2, | ||
349 | ts->gpio ? | ||
350 | ts->cmd_crtl2 & ~AD7879_GPIO_DATA : | ||
351 | ts->cmd_crtl2 | AD7879_GPIO_DATA); | ||
352 | mutex_unlock(&ts->mutex); | ||
353 | |||
354 | return error ? : count; | ||
355 | } | ||
356 | |||
357 | static DEVICE_ATTR(gpio, 0664, ad7879_gpio_show, ad7879_gpio_store); | ||
358 | |||
359 | static struct attribute *ad7879_attributes[] = { | ||
360 | &dev_attr_disable.attr, | ||
361 | &dev_attr_gpio.attr, | ||
362 | NULL | ||
363 | }; | ||
364 | |||
365 | static const struct attribute_group ad7879_attr_group = { | ||
366 | .attrs = ad7879_attributes, | ||
367 | }; | ||
368 | |||
369 | static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | ||
370 | { | ||
371 | struct input_dev *input_dev; | ||
372 | struct ad7879_platform_data *pdata = bus->dev.platform_data; | ||
373 | int err; | ||
374 | u16 revid; | ||
375 | |||
376 | if (!bus->irq) { | ||
377 | dev_err(&bus->dev, "no IRQ?\n"); | ||
378 | return -ENODEV; | ||
379 | } | ||
380 | |||
381 | if (!pdata) { | ||
382 | dev_err(&bus->dev, "no platform data?\n"); | ||
383 | return -ENODEV; | ||
384 | } | ||
385 | |||
386 | input_dev = input_allocate_device(); | ||
387 | if (!input_dev) | ||
388 | return -ENOMEM; | ||
389 | |||
390 | ts->input = input_dev; | ||
391 | |||
392 | setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts); | ||
393 | INIT_WORK(&ts->work, ad7879_work); | ||
394 | mutex_init(&ts->mutex); | ||
395 | |||
396 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
397 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
398 | |||
399 | ts->first_conversion_delay = pdata->first_conversion_delay; | ||
400 | ts->acquisition_time = pdata->acquisition_time; | ||
401 | ts->averaging = pdata->averaging; | ||
402 | ts->pen_down_acc_interval = pdata->pen_down_acc_interval; | ||
403 | ts->median = pdata->median; | ||
404 | |||
405 | if (pdata->gpio_output) | ||
406 | ts->gpio_init = AD7879_GPIO_EN | | ||
407 | (pdata->gpio_default ? 0 : AD7879_GPIO_DATA); | ||
408 | else | ||
409 | ts->gpio_init = AD7879_GPIO_EN | AD7879_GPIODIR; | ||
410 | |||
411 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev)); | ||
412 | |||
413 | input_dev->name = "AD7879 Touchscreen"; | ||
414 | input_dev->phys = ts->phys; | ||
415 | input_dev->dev.parent = &bus->dev; | ||
416 | |||
417 | __set_bit(EV_ABS, input_dev->evbit); | ||
418 | __set_bit(ABS_X, input_dev->absbit); | ||
419 | __set_bit(ABS_Y, input_dev->absbit); | ||
420 | __set_bit(ABS_PRESSURE, input_dev->absbit); | ||
421 | |||
422 | input_set_abs_params(input_dev, ABS_X, | ||
423 | pdata->x_min ? : 0, | ||
424 | pdata->x_max ? : MAX_12BIT, | ||
425 | 0, 0); | ||
426 | input_set_abs_params(input_dev, ABS_Y, | ||
427 | pdata->y_min ? : 0, | ||
428 | pdata->y_max ? : MAX_12BIT, | ||
429 | 0, 0); | ||
430 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
431 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
432 | |||
433 | err = ad7879_write(bus, AD7879_REG_CTRL2, AD7879_RESET); | ||
434 | |||
435 | if (err < 0) { | ||
436 | dev_err(&bus->dev, "Failed to write %s\n", input_dev->name); | ||
437 | goto err_free_mem; | ||
438 | } | ||
439 | |||
440 | revid = ad7879_read(bus, AD7879_REG_REVID); | ||
441 | |||
442 | if ((revid & 0xFF) != AD7879_DEVID) { | ||
443 | dev_err(&bus->dev, "Failed to probe %s\n", input_dev->name); | ||
444 | err = -ENODEV; | ||
445 | goto err_free_mem; | ||
446 | } | ||
447 | |||
448 | ad7879_setup(ts); | ||
449 | |||
450 | err = request_irq(bus->irq, ad7879_irq, | ||
451 | IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts); | ||
452 | |||
453 | if (err) { | ||
454 | dev_err(&bus->dev, "irq %d busy?\n", bus->irq); | ||
455 | goto err_free_mem; | ||
456 | } | ||
457 | |||
458 | err = sysfs_create_group(&bus->dev.kobj, &ad7879_attr_group); | ||
459 | if (err) | ||
460 | goto err_free_irq; | ||
461 | |||
462 | err = input_register_device(input_dev); | ||
463 | if (err) | ||
464 | goto err_remove_attr; | ||
465 | |||
466 | dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n", | ||
467 | revid >> 8, bus->irq); | ||
468 | |||
469 | return 0; | ||
470 | |||
471 | err_remove_attr: | ||
472 | sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group); | ||
473 | err_free_irq: | ||
474 | free_irq(bus->irq, ts); | ||
475 | err_free_mem: | ||
476 | input_free_device(input_dev); | ||
477 | |||
478 | return err; | ||
479 | } | ||
480 | |||
481 | static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts) | ||
482 | { | ||
483 | ad7879_disable(ts); | ||
484 | sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group); | ||
485 | free_irq(ts->bus->irq, ts); | ||
486 | input_unregister_device(ts->input); | ||
487 | dev_dbg(&bus->dev, "unregistered touchscreen\n"); | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | #ifdef CONFIG_PM | ||
493 | static int ad7879_suspend(bus_device *bus, pm_message_t message) | ||
494 | { | ||
495 | struct ad7879 *ts = dev_get_drvdata(&bus->dev); | ||
496 | |||
497 | ad7879_disable(ts); | ||
498 | |||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static int ad7879_resume(bus_device *bus) | ||
503 | { | ||
504 | struct ad7879 *ts = dev_get_drvdata(&bus->dev); | ||
505 | |||
506 | ad7879_enable(ts); | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | #else | ||
511 | #define ad7879_suspend NULL | ||
512 | #define ad7879_resume NULL | ||
513 | #endif | ||
514 | |||
515 | #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) | ||
516 | #define MAX_SPI_FREQ_HZ 5000000 | ||
517 | #define AD7879_CMD_MAGIC 0xE000 | ||
518 | #define AD7879_CMD_READ (1 << 10) | ||
519 | #define AD7879_WRITECMD(reg) (AD7879_CMD_MAGIC | (reg & 0xF)) | ||
520 | #define AD7879_READCMD(reg) (AD7879_CMD_MAGIC | AD7879_CMD_READ | (reg & 0xF)) | ||
521 | |||
522 | struct ser_req { | ||
523 | u16 command; | ||
524 | u16 data; | ||
525 | struct spi_message msg; | ||
526 | struct spi_transfer xfer[2]; | ||
527 | }; | ||
528 | |||
529 | /* | ||
530 | * ad7879_read/write are only used for initial setup and for sysfs controls. | ||
531 | * The main traffic is done in ad7879_collect(). | ||
532 | */ | ||
533 | |||
534 | static int ad7879_read(struct spi_device *spi, u8 reg) | ||
535 | { | ||
536 | struct ser_req *req; | ||
537 | int status, ret; | ||
538 | |||
539 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
540 | if (!req) | ||
541 | return -ENOMEM; | ||
542 | |||
543 | spi_message_init(&req->msg); | ||
544 | |||
545 | req->command = (u16) AD7879_READCMD(reg); | ||
546 | req->xfer[0].tx_buf = &req->command; | ||
547 | req->xfer[0].len = 2; | ||
548 | |||
549 | req->xfer[1].rx_buf = &req->data; | ||
550 | req->xfer[1].len = 2; | ||
551 | |||
552 | spi_message_add_tail(&req->xfer[0], &req->msg); | ||
553 | spi_message_add_tail(&req->xfer[1], &req->msg); | ||
554 | |||
555 | status = spi_sync(spi, &req->msg); | ||
556 | ret = status ? : req->data; | ||
557 | |||
558 | kfree(req); | ||
559 | |||
560 | return ret; | ||
561 | } | ||
562 | |||
563 | static int ad7879_write(struct spi_device *spi, u8 reg, u16 val) | ||
564 | { | ||
565 | struct ser_req *req; | ||
566 | int status; | ||
567 | |||
568 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
569 | if (!req) | ||
570 | return -ENOMEM; | ||
571 | |||
572 | spi_message_init(&req->msg); | ||
573 | |||
574 | req->command = (u16) AD7879_WRITECMD(reg); | ||
575 | req->xfer[0].tx_buf = &req->command; | ||
576 | req->xfer[0].len = 2; | ||
577 | |||
578 | req->data = val; | ||
579 | req->xfer[1].tx_buf = &req->data; | ||
580 | req->xfer[1].len = 2; | ||
581 | |||
582 | spi_message_add_tail(&req->xfer[0], &req->msg); | ||
583 | spi_message_add_tail(&req->xfer[1], &req->msg); | ||
584 | |||
585 | status = spi_sync(spi, &req->msg); | ||
586 | |||
587 | kfree(req); | ||
588 | |||
589 | return status; | ||
590 | } | ||
591 | |||
592 | static void ad7879_collect(struct ad7879 *ts) | ||
593 | { | ||
594 | int status = spi_sync(ts->bus, &ts->msg); | ||
595 | |||
596 | if (status) | ||
597 | dev_err(&ts->bus->dev, "spi_sync --> %d\n", status); | ||
598 | } | ||
599 | |||
600 | static void ad7879_setup_ts_def_msg(struct ad7879 *ts) | ||
601 | { | ||
602 | struct spi_message *m; | ||
603 | int i; | ||
604 | |||
605 | ts->cmd = (u16) AD7879_READCMD(AD7879_REG_XPLUS); | ||
606 | |||
607 | m = &ts->msg; | ||
608 | spi_message_init(m); | ||
609 | ts->xfer[0].tx_buf = &ts->cmd; | ||
610 | ts->xfer[0].len = 2; | ||
611 | |||
612 | spi_message_add_tail(&ts->xfer[0], m); | ||
613 | |||
614 | for (i = 0; i < AD7879_NR_SENSE; i++) { | ||
615 | ts->xfer[i + 1].rx_buf = &ts->conversion_data[i]; | ||
616 | ts->xfer[i + 1].len = 2; | ||
617 | spi_message_add_tail(&ts->xfer[i + 1], m); | ||
618 | } | ||
619 | } | ||
620 | |||
621 | static int __devinit ad7879_probe(struct spi_device *spi) | ||
622 | { | ||
623 | struct ad7879 *ts; | ||
624 | int error; | ||
625 | |||
626 | /* don't exceed max specified SPI CLK frequency */ | ||
627 | if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) { | ||
628 | dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz); | ||
629 | return -EINVAL; | ||
630 | } | ||
631 | |||
632 | ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL); | ||
633 | if (!ts) | ||
634 | return -ENOMEM; | ||
635 | |||
636 | dev_set_drvdata(&spi->dev, ts); | ||
637 | ts->bus = spi; | ||
638 | |||
639 | ad7879_setup_ts_def_msg(ts); | ||
640 | |||
641 | error = ad7879_construct(spi, ts); | ||
642 | if (error) { | ||
643 | dev_set_drvdata(&spi->dev, NULL); | ||
644 | kfree(ts); | ||
645 | } | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | static int __devexit ad7879_remove(struct spi_device *spi) | ||
651 | { | ||
652 | struct ad7879 *ts = dev_get_drvdata(&spi->dev); | ||
653 | |||
654 | ad7879_destroy(spi, ts); | ||
655 | dev_set_drvdata(&spi->dev, NULL); | ||
656 | kfree(ts); | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static struct spi_driver ad7879_driver = { | ||
662 | .driver = { | ||
663 | .name = "ad7879", | ||
664 | .bus = &spi_bus_type, | ||
665 | .owner = THIS_MODULE, | ||
666 | }, | ||
667 | .probe = ad7879_probe, | ||
668 | .remove = __devexit_p(ad7879_remove), | ||
669 | .suspend = ad7879_suspend, | ||
670 | .resume = ad7879_resume, | ||
671 | }; | ||
672 | |||
673 | static int __init ad7879_init(void) | ||
674 | { | ||
675 | return spi_register_driver(&ad7879_driver); | ||
676 | } | ||
677 | module_init(ad7879_init); | ||
678 | |||
679 | static void __exit ad7879_exit(void) | ||
680 | { | ||
681 | spi_unregister_driver(&ad7879_driver); | ||
682 | } | ||
683 | module_exit(ad7879_exit); | ||
684 | |||
685 | #elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE) | ||
686 | |||
687 | /* All registers are word-sized. | ||
688 | * AD7879 uses a high-byte first convention. | ||
689 | */ | ||
690 | static int ad7879_read(struct i2c_client *client, u8 reg) | ||
691 | { | ||
692 | return swab16(i2c_smbus_read_word_data(client, reg)); | ||
693 | } | ||
694 | |||
695 | static int ad7879_write(struct i2c_client *client, u8 reg, u16 val) | ||
696 | { | ||
697 | return i2c_smbus_write_word_data(client, reg, swab16(val)); | ||
698 | } | ||
699 | |||
700 | static void ad7879_collect(struct ad7879 *ts) | ||
701 | { | ||
702 | int i; | ||
703 | |||
704 | for (i = 0; i < AD7879_NR_SENSE; i++) | ||
705 | ts->conversion_data[i] = ad7879_read(ts->bus, | ||
706 | AD7879_REG_XPLUS + i); | ||
707 | } | ||
708 | |||
709 | static int __devinit ad7879_probe(struct i2c_client *client, | ||
710 | const struct i2c_device_id *id) | ||
711 | { | ||
712 | struct ad7879 *ts; | ||
713 | int error; | ||
714 | |||
715 | if (!i2c_check_functionality(client->adapter, | ||
716 | I2C_FUNC_SMBUS_WORD_DATA)) { | ||
717 | dev_err(&client->dev, "SMBUS Word Data not Supported\n"); | ||
718 | return -EIO; | ||
719 | } | ||
720 | |||
721 | ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL); | ||
722 | if (!ts) | ||
723 | return -ENOMEM; | ||
724 | |||
725 | i2c_set_clientdata(client, ts); | ||
726 | ts->bus = client; | ||
727 | |||
728 | error = ad7879_construct(client, ts); | ||
729 | if (error) { | ||
730 | i2c_set_clientdata(client, NULL); | ||
731 | kfree(ts); | ||
732 | } | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int __devexit ad7879_remove(struct i2c_client *client) | ||
738 | { | ||
739 | struct ad7879 *ts = dev_get_drvdata(&client->dev); | ||
740 | |||
741 | ad7879_destroy(client, ts); | ||
742 | i2c_set_clientdata(client, NULL); | ||
743 | kfree(ts); | ||
744 | |||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | static const struct i2c_device_id ad7879_id[] = { | ||
749 | { "ad7879", 0 }, | ||
750 | { } | ||
751 | }; | ||
752 | MODULE_DEVICE_TABLE(i2c, ad7879_id); | ||
753 | |||
754 | static struct i2c_driver ad7879_driver = { | ||
755 | .driver = { | ||
756 | .name = "ad7879", | ||
757 | .owner = THIS_MODULE, | ||
758 | }, | ||
759 | .probe = ad7879_probe, | ||
760 | .remove = __devexit_p(ad7879_remove), | ||
761 | .suspend = ad7879_suspend, | ||
762 | .resume = ad7879_resume, | ||
763 | .id_table = ad7879_id, | ||
764 | }; | ||
765 | |||
766 | static int __init ad7879_init(void) | ||
767 | { | ||
768 | return i2c_add_driver(&ad7879_driver); | ||
769 | } | ||
770 | module_init(ad7879_init); | ||
771 | |||
772 | static void __exit ad7879_exit(void) | ||
773 | { | ||
774 | i2c_del_driver(&ad7879_driver); | ||
775 | } | ||
776 | module_exit(ad7879_exit); | ||
777 | #endif | ||
778 | |||
779 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | ||
780 | MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver"); | ||
781 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 056ac77e2cf0..2b01e56568f8 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -127,6 +127,8 @@ struct ads7846 { | |||
127 | void (*filter_cleanup)(void *data); | 127 | void (*filter_cleanup)(void *data); |
128 | int (*get_pendown_state)(void); | 128 | int (*get_pendown_state)(void); |
129 | int gpio_pendown; | 129 | int gpio_pendown; |
130 | |||
131 | void (*wait_for_sync)(void); | ||
130 | }; | 132 | }; |
131 | 133 | ||
132 | /* leave chip selected when we're done, for quicker re-select? */ | 134 | /* leave chip selected when we're done, for quicker re-select? */ |
@@ -511,6 +513,10 @@ static int get_pendown_state(struct ads7846 *ts) | |||
511 | return !gpio_get_value(ts->gpio_pendown); | 513 | return !gpio_get_value(ts->gpio_pendown); |
512 | } | 514 | } |
513 | 515 | ||
516 | static void null_wait_for_sync(void) | ||
517 | { | ||
518 | } | ||
519 | |||
514 | /* | 520 | /* |
515 | * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, | 521 | * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, |
516 | * to retrieve touchscreen status. | 522 | * to retrieve touchscreen status. |
@@ -686,6 +692,7 @@ static void ads7846_rx_val(void *ads) | |||
686 | default: | 692 | default: |
687 | BUG(); | 693 | BUG(); |
688 | } | 694 | } |
695 | ts->wait_for_sync(); | ||
689 | status = spi_async(ts->spi, m); | 696 | status = spi_async(ts->spi, m); |
690 | if (status) | 697 | if (status) |
691 | dev_err(&ts->spi->dev, "spi_async --> %d\n", | 698 | dev_err(&ts->spi->dev, "spi_async --> %d\n", |
@@ -723,6 +730,7 @@ static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) | |||
723 | } else { | 730 | } else { |
724 | /* pen is still down, continue with the measurement */ | 731 | /* pen is still down, continue with the measurement */ |
725 | ts->msg_idx = 0; | 732 | ts->msg_idx = 0; |
733 | ts->wait_for_sync(); | ||
726 | status = spi_async(ts->spi, &ts->msg[0]); | 734 | status = spi_async(ts->spi, &ts->msg[0]); |
727 | if (status) | 735 | if (status) |
728 | dev_err(&ts->spi->dev, "spi_async --> %d\n", status); | 736 | dev_err(&ts->spi->dev, "spi_async --> %d\n", status); |
@@ -746,7 +754,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle) | |||
746 | * that here. (The "generic irq" framework may help...) | 754 | * that here. (The "generic irq" framework may help...) |
747 | */ | 755 | */ |
748 | ts->irq_disabled = 1; | 756 | ts->irq_disabled = 1; |
749 | disable_irq(ts->spi->irq); | 757 | disable_irq_nosync(ts->spi->irq); |
750 | ts->pending = 1; | 758 | ts->pending = 1; |
751 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), | 759 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), |
752 | HRTIMER_MODE_REL); | 760 | HRTIMER_MODE_REL); |
@@ -947,6 +955,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
947 | ts->penirq_recheck_delay_usecs = | 955 | ts->penirq_recheck_delay_usecs = |
948 | pdata->penirq_recheck_delay_usecs; | 956 | pdata->penirq_recheck_delay_usecs; |
949 | 957 | ||
958 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | ||
959 | |||
950 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | 960 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); |
951 | 961 | ||
952 | input_dev->name = "ADS784x Touchscreen"; | 962 | input_dev->name = "ADS784x Touchscreen"; |
diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c index fa67d782c3c3..3ffd4c4b170c 100644 --- a/drivers/input/touchscreen/da9034-ts.c +++ b/drivers/input/touchscreen/da9034-ts.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2006-2008 Marvell International Ltd. | 4 | * Copyright (C) 2006-2008 Marvell International Ltd. |
5 | * Fengwei Yin <fengwei.yin@marvell.com> | 5 | * Fengwei Yin <fengwei.yin@marvell.com> |
6 | * Bin Yang <bin.yang@marvell.com> | ||
6 | * Eric Miao <eric.miao@marvell.com> | 7 | * Eric Miao <eric.miao@marvell.com> |
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
@@ -175,6 +176,16 @@ static void da9034_event_handler(struct da9034_touch *touch, int event) | |||
175 | goto err_reset; | 176 | goto err_reset; |
176 | 177 | ||
177 | touch->state = STATE_STOP; | 178 | touch->state = STATE_STOP; |
179 | |||
180 | /* FIXME: PEN_{UP/DOWN} events are expected to be | ||
181 | * available by stopping TSI, but this is found not | ||
182 | * always true, delay and simulate such an event | ||
183 | * here is more reliable | ||
184 | */ | ||
185 | mdelay(1); | ||
186 | da9034_event_handler(touch, | ||
187 | is_pen_down(touch) ? EVENT_PEN_DOWN : | ||
188 | EVENT_PEN_UP); | ||
178 | break; | 189 | break; |
179 | 190 | ||
180 | case STATE_STOP: | 191 | case STATE_STOP: |
@@ -189,8 +200,6 @@ static void da9034_event_handler(struct da9034_touch *touch, int event) | |||
189 | report_pen_up(touch); | 200 | report_pen_up(touch); |
190 | touch->state = STATE_IDLE; | 201 | touch->state = STATE_IDLE; |
191 | } | 202 | } |
192 | |||
193 | input_sync(touch->input_dev); | ||
194 | break; | 203 | break; |
195 | 204 | ||
196 | case STATE_WAIT: | 205 | case STATE_WAIT: |
@@ -200,8 +209,10 @@ static void da9034_event_handler(struct da9034_touch *touch, int event) | |||
200 | if (is_pen_down(touch)) { | 209 | if (is_pen_down(touch)) { |
201 | start_tsi(touch); | 210 | start_tsi(touch); |
202 | touch->state = STATE_BUSY; | 211 | touch->state = STATE_BUSY; |
203 | } else | 212 | } else { |
213 | report_pen_up(touch); | ||
204 | touch->state = STATE_IDLE; | 214 | touch->state = STATE_IDLE; |
215 | } | ||
205 | break; | 216 | break; |
206 | } | 217 | } |
207 | return; | 218 | return; |
@@ -226,16 +237,12 @@ static int da9034_touch_notifier(struct notifier_block *nb, | |||
226 | struct da9034_touch *touch = | 237 | struct da9034_touch *touch = |
227 | container_of(nb, struct da9034_touch, notifier); | 238 | container_of(nb, struct da9034_touch, notifier); |
228 | 239 | ||
229 | if (event & DA9034_EVENT_PEN_DOWN) { | ||
230 | if (is_pen_down(touch)) | ||
231 | da9034_event_handler(touch, EVENT_PEN_DOWN); | ||
232 | else | ||
233 | da9034_event_handler(touch, EVENT_PEN_UP); | ||
234 | } | ||
235 | |||
236 | if (event & DA9034_EVENT_TSI_READY) | 240 | if (event & DA9034_EVENT_TSI_READY) |
237 | da9034_event_handler(touch, EVENT_TSI_READY); | 241 | da9034_event_handler(touch, EVENT_TSI_READY); |
238 | 242 | ||
243 | if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE) | ||
244 | da9034_event_handler(touch, EVENT_PEN_DOWN); | ||
245 | |||
239 | return 0; | 246 | return 0; |
240 | } | 247 | } |
241 | 248 | ||
@@ -385,6 +392,6 @@ static void __exit da9034_touch_exit(void) | |||
385 | module_exit(da9034_touch_exit); | 392 | module_exit(da9034_touch_exit); |
386 | 393 | ||
387 | MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034"); | 394 | MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9034"); |
388 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); | 395 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>, Bin Yang <bin.yang@marvell.com>"); |
389 | MODULE_LICENSE("GPL"); | 396 | MODULE_LICENSE("GPL"); |
390 | MODULE_ALIAS("platform:da9034-touch"); | 397 | MODULE_ALIAS("platform:da9034-touch"); |
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 1d11e2be9ef8..4cc047a5116e 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c | |||
@@ -111,13 +111,12 @@ static void wm97xx_acc_pen_up(struct wm97xx *wm) | |||
111 | #else | 111 | #else |
112 | static void wm97xx_acc_pen_up(struct wm97xx *wm) | 112 | static void wm97xx_acc_pen_up(struct wm97xx *wm) |
113 | { | 113 | { |
114 | int count = 16; | 114 | unsigned int count; |
115 | |||
115 | schedule_timeout_uninterruptible(1); | 116 | schedule_timeout_uninterruptible(1); |
116 | 117 | ||
117 | while (count < 16) { | 118 | for (count = 0; count < 16; count++) |
118 | MODR; | 119 | MODR; |
119 | count--; | ||
120 | } | ||
121 | } | 120 | } |
122 | #endif | 121 | #endif |
123 | 122 | ||
@@ -162,6 +161,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) | |||
162 | input_report_abs(wm->input_dev, ABS_X, x & 0xfff); | 161 | input_report_abs(wm->input_dev, ABS_X, x & 0xfff); |
163 | input_report_abs(wm->input_dev, ABS_Y, y & 0xfff); | 162 | input_report_abs(wm->input_dev, ABS_Y, y & 0xfff); |
164 | input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff); | 163 | input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff); |
164 | input_report_key(wm->input_dev, BTN_TOUCH, (p != 0)); | ||
165 | input_sync(wm->input_dev); | 165 | input_sync(wm->input_dev); |
166 | reads++; | 166 | reads++; |
167 | } while (reads < cinfo[sp_idx].reads); | 167 | } while (reads < cinfo[sp_idx].reads); |
@@ -245,7 +245,7 @@ static void wm97xx_irq_enable(struct wm97xx *wm, int enable) | |||
245 | if (enable) | 245 | if (enable) |
246 | enable_irq(wm->pen_irq); | 246 | enable_irq(wm->pen_irq); |
247 | else | 247 | else |
248 | disable_irq(wm->pen_irq); | 248 | disable_irq_nosync(wm->pen_irq); |
249 | } | 249 | } |
250 | 250 | ||
251 | static struct wm97xx_mach_ops mainstone_mach_ops = { | 251 | static struct wm97xx_mach_ops mainstone_mach_ops = { |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 54986627def0..e868264fe799 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -151,12 +151,14 @@ static void ucb1400_ts_evt_add(struct input_dev *idev, u16 pressure, u16 x, u16 | |||
151 | input_report_abs(idev, ABS_X, x); | 151 | input_report_abs(idev, ABS_X, x); |
152 | input_report_abs(idev, ABS_Y, y); | 152 | input_report_abs(idev, ABS_Y, y); |
153 | input_report_abs(idev, ABS_PRESSURE, pressure); | 153 | input_report_abs(idev, ABS_PRESSURE, pressure); |
154 | input_report_key(idev, BTN_TOUCH, 1); | ||
154 | input_sync(idev); | 155 | input_sync(idev); |
155 | } | 156 | } |
156 | 157 | ||
157 | static void ucb1400_ts_event_release(struct input_dev *idev) | 158 | static void ucb1400_ts_event_release(struct input_dev *idev) |
158 | { | 159 | { |
159 | input_report_abs(idev, ABS_PRESSURE, 0); | 160 | input_report_abs(idev, ABS_PRESSURE, 0); |
161 | input_report_key(idev, BTN_TOUCH, 0); | ||
160 | input_sync(idev); | 162 | input_sync(idev); |
161 | } | 163 | } |
162 | 164 | ||
@@ -377,7 +379,8 @@ static int ucb1400_ts_probe(struct platform_device *dev) | |||
377 | ucb->ts_idev->id.product = ucb->id; | 379 | ucb->ts_idev->id.product = ucb->id; |
378 | ucb->ts_idev->open = ucb1400_ts_open; | 380 | ucb->ts_idev->open = ucb1400_ts_open; |
379 | ucb->ts_idev->close = ucb1400_ts_close; | 381 | ucb->ts_idev->close = ucb1400_ts_close; |
380 | ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS); | 382 | ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); |
383 | ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
381 | 384 | ||
382 | ucb1400_adc_enable(ucb->ac97); | 385 | ucb1400_adc_enable(ucb->ac97); |
383 | x_res = ucb1400_ts_read_xres(ucb); | 386 | x_res = ucb1400_ts_read_xres(ucb); |
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index d15aa11d7056..69af8385ab14 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -370,8 +370,7 @@ static int wm97xx_init_pen_irq(struct wm97xx *wm) | |||
370 | * provided. */ | 370 | * provided. */ |
371 | BUG_ON(!wm->mach_ops->irq_enable); | 371 | BUG_ON(!wm->mach_ops->irq_enable); |
372 | 372 | ||
373 | if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, | 373 | if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, |
374 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | ||
375 | "wm97xx-pen", wm)) { | 374 | "wm97xx-pen", wm)) { |
376 | dev_err(wm->dev, | 375 | dev_err(wm->dev, |
377 | "Failed to register pen down interrupt, polling"); | 376 | "Failed to register pen down interrupt, polling"); |
@@ -409,6 +408,7 @@ static int wm97xx_read_samples(struct wm97xx *wm) | |||
409 | wm->pen_is_down = 0; | 408 | wm->pen_is_down = 0; |
410 | dev_dbg(wm->dev, "pen up\n"); | 409 | dev_dbg(wm->dev, "pen up\n"); |
411 | input_report_abs(wm->input_dev, ABS_PRESSURE, 0); | 410 | input_report_abs(wm->input_dev, ABS_PRESSURE, 0); |
411 | input_report_key(wm->input_dev, BTN_TOUCH, 0); | ||
412 | input_sync(wm->input_dev); | 412 | input_sync(wm->input_dev); |
413 | } else if (!(rc & RC_AGAIN)) { | 413 | } else if (!(rc & RC_AGAIN)) { |
414 | /* We need high frequency updates only while | 414 | /* We need high frequency updates only while |
@@ -433,6 +433,7 @@ static int wm97xx_read_samples(struct wm97xx *wm) | |||
433 | input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff); | 433 | input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff); |
434 | input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff); | 434 | input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff); |
435 | input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff); | 435 | input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff); |
436 | input_report_key(wm->input_dev, BTN_TOUCH, 1); | ||
436 | input_sync(wm->input_dev); | 437 | input_sync(wm->input_dev); |
437 | wm->pen_is_down = 1; | 438 | wm->pen_is_down = 1; |
438 | wm->ts_reader_interval = wm->ts_reader_min_interval; | 439 | wm->ts_reader_interval = wm->ts_reader_min_interval; |
@@ -628,18 +629,21 @@ static int wm97xx_probe(struct device *dev) | |||
628 | wm->input_dev->phys = "wm97xx"; | 629 | wm->input_dev->phys = "wm97xx"; |
629 | wm->input_dev->open = wm97xx_ts_input_open; | 630 | wm->input_dev->open = wm97xx_ts_input_open; |
630 | wm->input_dev->close = wm97xx_ts_input_close; | 631 | wm->input_dev->close = wm97xx_ts_input_close; |
631 | set_bit(EV_ABS, wm->input_dev->evbit); | 632 | |
632 | set_bit(ABS_X, wm->input_dev->absbit); | 633 | __set_bit(EV_ABS, wm->input_dev->evbit); |
633 | set_bit(ABS_Y, wm->input_dev->absbit); | 634 | __set_bit(EV_KEY, wm->input_dev->evbit); |
634 | set_bit(ABS_PRESSURE, wm->input_dev->absbit); | 635 | __set_bit(BTN_TOUCH, wm->input_dev->keybit); |
636 | |||
635 | input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1], | 637 | input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1], |
636 | abs_x[2], 0); | 638 | abs_x[2], 0); |
637 | input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1], | 639 | input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1], |
638 | abs_y[2], 0); | 640 | abs_y[2], 0); |
639 | input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1], | 641 | input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1], |
640 | abs_p[2], 0); | 642 | abs_p[2], 0); |
643 | |||
641 | input_set_drvdata(wm->input_dev, wm); | 644 | input_set_drvdata(wm->input_dev, wm); |
642 | wm->input_dev->dev.parent = dev; | 645 | wm->input_dev->dev.parent = dev; |
646 | |||
643 | ret = input_register_device(wm->input_dev); | 647 | ret = input_register_device(wm->input_dev); |
644 | if (ret < 0) | 648 | if (ret < 0) |
645 | goto dev_alloc_err; | 649 | goto dev_alloc_err; |
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c new file mode 100644 index 000000000000..41e4359c277c --- /dev/null +++ b/drivers/input/touchscreen/zylonite-wm97xx.c | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | * zylonite-wm97xx.c -- Zylonite Continuous Touch screen driver | ||
3 | * | ||
4 | * Copyright 2004, 2007, 2008 Wolfson Microelectronics PLC. | ||
5 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
6 | * Parts Copyright : Ian Molton <spyro@f2s.com> | ||
7 | * Andrew Zabolotny <zap@homelink.ru> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * Notes: | ||
15 | * This is a wm97xx extended touch driver supporting interrupt driven | ||
16 | * and continuous operation on Marvell Zylonite development systems | ||
17 | * (which have a WM9713 on board). | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/moduleparam.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/wm97xx.h> | ||
29 | |||
30 | #include <mach/hardware.h> | ||
31 | #include <mach/mfp.h> | ||
32 | #include <mach/regs-ac97.h> | ||
33 | |||
34 | struct continuous { | ||
35 | u16 id; /* codec id */ | ||
36 | u8 code; /* continuous code */ | ||
37 | u8 reads; /* number of coord reads per read cycle */ | ||
38 | u32 speed; /* number of coords per second */ | ||
39 | }; | ||
40 | |||
41 | #define WM_READS(sp) ((sp / HZ) + 1) | ||
42 | |||
43 | static const struct continuous cinfo[] = { | ||
44 | { WM9713_ID2, 0, WM_READS(94), 94 }, | ||
45 | { WM9713_ID2, 1, WM_READS(120), 120 }, | ||
46 | { WM9713_ID2, 2, WM_READS(154), 154 }, | ||
47 | { WM9713_ID2, 3, WM_READS(188), 188 }, | ||
48 | }; | ||
49 | |||
50 | /* continuous speed index */ | ||
51 | static int sp_idx; | ||
52 | |||
53 | /* | ||
54 | * Pen sampling frequency (Hz) in continuous mode. | ||
55 | */ | ||
56 | static int cont_rate = 200; | ||
57 | module_param(cont_rate, int, 0); | ||
58 | MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)"); | ||
59 | |||
60 | /* | ||
61 | * Pressure readback. | ||
62 | * | ||
63 | * Set to 1 to read back pen down pressure | ||
64 | */ | ||
65 | static int pressure; | ||
66 | module_param(pressure, int, 0); | ||
67 | MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)"); | ||
68 | |||
69 | /* | ||
70 | * AC97 touch data slot. | ||
71 | * | ||
72 | * Touch screen readback data ac97 slot | ||
73 | */ | ||
74 | static int ac97_touch_slot = 5; | ||
75 | module_param(ac97_touch_slot, int, 0); | ||
76 | MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number"); | ||
77 | |||
78 | |||
79 | /* flush AC97 slot 5 FIFO machines */ | ||
80 | static void wm97xx_acc_pen_up(struct wm97xx *wm) | ||
81 | { | ||
82 | int i; | ||
83 | |||
84 | msleep(1); | ||
85 | |||
86 | for (i = 0; i < 16; i++) | ||
87 | MODR; | ||
88 | } | ||
89 | |||
90 | static int wm97xx_acc_pen_down(struct wm97xx *wm) | ||
91 | { | ||
92 | u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES; | ||
93 | int reads = 0; | ||
94 | static u16 last, tries; | ||
95 | |||
96 | /* When the AC97 queue has been drained we need to allow time | ||
97 | * to buffer up samples otherwise we end up spinning polling | ||
98 | * for samples. The controller can't have a suitably low | ||
99 | * threashold set to use the notifications it gives. | ||
100 | */ | ||
101 | msleep(1); | ||
102 | |||
103 | if (tries > 5) { | ||
104 | tries = 0; | ||
105 | return RC_PENUP; | ||
106 | } | ||
107 | |||
108 | x = MODR; | ||
109 | if (x == last) { | ||
110 | tries++; | ||
111 | return RC_AGAIN; | ||
112 | } | ||
113 | last = x; | ||
114 | do { | ||
115 | if (reads) | ||
116 | x = MODR; | ||
117 | y = MODR; | ||
118 | if (pressure) | ||
119 | p = MODR; | ||
120 | |||
121 | /* are samples valid */ | ||
122 | if ((x & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_X || | ||
123 | (y & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_Y || | ||
124 | (p & WM97XX_ADCSRC_MASK) != WM97XX_ADCSEL_PRES) | ||
125 | goto up; | ||
126 | |||
127 | /* coordinate is good */ | ||
128 | tries = 0; | ||
129 | input_report_abs(wm->input_dev, ABS_X, x & 0xfff); | ||
130 | input_report_abs(wm->input_dev, ABS_Y, y & 0xfff); | ||
131 | input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff); | ||
132 | input_report_key(wm->input_dev, BTN_TOUCH, (p != 0)); | ||
133 | input_sync(wm->input_dev); | ||
134 | reads++; | ||
135 | } while (reads < cinfo[sp_idx].reads); | ||
136 | up: | ||
137 | return RC_PENDOWN | RC_AGAIN; | ||
138 | } | ||
139 | |||
140 | static int wm97xx_acc_startup(struct wm97xx *wm) | ||
141 | { | ||
142 | int idx; | ||
143 | |||
144 | /* check we have a codec */ | ||
145 | if (wm->ac97 == NULL) | ||
146 | return -ENODEV; | ||
147 | |||
148 | /* Go you big red fire engine */ | ||
149 | for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) { | ||
150 | if (wm->id != cinfo[idx].id) | ||
151 | continue; | ||
152 | sp_idx = idx; | ||
153 | if (cont_rate <= cinfo[idx].speed) | ||
154 | break; | ||
155 | } | ||
156 | wm->acc_rate = cinfo[sp_idx].code; | ||
157 | wm->acc_slot = ac97_touch_slot; | ||
158 | dev_info(wm->dev, | ||
159 | "zylonite accelerated touchscreen driver, %d samples/sec\n", | ||
160 | cinfo[sp_idx].speed); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static void wm97xx_irq_enable(struct wm97xx *wm, int enable) | ||
166 | { | ||
167 | if (enable) | ||
168 | enable_irq(wm->pen_irq); | ||
169 | else | ||
170 | disable_irq_nosync(wm->pen_irq); | ||
171 | } | ||
172 | |||
173 | static struct wm97xx_mach_ops zylonite_mach_ops = { | ||
174 | .acc_enabled = 1, | ||
175 | .acc_pen_up = wm97xx_acc_pen_up, | ||
176 | .acc_pen_down = wm97xx_acc_pen_down, | ||
177 | .acc_startup = wm97xx_acc_startup, | ||
178 | .irq_enable = wm97xx_irq_enable, | ||
179 | .irq_gpio = WM97XX_GPIO_2, | ||
180 | }; | ||
181 | |||
182 | static int zylonite_wm97xx_probe(struct platform_device *pdev) | ||
183 | { | ||
184 | struct wm97xx *wm = platform_get_drvdata(pdev); | ||
185 | int gpio_touch_irq; | ||
186 | |||
187 | if (cpu_is_pxa320()) | ||
188 | gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO15); | ||
189 | else | ||
190 | gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26); | ||
191 | |||
192 | wm->pen_irq = IRQ_GPIO(gpio_touch_irq); | ||
193 | set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH); | ||
194 | |||
195 | wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, | ||
196 | WM97XX_GPIO_POL_HIGH, | ||
197 | WM97XX_GPIO_STICKY, | ||
198 | WM97XX_GPIO_WAKE); | ||
199 | wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT, | ||
200 | WM97XX_GPIO_POL_HIGH, | ||
201 | WM97XX_GPIO_NOTSTICKY, | ||
202 | WM97XX_GPIO_NOWAKE); | ||
203 | |||
204 | return wm97xx_register_mach_ops(wm, &zylonite_mach_ops); | ||
205 | } | ||
206 | |||
207 | static int zylonite_wm97xx_remove(struct platform_device *pdev) | ||
208 | { | ||
209 | struct wm97xx *wm = platform_get_drvdata(pdev); | ||
210 | |||
211 | wm97xx_unregister_mach_ops(wm); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static struct platform_driver zylonite_wm97xx_driver = { | ||
217 | .probe = zylonite_wm97xx_probe, | ||
218 | .remove = zylonite_wm97xx_remove, | ||
219 | .driver = { | ||
220 | .name = "wm97xx-touch", | ||
221 | }, | ||
222 | }; | ||
223 | |||
224 | static int __init zylonite_wm97xx_init(void) | ||
225 | { | ||
226 | return platform_driver_register(&zylonite_wm97xx_driver); | ||
227 | } | ||
228 | |||
229 | static void __exit zylonite_wm97xx_exit(void) | ||
230 | { | ||
231 | platform_driver_unregister(&zylonite_wm97xx_driver); | ||
232 | } | ||
233 | |||
234 | module_init(zylonite_wm97xx_init); | ||
235 | module_exit(zylonite_wm97xx_exit); | ||
236 | |||
237 | /* Module information */ | ||
238 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
239 | MODULE_DESCRIPTION("wm97xx continuous touch driver for Zylonite"); | ||
240 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index ec3c0e507669..2b3a055059ea 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c | |||
@@ -149,14 +149,7 @@ static void usb_ctrl_complete(struct urb *urb) | |||
149 | if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { | 149 | if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { |
150 | /* Special case handling for pipe reset */ | 150 | /* Special case handling for pipe reset */ |
151 | le16_to_cpus(&ctrl_msg->dr.wIndex); | 151 | le16_to_cpus(&ctrl_msg->dr.wIndex); |
152 | 152 | usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex); | |
153 | /* toggle is reset on clear */ | ||
154 | usb_settoggle(adapter->usb_dev, | ||
155 | ctrl_msg->dr.wIndex & ~USB_DIR_IN, | ||
156 | (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0, | ||
157 | 0); | ||
158 | |||
159 | |||
160 | } | 153 | } |
161 | 154 | ||
162 | if (ctrl_msg->complete) | 155 | if (ctrl_msg->complete) |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 102ef4a14c5f..d2109054de85 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -82,7 +82,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, | |||
82 | if (!gpio_is_valid(template->gpio)) { | 82 | if (!gpio_is_valid(template->gpio)) { |
83 | printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n", | 83 | printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n", |
84 | template->gpio, template->name); | 84 | template->gpio, template->name); |
85 | return; | 85 | return 0; |
86 | } | 86 | } |
87 | 87 | ||
88 | ret = gpio_request(template->gpio, template->name); | 88 | ret = gpio_request(template->gpio, template->name); |
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index ac8a4a3741b8..af92a176697f 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h | |||
@@ -158,7 +158,8 @@ void free_interrupts(void); | |||
158 | /* segments.c: */ | 158 | /* segments.c: */ |
159 | void setup_default_gdt_entries(struct lguest_ro_state *state); | 159 | void setup_default_gdt_entries(struct lguest_ro_state *state); |
160 | void setup_guest_gdt(struct lg_cpu *cpu); | 160 | void setup_guest_gdt(struct lg_cpu *cpu); |
161 | void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num); | 161 | void load_guest_gdt_entry(struct lg_cpu *cpu, unsigned int i, |
162 | u32 low, u32 hi); | ||
162 | void guest_load_tls(struct lg_cpu *cpu, unsigned long tls_array); | 163 | void guest_load_tls(struct lg_cpu *cpu, unsigned long tls_array); |
163 | void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt); | 164 | void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt); |
164 | void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt); | 165 | void copy_gdt_tls(const struct lg_cpu *cpu, struct desc_struct *gdt); |
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c index 4f15439b7f12..7ede64ffeef9 100644 --- a/drivers/lguest/segments.c +++ b/drivers/lguest/segments.c | |||
@@ -144,18 +144,19 @@ void copy_gdt(const struct lg_cpu *cpu, struct desc_struct *gdt) | |||
144 | gdt[i] = cpu->arch.gdt[i]; | 144 | gdt[i] = cpu->arch.gdt[i]; |
145 | } | 145 | } |
146 | 146 | ||
147 | /*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). | 147 | /*H:620 This is where the Guest asks us to load a new GDT entry |
148 | * We copy it from the Guest and tweak the entries. */ | 148 | * (LHCALL_LOAD_GDT_ENTRY). We tweak the entry and copy it in. */ |
149 | void load_guest_gdt(struct lg_cpu *cpu, unsigned long table, u32 num) | 149 | void load_guest_gdt_entry(struct lg_cpu *cpu, u32 num, u32 lo, u32 hi) |
150 | { | 150 | { |
151 | /* We assume the Guest has the same number of GDT entries as the | 151 | /* We assume the Guest has the same number of GDT entries as the |
152 | * Host, otherwise we'd have to dynamically allocate the Guest GDT. */ | 152 | * Host, otherwise we'd have to dynamically allocate the Guest GDT. */ |
153 | if (num > ARRAY_SIZE(cpu->arch.gdt)) | 153 | if (num > ARRAY_SIZE(cpu->arch.gdt)) |
154 | kill_guest(cpu, "too many gdt entries %i", num); | 154 | kill_guest(cpu, "too many gdt entries %i", num); |
155 | 155 | ||
156 | /* We read the whole thing in, then fix it up. */ | 156 | /* Set it up, then fix it. */ |
157 | __lgread(cpu, cpu->arch.gdt, table, num * sizeof(cpu->arch.gdt[0])); | 157 | cpu->arch.gdt[num].a = lo; |
158 | fixup_gdt_table(cpu, 0, ARRAY_SIZE(cpu->arch.gdt)); | 158 | cpu->arch.gdt[num].b = hi; |
159 | fixup_gdt_table(cpu, num, num+1); | ||
159 | /* Mark that the GDT changed so the core knows it has to copy it again, | 160 | /* Mark that the GDT changed so the core knows it has to copy it again, |
160 | * even if the Guest is run on the same CPU. */ | 161 | * even if the Guest is run on the same CPU. */ |
161 | cpu->changed |= CHANGED_GDT; | 162 | cpu->changed |= CHANGED_GDT; |
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index a6b717644be0..1a83910f674f 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
@@ -324,6 +324,11 @@ static void rewrite_hypercall(struct lg_cpu *cpu) | |||
324 | u8 insn[3] = {0xcd, 0x1f, 0x90}; | 324 | u8 insn[3] = {0xcd, 0x1f, 0x90}; |
325 | 325 | ||
326 | __lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn)); | 326 | __lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn)); |
327 | /* The above write might have caused a copy of that page to be made | ||
328 | * (if it was read-only). We need to make sure the Guest has | ||
329 | * up-to-date pagetables. As this doesn't happen often, we can just | ||
330 | * drop them all. */ | ||
331 | guest_pagetable_clear_all(cpu); | ||
327 | } | 332 | } |
328 | 333 | ||
329 | static bool is_hypercall(struct lg_cpu *cpu) | 334 | static bool is_hypercall(struct lg_cpu *cpu) |
@@ -563,8 +568,8 @@ void __exit lguest_arch_host_fini(void) | |||
563 | int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args) | 568 | int lguest_arch_do_hcall(struct lg_cpu *cpu, struct hcall_args *args) |
564 | { | 569 | { |
565 | switch (args->arg0) { | 570 | switch (args->arg0) { |
566 | case LHCALL_LOAD_GDT: | 571 | case LHCALL_LOAD_GDT_ENTRY: |
567 | load_guest_gdt(cpu, args->arg1, args->arg2); | 572 | load_guest_gdt_entry(cpu, args->arg1, args->arg2, args->arg3); |
568 | break; | 573 | break; |
569 | case LHCALL_LOAD_IDT_ENTRY: | 574 | case LHCALL_LOAD_IDT_ENTRY: |
570 | load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3); | 575 | load_guest_idt_entry(cpu, args->arg1, args->arg2, args->arg3); |
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 173cf55c64d0..3d906833948d 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -123,7 +123,7 @@ config PMAC_APM_EMU | |||
123 | 123 | ||
124 | config PMAC_MEDIABAY | 124 | config PMAC_MEDIABAY |
125 | bool "Support PowerBook hotswap media bay" | 125 | bool "Support PowerBook hotswap media bay" |
126 | depends on PPC_PMAC && PPC32 | 126 | depends on PPC_PMAC && PPC32 && BLOCK |
127 | help | 127 | help |
128 | This option adds support for older PowerBook's hotswap media bay | 128 | This option adds support for older PowerBook's hotswap media bay |
129 | that can contains batteries, floppy drives, or IDE devices. PCI | 129 | that can contains batteries, floppy drives, or IDE devices. PCI |
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index d7e46d345d9e..029ad8ce8a7e 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/timer.h> | 18 | #include <linux/timer.h> |
19 | #include <linux/stddef.h> | 19 | #include <linux/stddef.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/ide.h> | ||
22 | #include <linux/kthread.h> | 21 | #include <linux/kthread.h> |
23 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
24 | #include <asm/prom.h> | 23 | #include <asm/prom.h> |
@@ -447,6 +446,7 @@ int check_media_bay_by_base(unsigned long base, int what) | |||
447 | 446 | ||
448 | return -ENODEV; | 447 | return -ENODEV; |
449 | } | 448 | } |
449 | EXPORT_SYMBOL_GPL(check_media_bay_by_base); | ||
450 | 450 | ||
451 | int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, | 451 | int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, |
452 | int irq, ide_hwif_t *hwif) | 452 | int irq, ide_hwif_t *hwif) |
@@ -486,6 +486,7 @@ int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, | |||
486 | 486 | ||
487 | return -ENODEV; | 487 | return -ENODEV; |
488 | } | 488 | } |
489 | EXPORT_SYMBOL_GPL(media_bay_set_ide_infos); | ||
489 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | 490 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ |
490 | 491 | ||
491 | static void media_bay_step(int i) | 492 | static void media_bay_step(int i) |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index f8a9f7ab2cb8..1fb91edc7de2 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1479,6 +1479,7 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector) | |||
1479 | s += blocks; | 1479 | s += blocks; |
1480 | } | 1480 | } |
1481 | bitmap->last_end_sync = jiffies; | 1481 | bitmap->last_end_sync = jiffies; |
1482 | sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed"); | ||
1482 | } | 1483 | } |
1483 | 1484 | ||
1484 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) | 1485 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) |
@@ -1589,7 +1590,7 @@ void bitmap_destroy(mddev_t *mddev) | |||
1589 | int bitmap_create(mddev_t *mddev) | 1590 | int bitmap_create(mddev_t *mddev) |
1590 | { | 1591 | { |
1591 | struct bitmap *bitmap; | 1592 | struct bitmap *bitmap; |
1592 | unsigned long blocks = mddev->resync_max_sectors; | 1593 | sector_t blocks = mddev->resync_max_sectors; |
1593 | unsigned long chunks; | 1594 | unsigned long chunks; |
1594 | unsigned long pages; | 1595 | unsigned long pages; |
1595 | struct file *file = mddev->bitmap_file; | 1596 | struct file *file = mddev->bitmap_file; |
@@ -1631,8 +1632,8 @@ int bitmap_create(mddev_t *mddev) | |||
1631 | bitmap->chunkshift = ffz(~bitmap->chunksize); | 1632 | bitmap->chunkshift = ffz(~bitmap->chunksize); |
1632 | 1633 | ||
1633 | /* now that chunksize and chunkshift are set, we can use these macros */ | 1634 | /* now that chunksize and chunkshift are set, we can use these macros */ |
1634 | chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) / | 1635 | chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) >> |
1635 | CHUNK_BLOCK_RATIO(bitmap); | 1636 | CHUNK_BLOCK_SHIFT(bitmap); |
1636 | pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; | 1637 | pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; |
1637 | 1638 | ||
1638 | BUG_ON(!pages); | 1639 | BUG_ON(!pages); |
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h deleted file mode 100644 index 345098b4ca77..000000000000 --- a/drivers/md/dm-bio-list.h +++ /dev/null | |||
@@ -1,117 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Red Hat UK Ltd. | ||
3 | * | ||
4 | * This file is released under the GPL. | ||
5 | */ | ||
6 | |||
7 | #ifndef DM_BIO_LIST_H | ||
8 | #define DM_BIO_LIST_H | ||
9 | |||
10 | #include <linux/bio.h> | ||
11 | |||
12 | #ifdef CONFIG_BLOCK | ||
13 | |||
14 | struct bio_list { | ||
15 | struct bio *head; | ||
16 | struct bio *tail; | ||
17 | }; | ||
18 | |||
19 | static inline int bio_list_empty(const struct bio_list *bl) | ||
20 | { | ||
21 | return bl->head == NULL; | ||
22 | } | ||
23 | |||
24 | static inline void bio_list_init(struct bio_list *bl) | ||
25 | { | ||
26 | bl->head = bl->tail = NULL; | ||
27 | } | ||
28 | |||
29 | #define bio_list_for_each(bio, bl) \ | ||
30 | for (bio = (bl)->head; bio; bio = bio->bi_next) | ||
31 | |||
32 | static inline unsigned bio_list_size(const struct bio_list *bl) | ||
33 | { | ||
34 | unsigned sz = 0; | ||
35 | struct bio *bio; | ||
36 | |||
37 | bio_list_for_each(bio, bl) | ||
38 | sz++; | ||
39 | |||
40 | return sz; | ||
41 | } | ||
42 | |||
43 | static inline void bio_list_add(struct bio_list *bl, struct bio *bio) | ||
44 | { | ||
45 | bio->bi_next = NULL; | ||
46 | |||
47 | if (bl->tail) | ||
48 | bl->tail->bi_next = bio; | ||
49 | else | ||
50 | bl->head = bio; | ||
51 | |||
52 | bl->tail = bio; | ||
53 | } | ||
54 | |||
55 | static inline void bio_list_add_head(struct bio_list *bl, struct bio *bio) | ||
56 | { | ||
57 | bio->bi_next = bl->head; | ||
58 | |||
59 | bl->head = bio; | ||
60 | |||
61 | if (!bl->tail) | ||
62 | bl->tail = bio; | ||
63 | } | ||
64 | |||
65 | static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2) | ||
66 | { | ||
67 | if (!bl2->head) | ||
68 | return; | ||
69 | |||
70 | if (bl->tail) | ||
71 | bl->tail->bi_next = bl2->head; | ||
72 | else | ||
73 | bl->head = bl2->head; | ||
74 | |||
75 | bl->tail = bl2->tail; | ||
76 | } | ||
77 | |||
78 | static inline void bio_list_merge_head(struct bio_list *bl, | ||
79 | struct bio_list *bl2) | ||
80 | { | ||
81 | if (!bl2->head) | ||
82 | return; | ||
83 | |||
84 | if (bl->head) | ||
85 | bl2->tail->bi_next = bl->head; | ||
86 | else | ||
87 | bl->tail = bl2->tail; | ||
88 | |||
89 | bl->head = bl2->head; | ||
90 | } | ||
91 | |||
92 | static inline struct bio *bio_list_pop(struct bio_list *bl) | ||
93 | { | ||
94 | struct bio *bio = bl->head; | ||
95 | |||
96 | if (bio) { | ||
97 | bl->head = bl->head->bi_next; | ||
98 | if (!bl->head) | ||
99 | bl->tail = NULL; | ||
100 | |||
101 | bio->bi_next = NULL; | ||
102 | } | ||
103 | |||
104 | return bio; | ||
105 | } | ||
106 | |||
107 | static inline struct bio *bio_list_get(struct bio_list *bl) | ||
108 | { | ||
109 | struct bio *bio = bl->head; | ||
110 | |||
111 | bl->head = bl->tail = NULL; | ||
112 | |||
113 | return bio; | ||
114 | } | ||
115 | |||
116 | #endif /* CONFIG_BLOCK */ | ||
117 | #endif | ||
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c index 59ee1b015d2d..559dbb52bc85 100644 --- a/drivers/md/dm-delay.c +++ b/drivers/md/dm-delay.c | |||
@@ -15,8 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/device-mapper.h> | 16 | #include <linux/device-mapper.h> |
17 | 17 | ||
18 | #include "dm-bio-list.h" | ||
19 | |||
20 | #define DM_MSG_PREFIX "delay" | 18 | #define DM_MSG_PREFIX "delay" |
21 | 19 | ||
22 | struct delay_c { | 20 | struct delay_c { |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 095f77bf9681..6a386ab4f7eb 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/device-mapper.h> | 8 | #include <linux/device-mapper.h> |
9 | 9 | ||
10 | #include "dm-path-selector.h" | 10 | #include "dm-path-selector.h" |
11 | #include "dm-bio-list.h" | ||
12 | #include "dm-bio-record.h" | 11 | #include "dm-bio-record.h" |
13 | #include "dm-uevent.h" | 12 | #include "dm-uevent.h" |
14 | 13 | ||
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 536ef0bef154..076fbb4e967a 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * This file is released under the GPL. | 5 | * This file is released under the GPL. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "dm-bio-list.h" | ||
9 | #include "dm-bio-record.h" | 8 | #include "dm-bio-record.h" |
10 | 9 | ||
11 | #include <linux/init.h> | 10 | #include <linux/init.h> |
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 59f8d9df9e1a..7b899be0b087 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/vmalloc.h> | 14 | #include <linux/vmalloc.h> |
15 | 15 | ||
16 | #include "dm.h" | 16 | #include "dm.h" |
17 | #include "dm-bio-list.h" | ||
18 | 17 | ||
19 | #define DM_MSG_PREFIX "region hash" | 18 | #define DM_MSG_PREFIX "region hash" |
20 | 19 | ||
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 981a0413068f..d73f17fc7778 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/workqueue.h> | 22 | #include <linux/workqueue.h> |
23 | 23 | ||
24 | #include "dm-exception-store.h" | 24 | #include "dm-exception-store.h" |
25 | #include "dm-bio-list.h" | ||
26 | 25 | ||
27 | #define DM_MSG_PREFIX "snapshots" | 26 | #define DM_MSG_PREFIX "snapshots" |
28 | 27 | ||
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 8a994be035ba..424f7b048c30 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -6,7 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "dm.h" | 8 | #include "dm.h" |
9 | #include "dm-bio-list.h" | ||
10 | #include "dm-uevent.h" | 9 | #include "dm-uevent.h" |
11 | 10 | ||
12 | #include <linux/init.h> | 11 | #include <linux/init.h> |
diff --git a/drivers/md/md.c b/drivers/md/md.c index ed5727c089a9..612343fdde94 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2017,6 +2017,8 @@ repeat: | |||
2017 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); | 2017 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); |
2018 | spin_unlock_irq(&mddev->write_lock); | 2018 | spin_unlock_irq(&mddev->write_lock); |
2019 | wake_up(&mddev->sb_wait); | 2019 | wake_up(&mddev->sb_wait); |
2020 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | ||
2021 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
2020 | 2022 | ||
2021 | } | 2023 | } |
2022 | 2024 | ||
@@ -2086,6 +2088,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2086 | * -writemostly - clears write_mostly | 2088 | * -writemostly - clears write_mostly |
2087 | * blocked - sets the Blocked flag | 2089 | * blocked - sets the Blocked flag |
2088 | * -blocked - clears the Blocked flag | 2090 | * -blocked - clears the Blocked flag |
2091 | * insync - sets Insync providing device isn't active | ||
2089 | */ | 2092 | */ |
2090 | int err = -EINVAL; | 2093 | int err = -EINVAL; |
2091 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { | 2094 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { |
@@ -2118,6 +2121,9 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2118 | md_wakeup_thread(rdev->mddev->thread); | 2121 | md_wakeup_thread(rdev->mddev->thread); |
2119 | 2122 | ||
2120 | err = 0; | 2123 | err = 0; |
2124 | } else if (cmd_match(buf, "insync") && rdev->raid_disk == -1) { | ||
2125 | set_bit(In_sync, &rdev->flags); | ||
2126 | err = 0; | ||
2121 | } | 2127 | } |
2122 | if (!err && rdev->sysfs_state) | 2128 | if (!err && rdev->sysfs_state) |
2123 | sysfs_notify_dirent(rdev->sysfs_state); | 2129 | sysfs_notify_dirent(rdev->sysfs_state); |
@@ -2190,7 +2196,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2190 | } else if (rdev->mddev->pers) { | 2196 | } else if (rdev->mddev->pers) { |
2191 | mdk_rdev_t *rdev2; | 2197 | mdk_rdev_t *rdev2; |
2192 | /* Activating a spare .. or possibly reactivating | 2198 | /* Activating a spare .. or possibly reactivating |
2193 | * if we every get bitmaps working here. | 2199 | * if we ever get bitmaps working here. |
2194 | */ | 2200 | */ |
2195 | 2201 | ||
2196 | if (rdev->raid_disk != -1) | 2202 | if (rdev->raid_disk != -1) |
@@ -3482,12 +3488,15 @@ sync_completed_show(mddev_t *mddev, char *page) | |||
3482 | { | 3488 | { |
3483 | unsigned long max_sectors, resync; | 3489 | unsigned long max_sectors, resync; |
3484 | 3490 | ||
3491 | if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | ||
3492 | return sprintf(page, "none\n"); | ||
3493 | |||
3485 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) | 3494 | if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) |
3486 | max_sectors = mddev->resync_max_sectors; | 3495 | max_sectors = mddev->resync_max_sectors; |
3487 | else | 3496 | else |
3488 | max_sectors = mddev->dev_sectors; | 3497 | max_sectors = mddev->dev_sectors; |
3489 | 3498 | ||
3490 | resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active)); | 3499 | resync = mddev->curr_resync_completed; |
3491 | return sprintf(page, "%lu / %lu\n", resync, max_sectors); | 3500 | return sprintf(page, "%lu / %lu\n", resync, max_sectors); |
3492 | } | 3501 | } |
3493 | 3502 | ||
@@ -6334,18 +6343,13 @@ void md_do_sync(mddev_t *mddev) | |||
6334 | sector_t sectors; | 6343 | sector_t sectors; |
6335 | 6344 | ||
6336 | skipped = 0; | 6345 | skipped = 0; |
6337 | if (j >= mddev->resync_max) { | ||
6338 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
6339 | wait_event(mddev->recovery_wait, | ||
6340 | mddev->resync_max > j | ||
6341 | || kthread_should_stop()); | ||
6342 | } | ||
6343 | if (kthread_should_stop()) | ||
6344 | goto interrupted; | ||
6345 | 6346 | ||
6346 | if (mddev->curr_resync > mddev->curr_resync_completed && | 6347 | if ((mddev->curr_resync > mddev->curr_resync_completed && |
6347 | (mddev->curr_resync - mddev->curr_resync_completed) | 6348 | (mddev->curr_resync - mddev->curr_resync_completed) |
6348 | > (max_sectors >> 4)) { | 6349 | > (max_sectors >> 4)) || |
6350 | (j - mddev->curr_resync_completed)*2 | ||
6351 | >= mddev->resync_max - mddev->curr_resync_completed | ||
6352 | ) { | ||
6349 | /* time to update curr_resync_completed */ | 6353 | /* time to update curr_resync_completed */ |
6350 | blk_unplug(mddev->queue); | 6354 | blk_unplug(mddev->queue); |
6351 | wait_event(mddev->recovery_wait, | 6355 | wait_event(mddev->recovery_wait, |
@@ -6353,7 +6357,17 @@ void md_do_sync(mddev_t *mddev) | |||
6353 | mddev->curr_resync_completed = | 6357 | mddev->curr_resync_completed = |
6354 | mddev->curr_resync; | 6358 | mddev->curr_resync; |
6355 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 6359 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); |
6360 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
6356 | } | 6361 | } |
6362 | |||
6363 | if (j >= mddev->resync_max) | ||
6364 | wait_event(mddev->recovery_wait, | ||
6365 | mddev->resync_max > j | ||
6366 | || kthread_should_stop()); | ||
6367 | |||
6368 | if (kthread_should_stop()) | ||
6369 | goto interrupted; | ||
6370 | |||
6357 | sectors = mddev->pers->sync_request(mddev, j, &skipped, | 6371 | sectors = mddev->pers->sync_request(mddev, j, &skipped, |
6358 | currspeed < speed_min(mddev)); | 6372 | currspeed < speed_min(mddev)); |
6359 | if (sectors == 0) { | 6373 | if (sectors == 0) { |
@@ -6461,6 +6475,7 @@ void md_do_sync(mddev_t *mddev) | |||
6461 | 6475 | ||
6462 | skip: | 6476 | skip: |
6463 | mddev->curr_resync = 0; | 6477 | mddev->curr_resync = 0; |
6478 | mddev->curr_resync_completed = 0; | ||
6464 | mddev->resync_min = 0; | 6479 | mddev->resync_min = 0; |
6465 | mddev->resync_max = MaxSector; | 6480 | mddev->resync_max = MaxSector; |
6466 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | 6481 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); |
diff --git a/drivers/md/md.h b/drivers/md/md.h index e9b7f54c24d6..8227ab909d44 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -12,10 +12,17 @@ | |||
12 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 12 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #ifndef _MD_K_H | 15 | #ifndef _MD_MD_H |
16 | #define _MD_K_H | 16 | #define _MD_MD_H |
17 | 17 | ||
18 | #ifdef CONFIG_BLOCK | 18 | #include <linux/blkdev.h> |
19 | #include <linux/kobject.h> | ||
20 | #include <linux/list.h> | ||
21 | #include <linux/mm.h> | ||
22 | #include <linux/mutex.h> | ||
23 | #include <linux/timer.h> | ||
24 | #include <linux/wait.h> | ||
25 | #include <linux/workqueue.h> | ||
19 | 26 | ||
20 | #define MaxSector (~(sector_t)0) | 27 | #define MaxSector (~(sector_t)0) |
21 | 28 | ||
@@ -408,10 +415,6 @@ static inline void safe_put_page(struct page *p) | |||
408 | if (p) put_page(p); | 415 | if (p) put_page(p); |
409 | } | 416 | } |
410 | 417 | ||
411 | #endif /* CONFIG_BLOCK */ | ||
412 | #endif | ||
413 | |||
414 | |||
415 | extern int register_md_personality(struct mdk_personality *p); | 418 | extern int register_md_personality(struct mdk_personality *p); |
416 | extern int unregister_md_personality(struct mdk_personality *p); | 419 | extern int unregister_md_personality(struct mdk_personality *p); |
417 | extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), | 420 | extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), |
@@ -434,3 +437,5 @@ extern void md_new_event(mddev_t *mddev); | |||
434 | extern int md_allow_write(mddev_t *mddev); | 437 | extern int md_allow_write(mddev_t *mddev); |
435 | extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); | 438 | extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); |
436 | extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); | 439 | extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); |
440 | |||
441 | #endif /* _MD_MD_H */ | ||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 274b491a11c1..36df9109cde1 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/blkdev.h> | 35 | #include <linux/blkdev.h> |
36 | #include <linux/seq_file.h> | 36 | #include <linux/seq_file.h> |
37 | #include "md.h" | 37 | #include "md.h" |
38 | #include "dm-bio-list.h" | ||
39 | #include "raid1.h" | 38 | #include "raid1.h" |
40 | #include "bitmap.h" | 39 | #include "bitmap.h" |
41 | 40 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index e293d92641ac..81a54f17417e 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
24 | #include "md.h" | 24 | #include "md.h" |
25 | #include "dm-bio-list.h" | ||
26 | #include "raid10.h" | 25 | #include "raid10.h" |
27 | #include "bitmap.h" | 26 | #include "bitmap.h" |
28 | 27 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 3bbc6d647044..4616bc3a6e71 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3845,6 +3845,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3845 | wait_event(conf->wait_for_overlap, | 3845 | wait_event(conf->wait_for_overlap, |
3846 | atomic_read(&conf->reshape_stripes)==0); | 3846 | atomic_read(&conf->reshape_stripes)==0); |
3847 | mddev->reshape_position = conf->reshape_progress; | 3847 | mddev->reshape_position = conf->reshape_progress; |
3848 | mddev->curr_resync_completed = mddev->curr_resync; | ||
3848 | conf->reshape_checkpoint = jiffies; | 3849 | conf->reshape_checkpoint = jiffies; |
3849 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 3850 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
3850 | md_wakeup_thread(mddev->thread); | 3851 | md_wakeup_thread(mddev->thread); |
@@ -3854,6 +3855,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3854 | conf->reshape_safe = mddev->reshape_position; | 3855 | conf->reshape_safe = mddev->reshape_position; |
3855 | spin_unlock_irq(&conf->device_lock); | 3856 | spin_unlock_irq(&conf->device_lock); |
3856 | wake_up(&conf->wait_for_overlap); | 3857 | wake_up(&conf->wait_for_overlap); |
3858 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
3857 | } | 3859 | } |
3858 | 3860 | ||
3859 | if (mddev->delta_disks < 0) { | 3861 | if (mddev->delta_disks < 0) { |
@@ -3938,11 +3940,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3938 | * then we need to write out the superblock. | 3940 | * then we need to write out the superblock. |
3939 | */ | 3941 | */ |
3940 | sector_nr += reshape_sectors; | 3942 | sector_nr += reshape_sectors; |
3941 | if (sector_nr >= mddev->resync_max) { | 3943 | if ((sector_nr - mddev->curr_resync_completed) * 2 |
3944 | >= mddev->resync_max - mddev->curr_resync_completed) { | ||
3942 | /* Cannot proceed until we've updated the superblock... */ | 3945 | /* Cannot proceed until we've updated the superblock... */ |
3943 | wait_event(conf->wait_for_overlap, | 3946 | wait_event(conf->wait_for_overlap, |
3944 | atomic_read(&conf->reshape_stripes) == 0); | 3947 | atomic_read(&conf->reshape_stripes) == 0); |
3945 | mddev->reshape_position = conf->reshape_progress; | 3948 | mddev->reshape_position = conf->reshape_progress; |
3949 | mddev->curr_resync_completed = mddev->curr_resync; | ||
3946 | conf->reshape_checkpoint = jiffies; | 3950 | conf->reshape_checkpoint = jiffies; |
3947 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 3951 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
3948 | md_wakeup_thread(mddev->thread); | 3952 | md_wakeup_thread(mddev->thread); |
@@ -3953,6 +3957,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3953 | conf->reshape_safe = mddev->reshape_position; | 3957 | conf->reshape_safe = mddev->reshape_position; |
3954 | spin_unlock_irq(&conf->device_lock); | 3958 | spin_unlock_irq(&conf->device_lock); |
3955 | wake_up(&conf->wait_for_overlap); | 3959 | wake_up(&conf->wait_for_overlap); |
3960 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
3956 | } | 3961 | } |
3957 | return reshape_sectors; | 3962 | return reshape_sectors; |
3958 | } | 3963 | } |
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 92c297796a9f..bd945d04dc90 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
@@ -1200,7 +1200,7 @@ static int si470x_fops_release(struct file *file) | |||
1200 | video_unregister_device(radio->videodev); | 1200 | video_unregister_device(radio->videodev); |
1201 | kfree(radio->buffer); | 1201 | kfree(radio->buffer); |
1202 | kfree(radio); | 1202 | kfree(radio); |
1203 | goto unlock; | 1203 | goto done; |
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | /* stop rds reception */ | 1206 | /* stop rds reception */ |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index d9d974a8f52a..add3395d3248 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -1461,7 +1461,6 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) | |||
1461 | return ret; | 1461 | return ret; |
1462 | } | 1462 | } |
1463 | 1463 | ||
1464 | usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0); | ||
1465 | usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); | 1464 | usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); |
1466 | 1465 | ||
1467 | pipe = usb_sndctrlpipe(hdw->usb_dev, 0); | 1466 | pipe = usb_sndctrlpipe(hdw->usb_dev, 0); |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index f9fbe02e0f69..50b415e07eda 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -159,35 +159,67 @@ static void pwc_set_image_buffer_size(struct pwc_device *pdev); | |||
159 | 159 | ||
160 | /****************************************************************************/ | 160 | /****************************************************************************/ |
161 | 161 | ||
162 | static int _send_control_msg(struct pwc_device *pdev, | ||
163 | u8 request, u16 value, int index, void *buf, int buflen, int timeout) | ||
164 | { | ||
165 | int rc; | ||
166 | void *kbuf = NULL; | ||
167 | |||
168 | if (buflen) { | ||
169 | kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */ | ||
170 | if (kbuf == NULL) | ||
171 | return -ENOMEM; | ||
172 | memcpy(kbuf, buf, buflen); | ||
173 | } | ||
162 | 174 | ||
163 | #define SendControlMsg(request, value, buflen) \ | 175 | rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), |
164 | usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0), \ | 176 | request, |
165 | request, \ | 177 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
166 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \ | 178 | value, |
167 | value, \ | 179 | index, |
168 | pdev->vcinterface, \ | 180 | kbuf, buflen, timeout); |
169 | &buf, buflen, 500) | ||
170 | 181 | ||
171 | #define RecvControlMsg(request, value, buflen) \ | 182 | kfree(kbuf); |
172 | usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), \ | 183 | return rc; |
173 | request, \ | 184 | } |
174 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, \ | ||
175 | value, \ | ||
176 | pdev->vcinterface, \ | ||
177 | &buf, buflen, 500) | ||
178 | 185 | ||
186 | static int recv_control_msg(struct pwc_device *pdev, | ||
187 | u8 request, u16 value, void *buf, int buflen) | ||
188 | { | ||
189 | int rc; | ||
190 | void *kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */ | ||
191 | |||
192 | if (kbuf == NULL) | ||
193 | return -ENOMEM; | ||
194 | |||
195 | rc = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0), | ||
196 | request, | ||
197 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
198 | value, | ||
199 | pdev->vcinterface, | ||
200 | kbuf, buflen, 500); | ||
201 | memcpy(buf, kbuf, buflen); | ||
202 | kfree(kbuf); | ||
203 | return rc; | ||
204 | } | ||
179 | 205 | ||
180 | static int send_video_command(struct usb_device *udev, int index, void *buf, int buflen) | 206 | static inline int send_video_command(struct pwc_device *pdev, |
207 | int index, void *buf, int buflen) | ||
181 | { | 208 | { |
182 | return usb_control_msg(udev, | 209 | return _send_control_msg(pdev, |
183 | usb_sndctrlpipe(udev, 0), | ||
184 | SET_EP_STREAM_CTL, | 210 | SET_EP_STREAM_CTL, |
185 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
186 | VIDEO_OUTPUT_CONTROL_FORMATTER, | 211 | VIDEO_OUTPUT_CONTROL_FORMATTER, |
187 | index, | 212 | index, |
188 | buf, buflen, 1000); | 213 | buf, buflen, 1000); |
189 | } | 214 | } |
190 | 215 | ||
216 | static inline int send_control_msg(struct pwc_device *pdev, | ||
217 | u8 request, u16 value, void *buf, int buflen) | ||
218 | { | ||
219 | return _send_control_msg(pdev, | ||
220 | request, value, pdev->vcinterface, buf, buflen, 500); | ||
221 | } | ||
222 | |||
191 | 223 | ||
192 | 224 | ||
193 | static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) | 225 | static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) |
@@ -224,7 +256,7 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) | |||
224 | return -EINVAL; | 256 | return -EINVAL; |
225 | 257 | ||
226 | memcpy(buf, pEntry->mode, 3); | 258 | memcpy(buf, pEntry->mode, 3); |
227 | ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 3); | 259 | ret = send_video_command(pdev, pdev->vendpoint, buf, 3); |
228 | if (ret < 0) { | 260 | if (ret < 0) { |
229 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); | 261 | PWC_DEBUG_MODULE("Failed to send video command... %d\n", ret); |
230 | return ret; | 262 | return ret; |
@@ -285,7 +317,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, i | |||
285 | memcpy(buf, pChoose->mode, 13); | 317 | memcpy(buf, pChoose->mode, 13); |
286 | if (snapshot) | 318 | if (snapshot) |
287 | buf[0] |= 0x80; | 319 | buf[0] |= 0x80; |
288 | ret = send_video_command(pdev->udev, pdev->vendpoint, buf, 13); | 320 | ret = send_video_command(pdev, pdev->vendpoint, buf, 13); |
289 | if (ret < 0) | 321 | if (ret < 0) |
290 | return ret; | 322 | return ret; |
291 | 323 | ||
@@ -358,7 +390,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, i | |||
358 | buf[0] |= 0x80; | 390 | buf[0] |= 0x80; |
359 | 391 | ||
360 | /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ | 392 | /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ |
361 | ret = send_video_command(pdev->udev, 4 /* pdev->vendpoint */, buf, 12); | 393 | ret = send_video_command(pdev, 4 /* pdev->vendpoint */, buf, 12); |
362 | if (ret < 0) | 394 | if (ret < 0) |
363 | return ret; | 395 | return ret; |
364 | 396 | ||
@@ -530,7 +562,8 @@ int pwc_get_brightness(struct pwc_device *pdev) | |||
530 | char buf; | 562 | char buf; |
531 | int ret; | 563 | int ret; |
532 | 564 | ||
533 | ret = RecvControlMsg(GET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); | 565 | ret = recv_control_msg(pdev, |
566 | GET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf)); | ||
534 | if (ret < 0) | 567 | if (ret < 0) |
535 | return ret; | 568 | return ret; |
536 | return buf; | 569 | return buf; |
@@ -545,7 +578,8 @@ int pwc_set_brightness(struct pwc_device *pdev, int value) | |||
545 | if (value > 0xffff) | 578 | if (value > 0xffff) |
546 | value = 0xffff; | 579 | value = 0xffff; |
547 | buf = (value >> 9) & 0x7f; | 580 | buf = (value >> 9) & 0x7f; |
548 | return SendControlMsg(SET_LUM_CTL, BRIGHTNESS_FORMATTER, 1); | 581 | return send_control_msg(pdev, |
582 | SET_LUM_CTL, BRIGHTNESS_FORMATTER, &buf, sizeof(buf)); | ||
549 | } | 583 | } |
550 | 584 | ||
551 | /* CONTRAST */ | 585 | /* CONTRAST */ |
@@ -555,7 +589,8 @@ int pwc_get_contrast(struct pwc_device *pdev) | |||
555 | char buf; | 589 | char buf; |
556 | int ret; | 590 | int ret; |
557 | 591 | ||
558 | ret = RecvControlMsg(GET_LUM_CTL, CONTRAST_FORMATTER, 1); | 592 | ret = recv_control_msg(pdev, |
593 | GET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf)); | ||
559 | if (ret < 0) | 594 | if (ret < 0) |
560 | return ret; | 595 | return ret; |
561 | return buf; | 596 | return buf; |
@@ -570,7 +605,8 @@ int pwc_set_contrast(struct pwc_device *pdev, int value) | |||
570 | if (value > 0xffff) | 605 | if (value > 0xffff) |
571 | value = 0xffff; | 606 | value = 0xffff; |
572 | buf = (value >> 10) & 0x3f; | 607 | buf = (value >> 10) & 0x3f; |
573 | return SendControlMsg(SET_LUM_CTL, CONTRAST_FORMATTER, 1); | 608 | return send_control_msg(pdev, |
609 | SET_LUM_CTL, CONTRAST_FORMATTER, &buf, sizeof(buf)); | ||
574 | } | 610 | } |
575 | 611 | ||
576 | /* GAMMA */ | 612 | /* GAMMA */ |
@@ -580,7 +616,8 @@ int pwc_get_gamma(struct pwc_device *pdev) | |||
580 | char buf; | 616 | char buf; |
581 | int ret; | 617 | int ret; |
582 | 618 | ||
583 | ret = RecvControlMsg(GET_LUM_CTL, GAMMA_FORMATTER, 1); | 619 | ret = recv_control_msg(pdev, |
620 | GET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf)); | ||
584 | if (ret < 0) | 621 | if (ret < 0) |
585 | return ret; | 622 | return ret; |
586 | return buf; | 623 | return buf; |
@@ -595,7 +632,8 @@ int pwc_set_gamma(struct pwc_device *pdev, int value) | |||
595 | if (value > 0xffff) | 632 | if (value > 0xffff) |
596 | value = 0xffff; | 633 | value = 0xffff; |
597 | buf = (value >> 11) & 0x1f; | 634 | buf = (value >> 11) & 0x1f; |
598 | return SendControlMsg(SET_LUM_CTL, GAMMA_FORMATTER, 1); | 635 | return send_control_msg(pdev, |
636 | SET_LUM_CTL, GAMMA_FORMATTER, &buf, sizeof(buf)); | ||
599 | } | 637 | } |
600 | 638 | ||
601 | 639 | ||
@@ -613,7 +651,8 @@ int pwc_get_saturation(struct pwc_device *pdev, int *value) | |||
613 | saturation_register = SATURATION_MODE_FORMATTER2; | 651 | saturation_register = SATURATION_MODE_FORMATTER2; |
614 | else | 652 | else |
615 | saturation_register = SATURATION_MODE_FORMATTER1; | 653 | saturation_register = SATURATION_MODE_FORMATTER1; |
616 | ret = RecvControlMsg(GET_CHROM_CTL, saturation_register, 1); | 654 | ret = recv_control_msg(pdev, |
655 | GET_CHROM_CTL, saturation_register, &buf, sizeof(buf)); | ||
617 | if (ret < 0) | 656 | if (ret < 0) |
618 | return ret; | 657 | return ret; |
619 | *value = (signed)buf; | 658 | *value = (signed)buf; |
@@ -636,7 +675,8 @@ int pwc_set_saturation(struct pwc_device *pdev, int value) | |||
636 | saturation_register = SATURATION_MODE_FORMATTER2; | 675 | saturation_register = SATURATION_MODE_FORMATTER2; |
637 | else | 676 | else |
638 | saturation_register = SATURATION_MODE_FORMATTER1; | 677 | saturation_register = SATURATION_MODE_FORMATTER1; |
639 | return SendControlMsg(SET_CHROM_CTL, saturation_register, 1); | 678 | return send_control_msg(pdev, |
679 | SET_CHROM_CTL, saturation_register, &buf, sizeof(buf)); | ||
640 | } | 680 | } |
641 | 681 | ||
642 | /* AGC */ | 682 | /* AGC */ |
@@ -651,7 +691,8 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value) | |||
651 | else | 691 | else |
652 | buf = 0xff; /* fixed */ | 692 | buf = 0xff; /* fixed */ |
653 | 693 | ||
654 | ret = SendControlMsg(SET_LUM_CTL, AGC_MODE_FORMATTER, 1); | 694 | ret = send_control_msg(pdev, |
695 | SET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf)); | ||
655 | 696 | ||
656 | if (!mode && ret >= 0) { | 697 | if (!mode && ret >= 0) { |
657 | if (value < 0) | 698 | if (value < 0) |
@@ -659,7 +700,8 @@ int pwc_set_agc(struct pwc_device *pdev, int mode, int value) | |||
659 | if (value > 0xffff) | 700 | if (value > 0xffff) |
660 | value = 0xffff; | 701 | value = 0xffff; |
661 | buf = (value >> 10) & 0x3F; | 702 | buf = (value >> 10) & 0x3F; |
662 | ret = SendControlMsg(SET_LUM_CTL, PRESET_AGC_FORMATTER, 1); | 703 | ret = send_control_msg(pdev, |
704 | SET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf)); | ||
663 | } | 705 | } |
664 | if (ret < 0) | 706 | if (ret < 0) |
665 | return ret; | 707 | return ret; |
@@ -671,12 +713,14 @@ int pwc_get_agc(struct pwc_device *pdev, int *value) | |||
671 | unsigned char buf; | 713 | unsigned char buf; |
672 | int ret; | 714 | int ret; |
673 | 715 | ||
674 | ret = RecvControlMsg(GET_LUM_CTL, AGC_MODE_FORMATTER, 1); | 716 | ret = recv_control_msg(pdev, |
717 | GET_LUM_CTL, AGC_MODE_FORMATTER, &buf, sizeof(buf)); | ||
675 | if (ret < 0) | 718 | if (ret < 0) |
676 | return ret; | 719 | return ret; |
677 | 720 | ||
678 | if (buf != 0) { /* fixed */ | 721 | if (buf != 0) { /* fixed */ |
679 | ret = RecvControlMsg(GET_LUM_CTL, PRESET_AGC_FORMATTER, 1); | 722 | ret = recv_control_msg(pdev, |
723 | GET_LUM_CTL, PRESET_AGC_FORMATTER, &buf, sizeof(buf)); | ||
680 | if (ret < 0) | 724 | if (ret < 0) |
681 | return ret; | 725 | return ret; |
682 | if (buf > 0x3F) | 726 | if (buf > 0x3F) |
@@ -684,7 +728,8 @@ int pwc_get_agc(struct pwc_device *pdev, int *value) | |||
684 | *value = (buf << 10); | 728 | *value = (buf << 10); |
685 | } | 729 | } |
686 | else { /* auto */ | 730 | else { /* auto */ |
687 | ret = RecvControlMsg(GET_STATUS_CTL, READ_AGC_FORMATTER, 1); | 731 | ret = recv_control_msg(pdev, |
732 | GET_STATUS_CTL, READ_AGC_FORMATTER, &buf, sizeof(buf)); | ||
688 | if (ret < 0) | 733 | if (ret < 0) |
689 | return ret; | 734 | return ret; |
690 | /* Gah... this value ranges from 0x00 ... 0x9F */ | 735 | /* Gah... this value ranges from 0x00 ... 0x9F */ |
@@ -707,7 +752,8 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) | |||
707 | else | 752 | else |
708 | buf[0] = 0xff; /* fixed */ | 753 | buf[0] = 0xff; /* fixed */ |
709 | 754 | ||
710 | ret = SendControlMsg(SET_LUM_CTL, SHUTTER_MODE_FORMATTER, 1); | 755 | ret = send_control_msg(pdev, |
756 | SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf)); | ||
711 | 757 | ||
712 | if (!mode && ret >= 0) { | 758 | if (!mode && ret >= 0) { |
713 | if (value < 0) | 759 | if (value < 0) |
@@ -726,7 +772,9 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) | |||
726 | buf[0] = value >> 8; | 772 | buf[0] = value >> 8; |
727 | } | 773 | } |
728 | 774 | ||
729 | ret = SendControlMsg(SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, 2); | 775 | ret = send_control_msg(pdev, |
776 | SET_LUM_CTL, PRESET_SHUTTER_FORMATTER, | ||
777 | &buf, sizeof(buf)); | ||
730 | } | 778 | } |
731 | return ret; | 779 | return ret; |
732 | } | 780 | } |
@@ -737,7 +785,8 @@ int pwc_get_shutter_speed(struct pwc_device *pdev, int *value) | |||
737 | unsigned char buf[2]; | 785 | unsigned char buf[2]; |
738 | int ret; | 786 | int ret; |
739 | 787 | ||
740 | ret = RecvControlMsg(GET_STATUS_CTL, READ_SHUTTER_FORMATTER, 2); | 788 | ret = recv_control_msg(pdev, |
789 | GET_STATUS_CTL, READ_SHUTTER_FORMATTER, &buf, sizeof(buf)); | ||
741 | if (ret < 0) | 790 | if (ret < 0) |
742 | return ret; | 791 | return ret; |
743 | *value = buf[0] + (buf[1] << 8); | 792 | *value = buf[0] + (buf[1] << 8); |
@@ -764,7 +813,9 @@ int pwc_camera_power(struct pwc_device *pdev, int power) | |||
764 | buf = 0x00; /* active */ | 813 | buf = 0x00; /* active */ |
765 | else | 814 | else |
766 | buf = 0xFF; /* power save */ | 815 | buf = 0xFF; /* power save */ |
767 | return SendControlMsg(SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, 1); | 816 | return send_control_msg(pdev, |
817 | SET_STATUS_CTL, SET_POWER_SAVE_MODE_FORMATTER, | ||
818 | &buf, sizeof(buf)); | ||
768 | } | 819 | } |
769 | 820 | ||
770 | 821 | ||
@@ -773,20 +824,20 @@ int pwc_camera_power(struct pwc_device *pdev, int power) | |||
773 | 824 | ||
774 | int pwc_restore_user(struct pwc_device *pdev) | 825 | int pwc_restore_user(struct pwc_device *pdev) |
775 | { | 826 | { |
776 | char buf; /* dummy */ | 827 | return send_control_msg(pdev, |
777 | return SendControlMsg(SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, 0); | 828 | SET_STATUS_CTL, RESTORE_USER_DEFAULTS_FORMATTER, NULL, 0); |
778 | } | 829 | } |
779 | 830 | ||
780 | int pwc_save_user(struct pwc_device *pdev) | 831 | int pwc_save_user(struct pwc_device *pdev) |
781 | { | 832 | { |
782 | char buf; /* dummy */ | 833 | return send_control_msg(pdev, |
783 | return SendControlMsg(SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, 0); | 834 | SET_STATUS_CTL, SAVE_USER_DEFAULTS_FORMATTER, NULL, 0); |
784 | } | 835 | } |
785 | 836 | ||
786 | int pwc_restore_factory(struct pwc_device *pdev) | 837 | int pwc_restore_factory(struct pwc_device *pdev) |
787 | { | 838 | { |
788 | char buf; /* dummy */ | 839 | return send_control_msg(pdev, |
789 | return SendControlMsg(SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, 0); | 840 | SET_STATUS_CTL, RESTORE_FACTORY_DEFAULTS_FORMATTER, NULL, 0); |
790 | } | 841 | } |
791 | 842 | ||
792 | /* ************************************************* */ | 843 | /* ************************************************* */ |
@@ -814,7 +865,8 @@ int pwc_set_awb(struct pwc_device *pdev, int mode) | |||
814 | 865 | ||
815 | buf = mode & 0x07; /* just the lowest three bits */ | 866 | buf = mode & 0x07; /* just the lowest three bits */ |
816 | 867 | ||
817 | ret = SendControlMsg(SET_CHROM_CTL, WB_MODE_FORMATTER, 1); | 868 | ret = send_control_msg(pdev, |
869 | SET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf)); | ||
818 | 870 | ||
819 | if (ret < 0) | 871 | if (ret < 0) |
820 | return ret; | 872 | return ret; |
@@ -826,7 +878,8 @@ int pwc_get_awb(struct pwc_device *pdev) | |||
826 | unsigned char buf; | 878 | unsigned char buf; |
827 | int ret; | 879 | int ret; |
828 | 880 | ||
829 | ret = RecvControlMsg(GET_CHROM_CTL, WB_MODE_FORMATTER, 1); | 881 | ret = recv_control_msg(pdev, |
882 | GET_CHROM_CTL, WB_MODE_FORMATTER, &buf, sizeof(buf)); | ||
830 | 883 | ||
831 | if (ret < 0) | 884 | if (ret < 0) |
832 | return ret; | 885 | return ret; |
@@ -843,7 +896,9 @@ int pwc_set_red_gain(struct pwc_device *pdev, int value) | |||
843 | value = 0xffff; | 896 | value = 0xffff; |
844 | /* only the msb is considered */ | 897 | /* only the msb is considered */ |
845 | buf = value >> 8; | 898 | buf = value >> 8; |
846 | return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); | 899 | return send_control_msg(pdev, |
900 | SET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, | ||
901 | &buf, sizeof(buf)); | ||
847 | } | 902 | } |
848 | 903 | ||
849 | int pwc_get_red_gain(struct pwc_device *pdev, int *value) | 904 | int pwc_get_red_gain(struct pwc_device *pdev, int *value) |
@@ -851,7 +906,9 @@ int pwc_get_red_gain(struct pwc_device *pdev, int *value) | |||
851 | unsigned char buf; | 906 | unsigned char buf; |
852 | int ret; | 907 | int ret; |
853 | 908 | ||
854 | ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, 1); | 909 | ret = recv_control_msg(pdev, |
910 | GET_CHROM_CTL, PRESET_MANUAL_RED_GAIN_FORMATTER, | ||
911 | &buf, sizeof(buf)); | ||
855 | if (ret < 0) | 912 | if (ret < 0) |
856 | return ret; | 913 | return ret; |
857 | *value = buf << 8; | 914 | *value = buf << 8; |
@@ -869,7 +926,9 @@ int pwc_set_blue_gain(struct pwc_device *pdev, int value) | |||
869 | value = 0xffff; | 926 | value = 0xffff; |
870 | /* only the msb is considered */ | 927 | /* only the msb is considered */ |
871 | buf = value >> 8; | 928 | buf = value >> 8; |
872 | return SendControlMsg(SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); | 929 | return send_control_msg(pdev, |
930 | SET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, | ||
931 | &buf, sizeof(buf)); | ||
873 | } | 932 | } |
874 | 933 | ||
875 | int pwc_get_blue_gain(struct pwc_device *pdev, int *value) | 934 | int pwc_get_blue_gain(struct pwc_device *pdev, int *value) |
@@ -877,7 +936,9 @@ int pwc_get_blue_gain(struct pwc_device *pdev, int *value) | |||
877 | unsigned char buf; | 936 | unsigned char buf; |
878 | int ret; | 937 | int ret; |
879 | 938 | ||
880 | ret = RecvControlMsg(GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, 1); | 939 | ret = recv_control_msg(pdev, |
940 | GET_CHROM_CTL, PRESET_MANUAL_BLUE_GAIN_FORMATTER, | ||
941 | &buf, sizeof(buf)); | ||
881 | if (ret < 0) | 942 | if (ret < 0) |
882 | return ret; | 943 | return ret; |
883 | *value = buf << 8; | 944 | *value = buf << 8; |
@@ -894,7 +955,8 @@ static int pwc_read_red_gain(struct pwc_device *pdev, int *value) | |||
894 | unsigned char buf; | 955 | unsigned char buf; |
895 | int ret; | 956 | int ret; |
896 | 957 | ||
897 | ret = RecvControlMsg(GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, 1); | 958 | ret = recv_control_msg(pdev, |
959 | GET_STATUS_CTL, READ_RED_GAIN_FORMATTER, &buf, sizeof(buf)); | ||
898 | if (ret < 0) | 960 | if (ret < 0) |
899 | return ret; | 961 | return ret; |
900 | *value = buf << 8; | 962 | *value = buf << 8; |
@@ -906,7 +968,8 @@ static int pwc_read_blue_gain(struct pwc_device *pdev, int *value) | |||
906 | unsigned char buf; | 968 | unsigned char buf; |
907 | int ret; | 969 | int ret; |
908 | 970 | ||
909 | ret = RecvControlMsg(GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, 1); | 971 | ret = recv_control_msg(pdev, |
972 | GET_STATUS_CTL, READ_BLUE_GAIN_FORMATTER, &buf, sizeof(buf)); | ||
910 | if (ret < 0) | 973 | if (ret < 0) |
911 | return ret; | 974 | return ret; |
912 | *value = buf << 8; | 975 | *value = buf << 8; |
@@ -920,7 +983,8 @@ static int pwc_set_wb_speed(struct pwc_device *pdev, int speed) | |||
920 | 983 | ||
921 | /* useful range is 0x01..0x20 */ | 984 | /* useful range is 0x01..0x20 */ |
922 | buf = speed / 0x7f0; | 985 | buf = speed / 0x7f0; |
923 | return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); | 986 | return send_control_msg(pdev, |
987 | SET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf)); | ||
924 | } | 988 | } |
925 | 989 | ||
926 | static int pwc_get_wb_speed(struct pwc_device *pdev, int *value) | 990 | static int pwc_get_wb_speed(struct pwc_device *pdev, int *value) |
@@ -928,7 +992,8 @@ static int pwc_get_wb_speed(struct pwc_device *pdev, int *value) | |||
928 | unsigned char buf; | 992 | unsigned char buf; |
929 | int ret; | 993 | int ret; |
930 | 994 | ||
931 | ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, 1); | 995 | ret = recv_control_msg(pdev, |
996 | GET_CHROM_CTL, AWB_CONTROL_SPEED_FORMATTER, &buf, sizeof(buf)); | ||
932 | if (ret < 0) | 997 | if (ret < 0) |
933 | return ret; | 998 | return ret; |
934 | *value = buf * 0x7f0; | 999 | *value = buf * 0x7f0; |
@@ -942,7 +1007,8 @@ static int pwc_set_wb_delay(struct pwc_device *pdev, int delay) | |||
942 | 1007 | ||
943 | /* useful range is 0x01..0x3F */ | 1008 | /* useful range is 0x01..0x3F */ |
944 | buf = (delay >> 10); | 1009 | buf = (delay >> 10); |
945 | return SendControlMsg(SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); | 1010 | return send_control_msg(pdev, |
1011 | SET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf)); | ||
946 | } | 1012 | } |
947 | 1013 | ||
948 | static int pwc_get_wb_delay(struct pwc_device *pdev, int *value) | 1014 | static int pwc_get_wb_delay(struct pwc_device *pdev, int *value) |
@@ -950,7 +1016,8 @@ static int pwc_get_wb_delay(struct pwc_device *pdev, int *value) | |||
950 | unsigned char buf; | 1016 | unsigned char buf; |
951 | int ret; | 1017 | int ret; |
952 | 1018 | ||
953 | ret = RecvControlMsg(GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, 1); | 1019 | ret = recv_control_msg(pdev, |
1020 | GET_CHROM_CTL, AWB_CONTROL_DELAY_FORMATTER, &buf, sizeof(buf)); | ||
954 | if (ret < 0) | 1021 | if (ret < 0) |
955 | return ret; | 1022 | return ret; |
956 | *value = buf << 10; | 1023 | *value = buf << 10; |
@@ -978,7 +1045,8 @@ int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value) | |||
978 | buf[0] = on_value; | 1045 | buf[0] = on_value; |
979 | buf[1] = off_value; | 1046 | buf[1] = off_value; |
980 | 1047 | ||
981 | return SendControlMsg(SET_STATUS_CTL, LED_FORMATTER, 2); | 1048 | return send_control_msg(pdev, |
1049 | SET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf)); | ||
982 | } | 1050 | } |
983 | 1051 | ||
984 | static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) | 1052 | static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) |
@@ -992,7 +1060,8 @@ static int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value) | |||
992 | return 0; | 1060 | return 0; |
993 | } | 1061 | } |
994 | 1062 | ||
995 | ret = RecvControlMsg(GET_STATUS_CTL, LED_FORMATTER, 2); | 1063 | ret = recv_control_msg(pdev, |
1064 | GET_STATUS_CTL, LED_FORMATTER, &buf, sizeof(buf)); | ||
996 | if (ret < 0) | 1065 | if (ret < 0) |
997 | return ret; | 1066 | return ret; |
998 | *on_value = buf[0] * 100; | 1067 | *on_value = buf[0] * 100; |
@@ -1009,7 +1078,8 @@ int pwc_set_contour(struct pwc_device *pdev, int contour) | |||
1009 | buf = 0xff; /* auto contour on */ | 1078 | buf = 0xff; /* auto contour on */ |
1010 | else | 1079 | else |
1011 | buf = 0x0; /* auto contour off */ | 1080 | buf = 0x0; /* auto contour off */ |
1012 | ret = SendControlMsg(SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1); | 1081 | ret = send_control_msg(pdev, |
1082 | SET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf)); | ||
1013 | if (ret < 0) | 1083 | if (ret < 0) |
1014 | return ret; | 1084 | return ret; |
1015 | 1085 | ||
@@ -1019,7 +1089,8 @@ int pwc_set_contour(struct pwc_device *pdev, int contour) | |||
1019 | contour = 0xffff; | 1089 | contour = 0xffff; |
1020 | 1090 | ||
1021 | buf = (contour >> 10); /* contour preset is [0..3f] */ | 1091 | buf = (contour >> 10); /* contour preset is [0..3f] */ |
1022 | ret = SendControlMsg(SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1); | 1092 | ret = send_control_msg(pdev, |
1093 | SET_LUM_CTL, PRESET_CONTOUR_FORMATTER, &buf, sizeof(buf)); | ||
1023 | if (ret < 0) | 1094 | if (ret < 0) |
1024 | return ret; | 1095 | return ret; |
1025 | return 0; | 1096 | return 0; |
@@ -1030,13 +1101,16 @@ int pwc_get_contour(struct pwc_device *pdev, int *contour) | |||
1030 | unsigned char buf; | 1101 | unsigned char buf; |
1031 | int ret; | 1102 | int ret; |
1032 | 1103 | ||
1033 | ret = RecvControlMsg(GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, 1); | 1104 | ret = recv_control_msg(pdev, |
1105 | GET_LUM_CTL, AUTO_CONTOUR_FORMATTER, &buf, sizeof(buf)); | ||
1034 | if (ret < 0) | 1106 | if (ret < 0) |
1035 | return ret; | 1107 | return ret; |
1036 | 1108 | ||
1037 | if (buf == 0) { | 1109 | if (buf == 0) { |
1038 | /* auto mode off, query current preset value */ | 1110 | /* auto mode off, query current preset value */ |
1039 | ret = RecvControlMsg(GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, 1); | 1111 | ret = recv_control_msg(pdev, |
1112 | GET_LUM_CTL, PRESET_CONTOUR_FORMATTER, | ||
1113 | &buf, sizeof(buf)); | ||
1040 | if (ret < 0) | 1114 | if (ret < 0) |
1041 | return ret; | 1115 | return ret; |
1042 | *contour = buf << 10; | 1116 | *contour = buf << 10; |
@@ -1055,7 +1129,9 @@ int pwc_set_backlight(struct pwc_device *pdev, int backlight) | |||
1055 | buf = 0xff; | 1129 | buf = 0xff; |
1056 | else | 1130 | else |
1057 | buf = 0x0; | 1131 | buf = 0x0; |
1058 | return SendControlMsg(SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); | 1132 | return send_control_msg(pdev, |
1133 | SET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, | ||
1134 | &buf, sizeof(buf)); | ||
1059 | } | 1135 | } |
1060 | 1136 | ||
1061 | int pwc_get_backlight(struct pwc_device *pdev, int *backlight) | 1137 | int pwc_get_backlight(struct pwc_device *pdev, int *backlight) |
@@ -1063,7 +1139,9 @@ int pwc_get_backlight(struct pwc_device *pdev, int *backlight) | |||
1063 | int ret; | 1139 | int ret; |
1064 | unsigned char buf; | 1140 | unsigned char buf; |
1065 | 1141 | ||
1066 | ret = RecvControlMsg(GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, 1); | 1142 | ret = recv_control_msg(pdev, |
1143 | GET_LUM_CTL, BACK_LIGHT_COMPENSATION_FORMATTER, | ||
1144 | &buf, sizeof(buf)); | ||
1067 | if (ret < 0) | 1145 | if (ret < 0) |
1068 | return ret; | 1146 | return ret; |
1069 | *backlight = !!buf; | 1147 | *backlight = !!buf; |
@@ -1078,7 +1156,8 @@ int pwc_set_colour_mode(struct pwc_device *pdev, int colour) | |||
1078 | buf = 0xff; | 1156 | buf = 0xff; |
1079 | else | 1157 | else |
1080 | buf = 0x0; | 1158 | buf = 0x0; |
1081 | return SendControlMsg(SET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1); | 1159 | return send_control_msg(pdev, |
1160 | SET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf)); | ||
1082 | } | 1161 | } |
1083 | 1162 | ||
1084 | int pwc_get_colour_mode(struct pwc_device *pdev, int *colour) | 1163 | int pwc_get_colour_mode(struct pwc_device *pdev, int *colour) |
@@ -1086,7 +1165,8 @@ int pwc_get_colour_mode(struct pwc_device *pdev, int *colour) | |||
1086 | int ret; | 1165 | int ret; |
1087 | unsigned char buf; | 1166 | unsigned char buf; |
1088 | 1167 | ||
1089 | ret = RecvControlMsg(GET_CHROM_CTL, COLOUR_MODE_FORMATTER, 1); | 1168 | ret = recv_control_msg(pdev, |
1169 | GET_CHROM_CTL, COLOUR_MODE_FORMATTER, &buf, sizeof(buf)); | ||
1090 | if (ret < 0) | 1170 | if (ret < 0) |
1091 | return ret; | 1171 | return ret; |
1092 | *colour = !!buf; | 1172 | *colour = !!buf; |
@@ -1102,7 +1182,8 @@ int pwc_set_flicker(struct pwc_device *pdev, int flicker) | |||
1102 | buf = 0xff; | 1182 | buf = 0xff; |
1103 | else | 1183 | else |
1104 | buf = 0x0; | 1184 | buf = 0x0; |
1105 | return SendControlMsg(SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); | 1185 | return send_control_msg(pdev, |
1186 | SET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf)); | ||
1106 | } | 1187 | } |
1107 | 1188 | ||
1108 | int pwc_get_flicker(struct pwc_device *pdev, int *flicker) | 1189 | int pwc_get_flicker(struct pwc_device *pdev, int *flicker) |
@@ -1110,7 +1191,8 @@ int pwc_get_flicker(struct pwc_device *pdev, int *flicker) | |||
1110 | int ret; | 1191 | int ret; |
1111 | unsigned char buf; | 1192 | unsigned char buf; |
1112 | 1193 | ||
1113 | ret = RecvControlMsg(GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, 1); | 1194 | ret = recv_control_msg(pdev, |
1195 | GET_LUM_CTL, FLICKERLESS_MODE_FORMATTER, &buf, sizeof(buf)); | ||
1114 | if (ret < 0) | 1196 | if (ret < 0) |
1115 | return ret; | 1197 | return ret; |
1116 | *flicker = !!buf; | 1198 | *flicker = !!buf; |
@@ -1126,7 +1208,9 @@ int pwc_set_dynamic_noise(struct pwc_device *pdev, int noise) | |||
1126 | if (noise > 3) | 1208 | if (noise > 3) |
1127 | noise = 3; | 1209 | noise = 3; |
1128 | buf = noise; | 1210 | buf = noise; |
1129 | return SendControlMsg(SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); | 1211 | return send_control_msg(pdev, |
1212 | SET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, | ||
1213 | &buf, sizeof(buf)); | ||
1130 | } | 1214 | } |
1131 | 1215 | ||
1132 | int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) | 1216 | int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) |
@@ -1134,7 +1218,9 @@ int pwc_get_dynamic_noise(struct pwc_device *pdev, int *noise) | |||
1134 | int ret; | 1218 | int ret; |
1135 | unsigned char buf; | 1219 | unsigned char buf; |
1136 | 1220 | ||
1137 | ret = RecvControlMsg(GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, 1); | 1221 | ret = recv_control_msg(pdev, |
1222 | GET_LUM_CTL, DYNAMIC_NOISE_CONTROL_FORMATTER, | ||
1223 | &buf, sizeof(buf)); | ||
1138 | if (ret < 0) | 1224 | if (ret < 0) |
1139 | return ret; | 1225 | return ret; |
1140 | *noise = buf; | 1226 | *noise = buf; |
@@ -1146,7 +1232,8 @@ static int _pwc_mpt_reset(struct pwc_device *pdev, int flags) | |||
1146 | unsigned char buf; | 1232 | unsigned char buf; |
1147 | 1233 | ||
1148 | buf = flags & 0x03; // only lower two bits are currently used | 1234 | buf = flags & 0x03; // only lower two bits are currently used |
1149 | return SendControlMsg(SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, 1); | 1235 | return send_control_msg(pdev, |
1236 | SET_MPT_CTL, PT_RESET_CONTROL_FORMATTER, &buf, sizeof(buf)); | ||
1150 | } | 1237 | } |
1151 | 1238 | ||
1152 | int pwc_mpt_reset(struct pwc_device *pdev, int flags) | 1239 | int pwc_mpt_reset(struct pwc_device *pdev, int flags) |
@@ -1175,7 +1262,8 @@ static int _pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) | |||
1175 | buf[1] = (pan >> 8) & 0xFF; | 1262 | buf[1] = (pan >> 8) & 0xFF; |
1176 | buf[2] = tilt & 0xFF; | 1263 | buf[2] = tilt & 0xFF; |
1177 | buf[3] = (tilt >> 8) & 0xFF; | 1264 | buf[3] = (tilt >> 8) & 0xFF; |
1178 | return SendControlMsg(SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, 4); | 1265 | return send_control_msg(pdev, |
1266 | SET_MPT_CTL, PT_RELATIVE_CONTROL_FORMATTER, &buf, sizeof(buf)); | ||
1179 | } | 1267 | } |
1180 | 1268 | ||
1181 | int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) | 1269 | int pwc_mpt_set_angle(struct pwc_device *pdev, int pan, int tilt) |
@@ -1211,7 +1299,8 @@ static int pwc_mpt_get_status(struct pwc_device *pdev, struct pwc_mpt_status *st | |||
1211 | int ret; | 1299 | int ret; |
1212 | unsigned char buf[5]; | 1300 | unsigned char buf[5]; |
1213 | 1301 | ||
1214 | ret = RecvControlMsg(GET_MPT_CTL, PT_STATUS_FORMATTER, 5); | 1302 | ret = recv_control_msg(pdev, |
1303 | GET_MPT_CTL, PT_STATUS_FORMATTER, &buf, sizeof(buf)); | ||
1215 | if (ret < 0) | 1304 | if (ret < 0) |
1216 | return ret; | 1305 | return ret; |
1217 | status->status = buf[0] & 0x7; // 3 bits are used for reporting | 1306 | status->status = buf[0] & 0x7; // 3 bits are used for reporting |
@@ -1233,7 +1322,8 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) | |||
1233 | else | 1322 | else |
1234 | request = SENSOR_TYPE_FORMATTER2; | 1323 | request = SENSOR_TYPE_FORMATTER2; |
1235 | 1324 | ||
1236 | ret = RecvControlMsg(GET_STATUS_CTL, request, 1); | 1325 | ret = recv_control_msg(pdev, |
1326 | GET_STATUS_CTL, request, &buf, sizeof(buf)); | ||
1237 | if (ret < 0) | 1327 | if (ret < 0) |
1238 | return ret; | 1328 | return ret; |
1239 | if (pdev->type < 675) | 1329 | if (pdev->type < 675) |
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index d0d126c69354..5d496a99e034 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -5934,7 +5934,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) | |||
5934 | 5934 | ||
5935 | /* Initalize the timer | 5935 | /* Initalize the timer |
5936 | */ | 5936 | */ |
5937 | init_timer(&pCfg->timer); | 5937 | init_timer_on_stack(&pCfg->timer); |
5938 | pCfg->timer.data = (unsigned long) ioc; | 5938 | pCfg->timer.data = (unsigned long) ioc; |
5939 | pCfg->timer.function = mpt_timer_expired; | 5939 | pCfg->timer.function = mpt_timer_expired; |
5940 | pCfg->wait_done = 0; | 5940 | pCfg->wait_done = 0; |
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index d184dfab9631..db39f4a52f53 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
@@ -278,7 +278,7 @@ static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr, | |||
278 | * We only use page mode writes; the alternative is sloooow. This routine | 278 | * We only use page mode writes; the alternative is sloooow. This routine |
279 | * writes at most one page. | 279 | * writes at most one page. |
280 | */ | 280 | */ |
281 | static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf, | 281 | static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf, |
282 | unsigned offset, size_t count) | 282 | unsigned offset, size_t count) |
283 | { | 283 | { |
284 | struct i2c_client *client; | 284 | struct i2c_client *client; |
@@ -347,8 +347,8 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf, | |||
347 | return -ETIMEDOUT; | 347 | return -ETIMEDOUT; |
348 | } | 348 | } |
349 | 349 | ||
350 | static ssize_t at24_write(struct at24_data *at24, | 350 | static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off, |
351 | char *buf, loff_t off, size_t count) | 351 | size_t count) |
352 | { | 352 | { |
353 | ssize_t retval = 0; | 353 | ssize_t retval = 0; |
354 | 354 | ||
@@ -406,7 +406,7 @@ static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf, | |||
406 | return at24_read(at24, buf, offset, count); | 406 | return at24_read(at24, buf, offset, count); |
407 | } | 407 | } |
408 | 408 | ||
409 | static ssize_t at24_macc_write(struct memory_accessor *macc, char *buf, | 409 | static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf, |
410 | off_t offset, size_t count) | 410 | off_t offset, size_t count) |
411 | { | 411 | { |
412 | struct at24_data *at24 = container_of(macc, struct at24_data, macc); | 412 | struct at24_data *at24 = container_of(macc, struct at24_data, macc); |
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 6bc0dac5c1e8..b34cb5f79eea 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c | |||
@@ -140,7 +140,8 @@ at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
140 | 140 | ||
141 | 141 | ||
142 | static ssize_t | 142 | static ssize_t |
143 | at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count) | 143 | at25_ee_write(struct at25_data *at25, const char *buf, loff_t off, |
144 | size_t count) | ||
144 | { | 145 | { |
145 | ssize_t status = 0; | 146 | ssize_t status = 0; |
146 | unsigned written = 0; | 147 | unsigned written = 0; |
@@ -276,7 +277,7 @@ static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf, | |||
276 | return at25_ee_read(at25, buf, offset, count); | 277 | return at25_ee_read(at25, buf, offset, count); |
277 | } | 278 | } |
278 | 279 | ||
279 | static ssize_t at25_mem_write(struct memory_accessor *mem, char *buf, | 280 | static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf, |
280 | off_t offset, size_t count) | 281 | off_t offset, size_t count) |
281 | { | 282 | { |
282 | struct at25_data *at25 = container_of(mem, struct at25_data, mem); | 283 | struct at25_data *at25 = container_of(mem, struct at25_data, mem); |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index 3e6e42d2f01b..bbefe77c67a9 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
@@ -375,7 +375,7 @@ static int __init gru_init(void) | |||
375 | void *gru_start_vaddr; | 375 | void *gru_start_vaddr; |
376 | 376 | ||
377 | if (!is_uv_system()) | 377 | if (!is_uv_system()) |
378 | return -ENODEV; | 378 | return 0; |
379 | 379 | ||
380 | #if defined CONFIG_IA64 | 380 | #if defined CONFIG_IA64 |
381 | gru_start_paddr = 0xd000000000UL; /* ZZZZZZZZZZZZZZZZZZZ fixme */ | 381 | gru_start_paddr = 0xd000000000UL; /* ZZZZZZZZZZZZZZZZZZZ fixme */ |
diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c index 16f8dcab2da4..7896849b16dc 100644 --- a/drivers/misc/sgi-xp/xp_main.c +++ b/drivers/misc/sgi-xp/xp_main.c | |||
@@ -248,19 +248,19 @@ xp_init(void) | |||
248 | enum xp_retval ret; | 248 | enum xp_retval ret; |
249 | int ch_number; | 249 | int ch_number; |
250 | 250 | ||
251 | /* initialize the connection registration mutex */ | ||
252 | for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) | ||
253 | mutex_init(&xpc_registrations[ch_number].mutex); | ||
254 | |||
251 | if (is_shub()) | 255 | if (is_shub()) |
252 | ret = xp_init_sn2(); | 256 | ret = xp_init_sn2(); |
253 | else if (is_uv()) | 257 | else if (is_uv()) |
254 | ret = xp_init_uv(); | 258 | ret = xp_init_uv(); |
255 | else | 259 | else |
256 | ret = xpUnsupported; | 260 | ret = 0; |
257 | 261 | ||
258 | if (ret != xpSuccess) | 262 | if (ret != xpSuccess) |
259 | return -ENODEV; | 263 | return ret; |
260 | |||
261 | /* initialize the connection registration mutex */ | ||
262 | for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) | ||
263 | mutex_init(&xpc_registrations[ch_number].mutex); | ||
264 | 264 | ||
265 | return 0; | 265 | return 0; |
266 | } | 266 | } |
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h index 114444cfd496..b94d5f767703 100644 --- a/drivers/misc/sgi-xp/xpc.h +++ b/drivers/misc/sgi-xp/xpc.h | |||
@@ -90,18 +90,21 @@ struct xpc_rsvd_page { | |||
90 | short max_npartitions; /* value of XPC_MAX_PARTITIONS */ | 90 | short max_npartitions; /* value of XPC_MAX_PARTITIONS */ |
91 | u8 version; | 91 | u8 version; |
92 | u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */ | 92 | u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */ |
93 | unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */ | ||
93 | union { | 94 | union { |
94 | unsigned long vars_pa; /* phys address of struct xpc_vars */ | 95 | struct { |
95 | unsigned long activate_gru_mq_desc_gpa; /* phys addr of */ | 96 | unsigned long vars_pa; /* phys addr */ |
96 | /* activate mq's */ | 97 | } sn2; |
97 | /* gru mq descriptor */ | 98 | struct { |
99 | unsigned long heartbeat_gpa; /* phys addr */ | ||
100 | unsigned long activate_gru_mq_desc_gpa; /* phys addr */ | ||
101 | } uv; | ||
98 | } sn; | 102 | } sn; |
99 | unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */ | 103 | u64 pad2[9]; /* align to last u64 in 2nd 64-byte cacheline */ |
100 | u64 pad2[10]; /* align to last u64 in 2nd 64-byte cacheline */ | ||
101 | u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */ | 104 | u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */ |
102 | }; | 105 | }; |
103 | 106 | ||
104 | #define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */ | 107 | #define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */ |
105 | 108 | ||
106 | /* | 109 | /* |
107 | * Define the structures by which XPC variables can be exported to other | 110 | * Define the structures by which XPC variables can be exported to other |
@@ -182,6 +185,17 @@ struct xpc_vars_part_sn2 { | |||
182 | (XPC_RP_MACH_NASIDS(_rp) + \ | 185 | (XPC_RP_MACH_NASIDS(_rp) + \ |
183 | xpc_nasid_mask_nlongs)) | 186 | xpc_nasid_mask_nlongs)) |
184 | 187 | ||
188 | |||
189 | /* | ||
190 | * The following structure describes the partition's heartbeat info which | ||
191 | * will be periodically read by other partitions to determine whether this | ||
192 | * XPC is still 'alive'. | ||
193 | */ | ||
194 | struct xpc_heartbeat_uv { | ||
195 | unsigned long value; | ||
196 | unsigned long offline; /* if 0, heartbeat should be changing */ | ||
197 | }; | ||
198 | |||
185 | /* | 199 | /* |
186 | * Info pertinent to a GRU message queue using a watch list for irq generation. | 200 | * Info pertinent to a GRU message queue using a watch list for irq generation. |
187 | */ | 201 | */ |
@@ -198,7 +212,7 @@ struct xpc_gru_mq_uv { | |||
198 | 212 | ||
199 | /* | 213 | /* |
200 | * The activate_mq is used to send/receive GRU messages that affect XPC's | 214 | * The activate_mq is used to send/receive GRU messages that affect XPC's |
201 | * heartbeat, partition active state, and channel state. This is UV only. | 215 | * partition active state and channel state. This is uv only. |
202 | */ | 216 | */ |
203 | struct xpc_activate_mq_msghdr_uv { | 217 | struct xpc_activate_mq_msghdr_uv { |
204 | unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */ | 218 | unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */ |
@@ -210,33 +224,27 @@ struct xpc_activate_mq_msghdr_uv { | |||
210 | 224 | ||
211 | /* activate_mq defined message types */ | 225 | /* activate_mq defined message types */ |
212 | #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0 | 226 | #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0 |
213 | #define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV 1 | ||
214 | #define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV 2 | ||
215 | #define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV 3 | ||
216 | 227 | ||
217 | #define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 4 | 228 | #define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 1 |
218 | #define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 5 | 229 | #define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 2 |
219 | 230 | ||
220 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 6 | 231 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 3 |
221 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 7 | 232 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 4 |
222 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 8 | 233 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 5 |
223 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 9 | 234 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 6 |
235 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV 7 | ||
224 | 236 | ||
225 | #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 10 | 237 | #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 8 |
226 | #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 11 | 238 | #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 9 |
227 | 239 | ||
228 | struct xpc_activate_mq_msg_uv { | 240 | struct xpc_activate_mq_msg_uv { |
229 | struct xpc_activate_mq_msghdr_uv hdr; | 241 | struct xpc_activate_mq_msghdr_uv hdr; |
230 | }; | 242 | }; |
231 | 243 | ||
232 | struct xpc_activate_mq_msg_heartbeat_req_uv { | ||
233 | struct xpc_activate_mq_msghdr_uv hdr; | ||
234 | u64 heartbeat; | ||
235 | }; | ||
236 | |||
237 | struct xpc_activate_mq_msg_activate_req_uv { | 244 | struct xpc_activate_mq_msg_activate_req_uv { |
238 | struct xpc_activate_mq_msghdr_uv hdr; | 245 | struct xpc_activate_mq_msghdr_uv hdr; |
239 | unsigned long rp_gpa; | 246 | unsigned long rp_gpa; |
247 | unsigned long heartbeat_gpa; | ||
240 | unsigned long activate_gru_mq_desc_gpa; | 248 | unsigned long activate_gru_mq_desc_gpa; |
241 | }; | 249 | }; |
242 | 250 | ||
@@ -271,6 +279,11 @@ struct xpc_activate_mq_msg_chctl_openreply_uv { | |||
271 | unsigned long notify_gru_mq_desc_gpa; | 279 | unsigned long notify_gru_mq_desc_gpa; |
272 | }; | 280 | }; |
273 | 281 | ||
282 | struct xpc_activate_mq_msg_chctl_opencomplete_uv { | ||
283 | struct xpc_activate_mq_msghdr_uv hdr; | ||
284 | short ch_number; | ||
285 | }; | ||
286 | |||
274 | /* | 287 | /* |
275 | * Functions registered by add_timer() or called by kernel_thread() only | 288 | * Functions registered by add_timer() or called by kernel_thread() only |
276 | * allow for a single 64-bit argument. The following macros can be used to | 289 | * allow for a single 64-bit argument. The following macros can be used to |
@@ -576,30 +589,32 @@ struct xpc_channel { | |||
576 | 589 | ||
577 | #define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */ | 590 | #define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */ |
578 | 591 | ||
579 | #define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */ | 592 | #define XPC_C_ROPENCOMPLETE 0x00000002 /* remote open channel complete */ |
580 | #define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */ | 593 | #define XPC_C_OPENCOMPLETE 0x00000004 /* local open channel complete */ |
581 | #define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */ | 594 | #define XPC_C_ROPENREPLY 0x00000008 /* remote open channel reply */ |
582 | #define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */ | 595 | #define XPC_C_OPENREPLY 0x00000010 /* local open channel reply */ |
596 | #define XPC_C_ROPENREQUEST 0x00000020 /* remote open channel request */ | ||
597 | #define XPC_C_OPENREQUEST 0x00000040 /* local open channel request */ | ||
583 | 598 | ||
584 | #define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */ | 599 | #define XPC_C_SETUP 0x00000080 /* channel's msgqueues are alloc'd */ |
585 | #define XPC_C_CONNECTEDCALLOUT 0x00000040 /* connected callout initiated */ | 600 | #define XPC_C_CONNECTEDCALLOUT 0x00000100 /* connected callout initiated */ |
586 | #define XPC_C_CONNECTEDCALLOUT_MADE \ | 601 | #define XPC_C_CONNECTEDCALLOUT_MADE \ |
587 | 0x00000080 /* connected callout completed */ | 602 | 0x00000200 /* connected callout completed */ |
588 | #define XPC_C_CONNECTED 0x00000100 /* local channel is connected */ | 603 | #define XPC_C_CONNECTED 0x00000400 /* local channel is connected */ |
589 | #define XPC_C_CONNECTING 0x00000200 /* channel is being connected */ | 604 | #define XPC_C_CONNECTING 0x00000800 /* channel is being connected */ |
590 | 605 | ||
591 | #define XPC_C_RCLOSEREPLY 0x00000400 /* remote close channel reply */ | 606 | #define XPC_C_RCLOSEREPLY 0x00001000 /* remote close channel reply */ |
592 | #define XPC_C_CLOSEREPLY 0x00000800 /* local close channel reply */ | 607 | #define XPC_C_CLOSEREPLY 0x00002000 /* local close channel reply */ |
593 | #define XPC_C_RCLOSEREQUEST 0x00001000 /* remote close channel request */ | 608 | #define XPC_C_RCLOSEREQUEST 0x00004000 /* remote close channel request */ |
594 | #define XPC_C_CLOSEREQUEST 0x00002000 /* local close channel request */ | 609 | #define XPC_C_CLOSEREQUEST 0x00008000 /* local close channel request */ |
595 | 610 | ||
596 | #define XPC_C_DISCONNECTED 0x00004000 /* channel is disconnected */ | 611 | #define XPC_C_DISCONNECTED 0x00010000 /* channel is disconnected */ |
597 | #define XPC_C_DISCONNECTING 0x00008000 /* channel is being disconnected */ | 612 | #define XPC_C_DISCONNECTING 0x00020000 /* channel is being disconnected */ |
598 | #define XPC_C_DISCONNECTINGCALLOUT \ | 613 | #define XPC_C_DISCONNECTINGCALLOUT \ |
599 | 0x00010000 /* disconnecting callout initiated */ | 614 | 0x00040000 /* disconnecting callout initiated */ |
600 | #define XPC_C_DISCONNECTINGCALLOUT_MADE \ | 615 | #define XPC_C_DISCONNECTINGCALLOUT_MADE \ |
601 | 0x00020000 /* disconnecting callout completed */ | 616 | 0x00080000 /* disconnecting callout completed */ |
602 | #define XPC_C_WDISCONNECT 0x00040000 /* waiting for channel disconnect */ | 617 | #define XPC_C_WDISCONNECT 0x00100000 /* waiting for channel disconnect */ |
603 | 618 | ||
604 | /* | 619 | /* |
605 | * The channel control flags (chctl) union consists of a 64-bit variable which | 620 | * The channel control flags (chctl) union consists of a 64-bit variable which |
@@ -618,11 +633,13 @@ union xpc_channel_ctl_flags { | |||
618 | #define XPC_CHCTL_CLOSEREPLY 0x02 | 633 | #define XPC_CHCTL_CLOSEREPLY 0x02 |
619 | #define XPC_CHCTL_OPENREQUEST 0x04 | 634 | #define XPC_CHCTL_OPENREQUEST 0x04 |
620 | #define XPC_CHCTL_OPENREPLY 0x08 | 635 | #define XPC_CHCTL_OPENREPLY 0x08 |
621 | #define XPC_CHCTL_MSGREQUEST 0x10 | 636 | #define XPC_CHCTL_OPENCOMPLETE 0x10 |
637 | #define XPC_CHCTL_MSGREQUEST 0x20 | ||
622 | 638 | ||
623 | #define XPC_OPENCLOSE_CHCTL_FLAGS \ | 639 | #define XPC_OPENCLOSE_CHCTL_FLAGS \ |
624 | (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \ | 640 | (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \ |
625 | XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY) | 641 | XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \ |
642 | XPC_CHCTL_OPENCOMPLETE) | ||
626 | #define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST | 643 | #define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST |
627 | 644 | ||
628 | static inline int | 645 | static inline int |
@@ -687,6 +704,9 @@ struct xpc_partition_sn2 { | |||
687 | }; | 704 | }; |
688 | 705 | ||
689 | struct xpc_partition_uv { | 706 | struct xpc_partition_uv { |
707 | unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */ | ||
708 | struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */ | ||
709 | /* partition's heartbeat */ | ||
690 | unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */ | 710 | unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */ |
691 | /* activate mq's gru mq */ | 711 | /* activate mq's gru mq */ |
692 | /* descriptor */ | 712 | /* descriptor */ |
@@ -698,14 +718,12 @@ struct xpc_partition_uv { | |||
698 | u8 remote_act_state; /* remote partition's act_state */ | 718 | u8 remote_act_state; /* remote partition's act_state */ |
699 | u8 act_state_req; /* act_state request from remote partition */ | 719 | u8 act_state_req; /* act_state request from remote partition */ |
700 | enum xp_retval reason; /* reason for deactivate act_state request */ | 720 | enum xp_retval reason; /* reason for deactivate act_state request */ |
701 | u64 heartbeat; /* incremented by remote partition */ | ||
702 | }; | 721 | }; |
703 | 722 | ||
704 | /* struct xpc_partition_uv flags */ | 723 | /* struct xpc_partition_uv flags */ |
705 | 724 | ||
706 | #define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001 | 725 | #define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000001 |
707 | #define XPC_P_ENGAGED_UV 0x00000002 | 726 | #define XPC_P_ENGAGED_UV 0x00000002 |
708 | #define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000004 | ||
709 | 727 | ||
710 | /* struct xpc_partition_uv act_state change requests */ | 728 | /* struct xpc_partition_uv act_state change requests */ |
711 | 729 | ||
@@ -762,6 +780,62 @@ struct xpc_partition { | |||
762 | 780 | ||
763 | } ____cacheline_aligned; | 781 | } ____cacheline_aligned; |
764 | 782 | ||
783 | struct xpc_arch_operations { | ||
784 | int (*setup_partitions) (void); | ||
785 | void (*teardown_partitions) (void); | ||
786 | void (*process_activate_IRQ_rcvd) (void); | ||
787 | enum xp_retval (*get_partition_rsvd_page_pa) | ||
788 | (void *, u64 *, unsigned long *, size_t *); | ||
789 | int (*setup_rsvd_page) (struct xpc_rsvd_page *); | ||
790 | |||
791 | void (*allow_hb) (short); | ||
792 | void (*disallow_hb) (short); | ||
793 | void (*disallow_all_hbs) (void); | ||
794 | void (*increment_heartbeat) (void); | ||
795 | void (*offline_heartbeat) (void); | ||
796 | void (*online_heartbeat) (void); | ||
797 | void (*heartbeat_init) (void); | ||
798 | void (*heartbeat_exit) (void); | ||
799 | enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *); | ||
800 | |||
801 | void (*request_partition_activation) (struct xpc_rsvd_page *, | ||
802 | unsigned long, int); | ||
803 | void (*request_partition_reactivation) (struct xpc_partition *); | ||
804 | void (*request_partition_deactivation) (struct xpc_partition *); | ||
805 | void (*cancel_partition_deactivation_request) (struct xpc_partition *); | ||
806 | enum xp_retval (*setup_ch_structures) (struct xpc_partition *); | ||
807 | void (*teardown_ch_structures) (struct xpc_partition *); | ||
808 | |||
809 | enum xp_retval (*make_first_contact) (struct xpc_partition *); | ||
810 | |||
811 | u64 (*get_chctl_all_flags) (struct xpc_partition *); | ||
812 | void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *); | ||
813 | void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *); | ||
814 | void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *); | ||
815 | void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *); | ||
816 | void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *); | ||
817 | void (*process_msg_chctl_flags) (struct xpc_partition *, int); | ||
818 | |||
819 | enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *, | ||
820 | unsigned long); | ||
821 | |||
822 | enum xp_retval (*setup_msg_structures) (struct xpc_channel *); | ||
823 | void (*teardown_msg_structures) (struct xpc_channel *); | ||
824 | |||
825 | void (*indicate_partition_engaged) (struct xpc_partition *); | ||
826 | void (*indicate_partition_disengaged) (struct xpc_partition *); | ||
827 | void (*assume_partition_disengaged) (short); | ||
828 | int (*partition_engaged) (short); | ||
829 | int (*any_partition_engaged) (void); | ||
830 | |||
831 | int (*n_of_deliverable_payloads) (struct xpc_channel *); | ||
832 | enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *, | ||
833 | u16, u8, xpc_notify_func, void *); | ||
834 | void *(*get_deliverable_payload) (struct xpc_channel *); | ||
835 | void (*received_payload) (struct xpc_channel *, void *); | ||
836 | void (*notify_senders_of_disconnect) (struct xpc_channel *); | ||
837 | }; | ||
838 | |||
765 | /* struct xpc_partition act_state values (for XPC HB) */ | 839 | /* struct xpc_partition act_state values (for XPC HB) */ |
766 | 840 | ||
767 | #define XPC_P_AS_INACTIVE 0x00 /* partition is not active */ | 841 | #define XPC_P_AS_INACTIVE 0x00 /* partition is not active */ |
@@ -802,67 +876,17 @@ extern struct xpc_registration xpc_registrations[]; | |||
802 | /* found in xpc_main.c */ | 876 | /* found in xpc_main.c */ |
803 | extern struct device *xpc_part; | 877 | extern struct device *xpc_part; |
804 | extern struct device *xpc_chan; | 878 | extern struct device *xpc_chan; |
879 | extern struct xpc_arch_operations xpc_arch_ops; | ||
805 | extern int xpc_disengage_timelimit; | 880 | extern int xpc_disengage_timelimit; |
806 | extern int xpc_disengage_timedout; | 881 | extern int xpc_disengage_timedout; |
807 | extern int xpc_activate_IRQ_rcvd; | 882 | extern int xpc_activate_IRQ_rcvd; |
808 | extern spinlock_t xpc_activate_IRQ_rcvd_lock; | 883 | extern spinlock_t xpc_activate_IRQ_rcvd_lock; |
809 | extern wait_queue_head_t xpc_activate_IRQ_wq; | 884 | extern wait_queue_head_t xpc_activate_IRQ_wq; |
810 | extern void *xpc_heartbeating_to_mask; | ||
811 | extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **); | 885 | extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **); |
812 | extern void xpc_activate_partition(struct xpc_partition *); | 886 | extern void xpc_activate_partition(struct xpc_partition *); |
813 | extern void xpc_activate_kthreads(struct xpc_channel *, int); | 887 | extern void xpc_activate_kthreads(struct xpc_channel *, int); |
814 | extern void xpc_create_kthreads(struct xpc_channel *, int, int); | 888 | extern void xpc_create_kthreads(struct xpc_channel *, int, int); |
815 | extern void xpc_disconnect_wait(int); | 889 | extern void xpc_disconnect_wait(int); |
816 | extern int (*xpc_setup_partitions_sn) (void); | ||
817 | extern void (*xpc_teardown_partitions_sn) (void); | ||
818 | extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *, | ||
819 | unsigned long *, | ||
820 | size_t *); | ||
821 | extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *); | ||
822 | extern void (*xpc_heartbeat_init) (void); | ||
823 | extern void (*xpc_heartbeat_exit) (void); | ||
824 | extern void (*xpc_increment_heartbeat) (void); | ||
825 | extern void (*xpc_offline_heartbeat) (void); | ||
826 | extern void (*xpc_online_heartbeat) (void); | ||
827 | extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *); | ||
828 | extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *); | ||
829 | extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *); | ||
830 | extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *); | ||
831 | extern void (*xpc_teardown_msg_structures) (struct xpc_channel *); | ||
832 | extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *); | ||
833 | extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int); | ||
834 | extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *); | ||
835 | extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *); | ||
836 | extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *, | ||
837 | unsigned long, int); | ||
838 | extern void (*xpc_request_partition_reactivation) (struct xpc_partition *); | ||
839 | extern void (*xpc_request_partition_deactivation) (struct xpc_partition *); | ||
840 | extern void (*xpc_cancel_partition_deactivation_request) ( | ||
841 | struct xpc_partition *); | ||
842 | extern void (*xpc_process_activate_IRQ_rcvd) (void); | ||
843 | extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *); | ||
844 | extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *); | ||
845 | |||
846 | extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *); | ||
847 | extern int (*xpc_partition_engaged) (short); | ||
848 | extern int (*xpc_any_partition_engaged) (void); | ||
849 | extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *); | ||
850 | extern void (*xpc_assume_partition_disengaged) (short); | ||
851 | |||
852 | extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *, | ||
853 | unsigned long *); | ||
854 | extern void (*xpc_send_chctl_closereply) (struct xpc_channel *, | ||
855 | unsigned long *); | ||
856 | extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *, | ||
857 | unsigned long *); | ||
858 | extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *); | ||
859 | |||
860 | extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *, | ||
861 | unsigned long); | ||
862 | |||
863 | extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *, | ||
864 | u16, u8, xpc_notify_func, void *); | ||
865 | extern void (*xpc_received_payload) (struct xpc_channel *, void *); | ||
866 | 890 | ||
867 | /* found in xpc_sn2.c */ | 891 | /* found in xpc_sn2.c */ |
868 | extern int xpc_init_sn2(void); | 892 | extern int xpc_init_sn2(void); |
@@ -909,40 +933,6 @@ extern void xpc_disconnect_channel(const int, struct xpc_channel *, | |||
909 | extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval); | 933 | extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval); |
910 | extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval); | 934 | extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval); |
911 | 935 | ||
912 | static inline int | ||
913 | xpc_hb_allowed(short partid, void *heartbeating_to_mask) | ||
914 | { | ||
915 | return test_bit(partid, heartbeating_to_mask); | ||
916 | } | ||
917 | |||
918 | static inline int | ||
919 | xpc_any_hbs_allowed(void) | ||
920 | { | ||
921 | DBUG_ON(xpc_heartbeating_to_mask == NULL); | ||
922 | return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions); | ||
923 | } | ||
924 | |||
925 | static inline void | ||
926 | xpc_allow_hb(short partid) | ||
927 | { | ||
928 | DBUG_ON(xpc_heartbeating_to_mask == NULL); | ||
929 | set_bit(partid, xpc_heartbeating_to_mask); | ||
930 | } | ||
931 | |||
932 | static inline void | ||
933 | xpc_disallow_hb(short partid) | ||
934 | { | ||
935 | DBUG_ON(xpc_heartbeating_to_mask == NULL); | ||
936 | clear_bit(partid, xpc_heartbeating_to_mask); | ||
937 | } | ||
938 | |||
939 | static inline void | ||
940 | xpc_disallow_all_hbs(void) | ||
941 | { | ||
942 | DBUG_ON(xpc_heartbeating_to_mask == NULL); | ||
943 | bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions); | ||
944 | } | ||
945 | |||
946 | static inline void | 936 | static inline void |
947 | xpc_wakeup_channel_mgr(struct xpc_partition *part) | 937 | xpc_wakeup_channel_mgr(struct xpc_partition *part) |
948 | { | 938 | { |
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c index 99a2534c38a1..652593fc486d 100644 --- a/drivers/misc/sgi-xp/xpc_channel.c +++ b/drivers/misc/sgi-xp/xpc_channel.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* | 9 | /* |
@@ -39,34 +39,38 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
39 | 39 | ||
40 | if (!(ch->flags & XPC_C_SETUP)) { | 40 | if (!(ch->flags & XPC_C_SETUP)) { |
41 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | 41 | spin_unlock_irqrestore(&ch->lock, *irq_flags); |
42 | ret = xpc_setup_msg_structures(ch); | 42 | ret = xpc_arch_ops.setup_msg_structures(ch); |
43 | spin_lock_irqsave(&ch->lock, *irq_flags); | 43 | spin_lock_irqsave(&ch->lock, *irq_flags); |
44 | 44 | ||
45 | if (ret != xpSuccess) | 45 | if (ret != xpSuccess) |
46 | XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags); | 46 | XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags); |
47 | else | ||
48 | ch->flags |= XPC_C_SETUP; | ||
47 | 49 | ||
48 | ch->flags |= XPC_C_SETUP; | 50 | if (ch->flags & XPC_C_DISCONNECTING) |
49 | |||
50 | if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING)) | ||
51 | return; | 51 | return; |
52 | } | 52 | } |
53 | 53 | ||
54 | if (!(ch->flags & XPC_C_OPENREPLY)) { | 54 | if (!(ch->flags & XPC_C_OPENREPLY)) { |
55 | ch->flags |= XPC_C_OPENREPLY; | 55 | ch->flags |= XPC_C_OPENREPLY; |
56 | xpc_send_chctl_openreply(ch, irq_flags); | 56 | xpc_arch_ops.send_chctl_openreply(ch, irq_flags); |
57 | } | 57 | } |
58 | 58 | ||
59 | if (!(ch->flags & XPC_C_ROPENREPLY)) | 59 | if (!(ch->flags & XPC_C_ROPENREPLY)) |
60 | return; | 60 | return; |
61 | 61 | ||
62 | ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */ | 62 | if (!(ch->flags & XPC_C_OPENCOMPLETE)) { |
63 | ch->flags |= (XPC_C_OPENCOMPLETE | XPC_C_CONNECTED); | ||
64 | xpc_arch_ops.send_chctl_opencomplete(ch, irq_flags); | ||
65 | } | ||
66 | |||
67 | if (!(ch->flags & XPC_C_ROPENCOMPLETE)) | ||
68 | return; | ||
63 | 69 | ||
64 | dev_info(xpc_chan, "channel %d to partition %d connected\n", | 70 | dev_info(xpc_chan, "channel %d to partition %d connected\n", |
65 | ch->number, ch->partid); | 71 | ch->number, ch->partid); |
66 | 72 | ||
67 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | 73 | ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */ |
68 | xpc_create_kthreads(ch, 1, 0); | ||
69 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
70 | } | 74 | } |
71 | 75 | ||
72 | /* | 76 | /* |
@@ -96,7 +100,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
96 | 100 | ||
97 | if (part->act_state == XPC_P_AS_DEACTIVATING) { | 101 | if (part->act_state == XPC_P_AS_DEACTIVATING) { |
98 | /* can't proceed until the other side disengages from us */ | 102 | /* can't proceed until the other side disengages from us */ |
99 | if (xpc_partition_engaged(ch->partid)) | 103 | if (xpc_arch_ops.partition_engaged(ch->partid)) |
100 | return; | 104 | return; |
101 | 105 | ||
102 | } else { | 106 | } else { |
@@ -108,7 +112,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
108 | 112 | ||
109 | if (!(ch->flags & XPC_C_CLOSEREPLY)) { | 113 | if (!(ch->flags & XPC_C_CLOSEREPLY)) { |
110 | ch->flags |= XPC_C_CLOSEREPLY; | 114 | ch->flags |= XPC_C_CLOSEREPLY; |
111 | xpc_send_chctl_closereply(ch, irq_flags); | 115 | xpc_arch_ops.send_chctl_closereply(ch, irq_flags); |
112 | } | 116 | } |
113 | 117 | ||
114 | if (!(ch->flags & XPC_C_RCLOSEREPLY)) | 118 | if (!(ch->flags & XPC_C_RCLOSEREPLY)) |
@@ -118,7 +122,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
118 | /* wake those waiting for notify completion */ | 122 | /* wake those waiting for notify completion */ |
119 | if (atomic_read(&ch->n_to_notify) > 0) { | 123 | if (atomic_read(&ch->n_to_notify) > 0) { |
120 | /* we do callout while holding ch->lock, callout can't block */ | 124 | /* we do callout while holding ch->lock, callout can't block */ |
121 | xpc_notify_senders_of_disconnect(ch); | 125 | xpc_arch_ops.notify_senders_of_disconnect(ch); |
122 | } | 126 | } |
123 | 127 | ||
124 | /* both sides are disconnected now */ | 128 | /* both sides are disconnected now */ |
@@ -132,7 +136,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
132 | DBUG_ON(atomic_read(&ch->n_to_notify) != 0); | 136 | DBUG_ON(atomic_read(&ch->n_to_notify) != 0); |
133 | 137 | ||
134 | /* it's now safe to free the channel's message queues */ | 138 | /* it's now safe to free the channel's message queues */ |
135 | xpc_teardown_msg_structures(ch); | 139 | xpc_arch_ops.teardown_msg_structures(ch); |
136 | 140 | ||
137 | ch->func = NULL; | 141 | ch->func = NULL; |
138 | ch->key = NULL; | 142 | ch->key = NULL; |
@@ -144,8 +148,9 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
144 | 148 | ||
145 | /* | 149 | /* |
146 | * Mark the channel disconnected and clear all other flags, including | 150 | * Mark the channel disconnected and clear all other flags, including |
147 | * XPC_C_SETUP (because of call to xpc_teardown_msg_structures()) but | 151 | * XPC_C_SETUP (because of call to |
148 | * not including XPC_C_WDISCONNECT (if it was set). | 152 | * xpc_arch_ops.teardown_msg_structures()) but not including |
153 | * XPC_C_WDISCONNECT (if it was set). | ||
149 | */ | 154 | */ |
150 | ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT)); | 155 | ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT)); |
151 | 156 | ||
@@ -184,6 +189,7 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number, | |||
184 | struct xpc_channel *ch = &part->channels[ch_number]; | 189 | struct xpc_channel *ch = &part->channels[ch_number]; |
185 | enum xp_retval reason; | 190 | enum xp_retval reason; |
186 | enum xp_retval ret; | 191 | enum xp_retval ret; |
192 | int create_kthread = 0; | ||
187 | 193 | ||
188 | spin_lock_irqsave(&ch->lock, irq_flags); | 194 | spin_lock_irqsave(&ch->lock, irq_flags); |
189 | 195 | ||
@@ -196,8 +202,7 @@ again: | |||
196 | * has had a chance to see that the channel is disconnected. | 202 | * has had a chance to see that the channel is disconnected. |
197 | */ | 203 | */ |
198 | ch->delayed_chctl_flags |= chctl_flags; | 204 | ch->delayed_chctl_flags |= chctl_flags; |
199 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 205 | goto out; |
200 | return; | ||
201 | } | 206 | } |
202 | 207 | ||
203 | if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) { | 208 | if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) { |
@@ -239,8 +244,7 @@ again: | |||
239 | XPC_CHCTL_CLOSEREQUEST; | 244 | XPC_CHCTL_CLOSEREQUEST; |
240 | spin_unlock(&part->chctl_lock); | 245 | spin_unlock(&part->chctl_lock); |
241 | } | 246 | } |
242 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 247 | goto out; |
243 | return; | ||
244 | } | 248 | } |
245 | 249 | ||
246 | XPC_SET_REASON(ch, 0, 0); | 250 | XPC_SET_REASON(ch, 0, 0); |
@@ -250,7 +254,8 @@ again: | |||
250 | ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST); | 254 | ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST); |
251 | } | 255 | } |
252 | 256 | ||
253 | chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY); | 257 | chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | |
258 | XPC_CHCTL_OPENCOMPLETE); | ||
254 | 259 | ||
255 | /* | 260 | /* |
256 | * The meaningful CLOSEREQUEST connection state fields are: | 261 | * The meaningful CLOSEREQUEST connection state fields are: |
@@ -269,8 +274,7 @@ again: | |||
269 | XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); | 274 | XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); |
270 | 275 | ||
271 | DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY); | 276 | DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY); |
272 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 277 | goto out; |
273 | return; | ||
274 | } | 278 | } |
275 | 279 | ||
276 | xpc_process_disconnect(ch, &irq_flags); | 280 | xpc_process_disconnect(ch, &irq_flags); |
@@ -283,8 +287,7 @@ again: | |||
283 | 287 | ||
284 | if (ch->flags & XPC_C_DISCONNECTED) { | 288 | if (ch->flags & XPC_C_DISCONNECTED) { |
285 | DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING); | 289 | DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING); |
286 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 290 | goto out; |
287 | return; | ||
288 | } | 291 | } |
289 | 292 | ||
290 | DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); | 293 | DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); |
@@ -299,8 +302,7 @@ again: | |||
299 | XPC_CHCTL_CLOSEREPLY; | 302 | XPC_CHCTL_CLOSEREPLY; |
300 | spin_unlock(&part->chctl_lock); | 303 | spin_unlock(&part->chctl_lock); |
301 | } | 304 | } |
302 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 305 | goto out; |
303 | return; | ||
304 | } | 306 | } |
305 | 307 | ||
306 | ch->flags |= XPC_C_RCLOSEREPLY; | 308 | ch->flags |= XPC_C_RCLOSEREPLY; |
@@ -320,14 +322,12 @@ again: | |||
320 | 322 | ||
321 | if (part->act_state == XPC_P_AS_DEACTIVATING || | 323 | if (part->act_state == XPC_P_AS_DEACTIVATING || |
322 | (ch->flags & XPC_C_ROPENREQUEST)) { | 324 | (ch->flags & XPC_C_ROPENREQUEST)) { |
323 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 325 | goto out; |
324 | return; | ||
325 | } | 326 | } |
326 | 327 | ||
327 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) { | 328 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) { |
328 | ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST; | 329 | ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST; |
329 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 330 | goto out; |
330 | return; | ||
331 | } | 331 | } |
332 | DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED | | 332 | DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED | |
333 | XPC_C_OPENREQUEST))); | 333 | XPC_C_OPENREQUEST))); |
@@ -341,8 +341,7 @@ again: | |||
341 | */ | 341 | */ |
342 | if (args->entry_size == 0 || args->local_nentries == 0) { | 342 | if (args->entry_size == 0 || args->local_nentries == 0) { |
343 | /* assume OPENREQUEST was delayed by mistake */ | 343 | /* assume OPENREQUEST was delayed by mistake */ |
344 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 344 | goto out; |
345 | return; | ||
346 | } | 345 | } |
347 | 346 | ||
348 | ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING); | 347 | ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING); |
@@ -352,8 +351,7 @@ again: | |||
352 | if (args->entry_size != ch->entry_size) { | 351 | if (args->entry_size != ch->entry_size) { |
353 | XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes, | 352 | XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes, |
354 | &irq_flags); | 353 | &irq_flags); |
355 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 354 | goto out; |
356 | return; | ||
357 | } | 355 | } |
358 | } else { | 356 | } else { |
359 | ch->entry_size = args->entry_size; | 357 | ch->entry_size = args->entry_size; |
@@ -375,15 +373,13 @@ again: | |||
375 | args->local_msgqueue_pa, args->local_nentries, | 373 | args->local_msgqueue_pa, args->local_nentries, |
376 | args->remote_nentries, ch->partid, ch->number); | 374 | args->remote_nentries, ch->partid, ch->number); |
377 | 375 | ||
378 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) { | 376 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) |
379 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 377 | goto out; |
380 | return; | 378 | |
381 | } | ||
382 | if (!(ch->flags & XPC_C_OPENREQUEST)) { | 379 | if (!(ch->flags & XPC_C_OPENREQUEST)) { |
383 | XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError, | 380 | XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError, |
384 | &irq_flags); | 381 | &irq_flags); |
385 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 382 | goto out; |
386 | return; | ||
387 | } | 383 | } |
388 | 384 | ||
389 | DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST)); | 385 | DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST)); |
@@ -400,11 +396,11 @@ again: | |||
400 | DBUG_ON(args->local_nentries == 0); | 396 | DBUG_ON(args->local_nentries == 0); |
401 | DBUG_ON(args->remote_nentries == 0); | 397 | DBUG_ON(args->remote_nentries == 0); |
402 | 398 | ||
403 | ret = xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa); | 399 | ret = xpc_arch_ops.save_remote_msgqueue_pa(ch, |
400 | args->local_msgqueue_pa); | ||
404 | if (ret != xpSuccess) { | 401 | if (ret != xpSuccess) { |
405 | XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags); | 402 | XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags); |
406 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 403 | goto out; |
407 | return; | ||
408 | } | 404 | } |
409 | ch->flags |= XPC_C_ROPENREPLY; | 405 | ch->flags |= XPC_C_ROPENREPLY; |
410 | 406 | ||
@@ -430,7 +426,36 @@ again: | |||
430 | xpc_process_connect(ch, &irq_flags); | 426 | xpc_process_connect(ch, &irq_flags); |
431 | } | 427 | } |
432 | 428 | ||
429 | if (chctl_flags & XPC_CHCTL_OPENCOMPLETE) { | ||
430 | |||
431 | dev_dbg(xpc_chan, "XPC_CHCTL_OPENCOMPLETE received from " | ||
432 | "partid=%d, channel=%d\n", ch->partid, ch->number); | ||
433 | |||
434 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) | ||
435 | goto out; | ||
436 | |||
437 | if (!(ch->flags & XPC_C_OPENREQUEST) || | ||
438 | !(ch->flags & XPC_C_OPENREPLY)) { | ||
439 | XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError, | ||
440 | &irq_flags); | ||
441 | goto out; | ||
442 | } | ||
443 | |||
444 | DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST)); | ||
445 | DBUG_ON(!(ch->flags & XPC_C_ROPENREPLY)); | ||
446 | DBUG_ON(!(ch->flags & XPC_C_CONNECTED)); | ||
447 | |||
448 | ch->flags |= XPC_C_ROPENCOMPLETE; | ||
449 | |||
450 | xpc_process_connect(ch, &irq_flags); | ||
451 | create_kthread = 1; | ||
452 | } | ||
453 | |||
454 | out: | ||
433 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 455 | spin_unlock_irqrestore(&ch->lock, irq_flags); |
456 | |||
457 | if (create_kthread) | ||
458 | xpc_create_kthreads(ch, 1, 0); | ||
434 | } | 459 | } |
435 | 460 | ||
436 | /* | 461 | /* |
@@ -508,7 +533,7 @@ xpc_connect_channel(struct xpc_channel *ch) | |||
508 | /* initiate the connection */ | 533 | /* initiate the connection */ |
509 | 534 | ||
510 | ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING); | 535 | ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING); |
511 | xpc_send_chctl_openrequest(ch, &irq_flags); | 536 | xpc_arch_ops.send_chctl_openrequest(ch, &irq_flags); |
512 | 537 | ||
513 | xpc_process_connect(ch, &irq_flags); | 538 | xpc_process_connect(ch, &irq_flags); |
514 | 539 | ||
@@ -526,7 +551,7 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part) | |||
526 | int ch_number; | 551 | int ch_number; |
527 | u32 ch_flags; | 552 | u32 ch_flags; |
528 | 553 | ||
529 | chctl.all_flags = xpc_get_chctl_all_flags(part); | 554 | chctl.all_flags = xpc_arch_ops.get_chctl_all_flags(part); |
530 | 555 | ||
531 | /* | 556 | /* |
532 | * Initiate channel connections for registered channels. | 557 | * Initiate channel connections for registered channels. |
@@ -564,10 +589,6 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part) | |||
564 | if (!(ch_flags & XPC_C_OPENREQUEST)) { | 589 | if (!(ch_flags & XPC_C_OPENREQUEST)) { |
565 | DBUG_ON(ch_flags & XPC_C_SETUP); | 590 | DBUG_ON(ch_flags & XPC_C_SETUP); |
566 | (void)xpc_connect_channel(ch); | 591 | (void)xpc_connect_channel(ch); |
567 | } else { | ||
568 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
569 | xpc_process_connect(ch, &irq_flags); | ||
570 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
571 | } | 592 | } |
572 | continue; | 593 | continue; |
573 | } | 594 | } |
@@ -579,7 +600,7 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part) | |||
579 | */ | 600 | */ |
580 | 601 | ||
581 | if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS) | 602 | if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS) |
582 | xpc_process_msg_chctl_flags(part, ch_number); | 603 | xpc_arch_ops.process_msg_chctl_flags(part, ch_number); |
583 | } | 604 | } |
584 | } | 605 | } |
585 | 606 | ||
@@ -755,7 +776,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch, | |||
755 | XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY | | 776 | XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY | |
756 | XPC_C_CONNECTING | XPC_C_CONNECTED); | 777 | XPC_C_CONNECTING | XPC_C_CONNECTED); |
757 | 778 | ||
758 | xpc_send_chctl_closerequest(ch, irq_flags); | 779 | xpc_arch_ops.send_chctl_closerequest(ch, irq_flags); |
759 | 780 | ||
760 | if (channel_was_connected) | 781 | if (channel_was_connected) |
761 | ch->flags |= XPC_C_WASCONNECTED; | 782 | ch->flags |= XPC_C_WASCONNECTED; |
@@ -862,8 +883,8 @@ xpc_initiate_send(short partid, int ch_number, u32 flags, void *payload, | |||
862 | DBUG_ON(payload == NULL); | 883 | DBUG_ON(payload == NULL); |
863 | 884 | ||
864 | if (xpc_part_ref(part)) { | 885 | if (xpc_part_ref(part)) { |
865 | ret = xpc_send_payload(&part->channels[ch_number], flags, | 886 | ret = xpc_arch_ops.send_payload(&part->channels[ch_number], |
866 | payload, payload_size, 0, NULL, NULL); | 887 | flags, payload, payload_size, 0, NULL, NULL); |
867 | xpc_part_deref(part); | 888 | xpc_part_deref(part); |
868 | } | 889 | } |
869 | 890 | ||
@@ -914,9 +935,8 @@ xpc_initiate_send_notify(short partid, int ch_number, u32 flags, void *payload, | |||
914 | DBUG_ON(func == NULL); | 935 | DBUG_ON(func == NULL); |
915 | 936 | ||
916 | if (xpc_part_ref(part)) { | 937 | if (xpc_part_ref(part)) { |
917 | ret = xpc_send_payload(&part->channels[ch_number], flags, | 938 | ret = xpc_arch_ops.send_payload(&part->channels[ch_number], |
918 | payload, payload_size, XPC_N_CALL, func, | 939 | flags, payload, payload_size, XPC_N_CALL, func, key); |
919 | key); | ||
920 | xpc_part_deref(part); | 940 | xpc_part_deref(part); |
921 | } | 941 | } |
922 | return ret; | 942 | return ret; |
@@ -930,7 +950,7 @@ xpc_deliver_payload(struct xpc_channel *ch) | |||
930 | { | 950 | { |
931 | void *payload; | 951 | void *payload; |
932 | 952 | ||
933 | payload = xpc_get_deliverable_payload(ch); | 953 | payload = xpc_arch_ops.get_deliverable_payload(ch); |
934 | if (payload != NULL) { | 954 | if (payload != NULL) { |
935 | 955 | ||
936 | /* | 956 | /* |
@@ -984,7 +1004,7 @@ xpc_initiate_received(short partid, int ch_number, void *payload) | |||
984 | DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); | 1004 | DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); |
985 | 1005 | ||
986 | ch = &part->channels[ch_number]; | 1006 | ch = &part->channels[ch_number]; |
987 | xpc_received_payload(ch, payload); | 1007 | xpc_arch_ops.received_payload(ch, payload); |
988 | 1008 | ||
989 | /* the call to xpc_msgqueue_ref() was done by xpc_deliver_payload() */ | 1009 | /* the call to xpc_msgqueue_ref() was done by xpc_deliver_payload() */ |
990 | xpc_msgqueue_deref(ch); | 1010 | xpc_msgqueue_deref(ch); |
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index 1ab9fda87fab..fd3688a3e23f 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* | 9 | /* |
@@ -150,7 +150,6 @@ DECLARE_WAIT_QUEUE_HEAD(xpc_activate_IRQ_wq); | |||
150 | 150 | ||
151 | static unsigned long xpc_hb_check_timeout; | 151 | static unsigned long xpc_hb_check_timeout; |
152 | static struct timer_list xpc_hb_timer; | 152 | static struct timer_list xpc_hb_timer; |
153 | void *xpc_heartbeating_to_mask; | ||
154 | 153 | ||
155 | /* notification that the xpc_hb_checker thread has exited */ | 154 | /* notification that the xpc_hb_checker thread has exited */ |
156 | static DECLARE_COMPLETION(xpc_hb_checker_exited); | 155 | static DECLARE_COMPLETION(xpc_hb_checker_exited); |
@@ -170,62 +169,7 @@ static struct notifier_block xpc_die_notifier = { | |||
170 | .notifier_call = xpc_system_die, | 169 | .notifier_call = xpc_system_die, |
171 | }; | 170 | }; |
172 | 171 | ||
173 | int (*xpc_setup_partitions_sn) (void); | 172 | struct xpc_arch_operations xpc_arch_ops; |
174 | void (*xpc_teardown_partitions_sn) (void); | ||
175 | enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie, | ||
176 | unsigned long *rp_pa, | ||
177 | size_t *len); | ||
178 | int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *rp); | ||
179 | void (*xpc_heartbeat_init) (void); | ||
180 | void (*xpc_heartbeat_exit) (void); | ||
181 | void (*xpc_increment_heartbeat) (void); | ||
182 | void (*xpc_offline_heartbeat) (void); | ||
183 | void (*xpc_online_heartbeat) (void); | ||
184 | enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *part); | ||
185 | |||
186 | enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part); | ||
187 | void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *ch); | ||
188 | u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *part); | ||
189 | enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *ch); | ||
190 | void (*xpc_teardown_msg_structures) (struct xpc_channel *ch); | ||
191 | void (*xpc_process_msg_chctl_flags) (struct xpc_partition *part, int ch_number); | ||
192 | int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *ch); | ||
193 | void *(*xpc_get_deliverable_payload) (struct xpc_channel *ch); | ||
194 | |||
195 | void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp, | ||
196 | unsigned long remote_rp_pa, | ||
197 | int nasid); | ||
198 | void (*xpc_request_partition_reactivation) (struct xpc_partition *part); | ||
199 | void (*xpc_request_partition_deactivation) (struct xpc_partition *part); | ||
200 | void (*xpc_cancel_partition_deactivation_request) (struct xpc_partition *part); | ||
201 | |||
202 | void (*xpc_process_activate_IRQ_rcvd) (void); | ||
203 | enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *part); | ||
204 | void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *part); | ||
205 | |||
206 | void (*xpc_indicate_partition_engaged) (struct xpc_partition *part); | ||
207 | int (*xpc_partition_engaged) (short partid); | ||
208 | int (*xpc_any_partition_engaged) (void); | ||
209 | void (*xpc_indicate_partition_disengaged) (struct xpc_partition *part); | ||
210 | void (*xpc_assume_partition_disengaged) (short partid); | ||
211 | |||
212 | void (*xpc_send_chctl_closerequest) (struct xpc_channel *ch, | ||
213 | unsigned long *irq_flags); | ||
214 | void (*xpc_send_chctl_closereply) (struct xpc_channel *ch, | ||
215 | unsigned long *irq_flags); | ||
216 | void (*xpc_send_chctl_openrequest) (struct xpc_channel *ch, | ||
217 | unsigned long *irq_flags); | ||
218 | void (*xpc_send_chctl_openreply) (struct xpc_channel *ch, | ||
219 | unsigned long *irq_flags); | ||
220 | |||
221 | enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch, | ||
222 | unsigned long msgqueue_pa); | ||
223 | |||
224 | enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags, | ||
225 | void *payload, u16 payload_size, | ||
226 | u8 notify_type, xpc_notify_func func, | ||
227 | void *key); | ||
228 | void (*xpc_received_payload) (struct xpc_channel *ch, void *payload); | ||
229 | 173 | ||
230 | /* | 174 | /* |
231 | * Timer function to enforce the timelimit on the partition disengage. | 175 | * Timer function to enforce the timelimit on the partition disengage. |
@@ -240,7 +184,7 @@ xpc_timeout_partition_disengage(unsigned long data) | |||
240 | (void)xpc_partition_disengaged(part); | 184 | (void)xpc_partition_disengaged(part); |
241 | 185 | ||
242 | DBUG_ON(part->disengage_timeout != 0); | 186 | DBUG_ON(part->disengage_timeout != 0); |
243 | DBUG_ON(xpc_partition_engaged(XPC_PARTID(part))); | 187 | DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part))); |
244 | } | 188 | } |
245 | 189 | ||
246 | /* | 190 | /* |
@@ -251,7 +195,7 @@ xpc_timeout_partition_disengage(unsigned long data) | |||
251 | static void | 195 | static void |
252 | xpc_hb_beater(unsigned long dummy) | 196 | xpc_hb_beater(unsigned long dummy) |
253 | { | 197 | { |
254 | xpc_increment_heartbeat(); | 198 | xpc_arch_ops.increment_heartbeat(); |
255 | 199 | ||
256 | if (time_is_before_eq_jiffies(xpc_hb_check_timeout)) | 200 | if (time_is_before_eq_jiffies(xpc_hb_check_timeout)) |
257 | wake_up_interruptible(&xpc_activate_IRQ_wq); | 201 | wake_up_interruptible(&xpc_activate_IRQ_wq); |
@@ -263,7 +207,7 @@ xpc_hb_beater(unsigned long dummy) | |||
263 | static void | 207 | static void |
264 | xpc_start_hb_beater(void) | 208 | xpc_start_hb_beater(void) |
265 | { | 209 | { |
266 | xpc_heartbeat_init(); | 210 | xpc_arch_ops.heartbeat_init(); |
267 | init_timer(&xpc_hb_timer); | 211 | init_timer(&xpc_hb_timer); |
268 | xpc_hb_timer.function = xpc_hb_beater; | 212 | xpc_hb_timer.function = xpc_hb_beater; |
269 | xpc_hb_beater(0); | 213 | xpc_hb_beater(0); |
@@ -273,7 +217,7 @@ static void | |||
273 | xpc_stop_hb_beater(void) | 217 | xpc_stop_hb_beater(void) |
274 | { | 218 | { |
275 | del_timer_sync(&xpc_hb_timer); | 219 | del_timer_sync(&xpc_hb_timer); |
276 | xpc_heartbeat_exit(); | 220 | xpc_arch_ops.heartbeat_exit(); |
277 | } | 221 | } |
278 | 222 | ||
279 | /* | 223 | /* |
@@ -302,7 +246,7 @@ xpc_check_remote_hb(void) | |||
302 | continue; | 246 | continue; |
303 | } | 247 | } |
304 | 248 | ||
305 | ret = xpc_get_remote_heartbeat(part); | 249 | ret = xpc_arch_ops.get_remote_heartbeat(part); |
306 | if (ret != xpSuccess) | 250 | if (ret != xpSuccess) |
307 | XPC_DEACTIVATE_PARTITION(part, ret); | 251 | XPC_DEACTIVATE_PARTITION(part, ret); |
308 | } | 252 | } |
@@ -353,7 +297,7 @@ xpc_hb_checker(void *ignore) | |||
353 | force_IRQ = 0; | 297 | force_IRQ = 0; |
354 | dev_dbg(xpc_part, "processing activate IRQs " | 298 | dev_dbg(xpc_part, "processing activate IRQs " |
355 | "received\n"); | 299 | "received\n"); |
356 | xpc_process_activate_IRQ_rcvd(); | 300 | xpc_arch_ops.process_activate_IRQ_rcvd(); |
357 | } | 301 | } |
358 | 302 | ||
359 | /* wait for IRQ or timeout */ | 303 | /* wait for IRQ or timeout */ |
@@ -528,7 +472,7 @@ xpc_setup_ch_structures(struct xpc_partition *part) | |||
528 | init_waitqueue_head(&ch->idle_wq); | 472 | init_waitqueue_head(&ch->idle_wq); |
529 | } | 473 | } |
530 | 474 | ||
531 | ret = xpc_setup_ch_structures_sn(part); | 475 | ret = xpc_arch_ops.setup_ch_structures(part); |
532 | if (ret != xpSuccess) | 476 | if (ret != xpSuccess) |
533 | goto out_2; | 477 | goto out_2; |
534 | 478 | ||
@@ -572,7 +516,7 @@ xpc_teardown_ch_structures(struct xpc_partition *part) | |||
572 | 516 | ||
573 | /* now we can begin tearing down the infrastructure */ | 517 | /* now we can begin tearing down the infrastructure */ |
574 | 518 | ||
575 | xpc_teardown_ch_structures_sn(part); | 519 | xpc_arch_ops.teardown_ch_structures(part); |
576 | 520 | ||
577 | kfree(part->remote_openclose_args_base); | 521 | kfree(part->remote_openclose_args_base); |
578 | part->remote_openclose_args = NULL; | 522 | part->remote_openclose_args = NULL; |
@@ -620,12 +564,12 @@ xpc_activating(void *__partid) | |||
620 | 564 | ||
621 | dev_dbg(xpc_part, "activating partition %d\n", partid); | 565 | dev_dbg(xpc_part, "activating partition %d\n", partid); |
622 | 566 | ||
623 | xpc_allow_hb(partid); | 567 | xpc_arch_ops.allow_hb(partid); |
624 | 568 | ||
625 | if (xpc_setup_ch_structures(part) == xpSuccess) { | 569 | if (xpc_setup_ch_structures(part) == xpSuccess) { |
626 | (void)xpc_part_ref(part); /* this will always succeed */ | 570 | (void)xpc_part_ref(part); /* this will always succeed */ |
627 | 571 | ||
628 | if (xpc_make_first_contact(part) == xpSuccess) { | 572 | if (xpc_arch_ops.make_first_contact(part) == xpSuccess) { |
629 | xpc_mark_partition_active(part); | 573 | xpc_mark_partition_active(part); |
630 | xpc_channel_mgr(part); | 574 | xpc_channel_mgr(part); |
631 | /* won't return until partition is deactivating */ | 575 | /* won't return until partition is deactivating */ |
@@ -635,12 +579,12 @@ xpc_activating(void *__partid) | |||
635 | xpc_teardown_ch_structures(part); | 579 | xpc_teardown_ch_structures(part); |
636 | } | 580 | } |
637 | 581 | ||
638 | xpc_disallow_hb(partid); | 582 | xpc_arch_ops.disallow_hb(partid); |
639 | xpc_mark_partition_inactive(part); | 583 | xpc_mark_partition_inactive(part); |
640 | 584 | ||
641 | if (part->reason == xpReactivating) { | 585 | if (part->reason == xpReactivating) { |
642 | /* interrupting ourselves results in activating partition */ | 586 | /* interrupting ourselves results in activating partition */ |
643 | xpc_request_partition_reactivation(part); | 587 | xpc_arch_ops.request_partition_reactivation(part); |
644 | } | 588 | } |
645 | 589 | ||
646 | return 0; | 590 | return 0; |
@@ -713,10 +657,13 @@ xpc_activate_kthreads(struct xpc_channel *ch, int needed) | |||
713 | static void | 657 | static void |
714 | xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch) | 658 | xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch) |
715 | { | 659 | { |
660 | int (*n_of_deliverable_payloads) (struct xpc_channel *) = | ||
661 | xpc_arch_ops.n_of_deliverable_payloads; | ||
662 | |||
716 | do { | 663 | do { |
717 | /* deliver messages to their intended recipients */ | 664 | /* deliver messages to their intended recipients */ |
718 | 665 | ||
719 | while (xpc_n_of_deliverable_payloads(ch) > 0 && | 666 | while (n_of_deliverable_payloads(ch) > 0 && |
720 | !(ch->flags & XPC_C_DISCONNECTING)) { | 667 | !(ch->flags & XPC_C_DISCONNECTING)) { |
721 | xpc_deliver_payload(ch); | 668 | xpc_deliver_payload(ch); |
722 | } | 669 | } |
@@ -732,7 +679,7 @@ xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch) | |||
732 | "wait_event_interruptible_exclusive()\n"); | 679 | "wait_event_interruptible_exclusive()\n"); |
733 | 680 | ||
734 | (void)wait_event_interruptible_exclusive(ch->idle_wq, | 681 | (void)wait_event_interruptible_exclusive(ch->idle_wq, |
735 | (xpc_n_of_deliverable_payloads(ch) > 0 || | 682 | (n_of_deliverable_payloads(ch) > 0 || |
736 | (ch->flags & XPC_C_DISCONNECTING))); | 683 | (ch->flags & XPC_C_DISCONNECTING))); |
737 | 684 | ||
738 | atomic_dec(&ch->kthreads_idle); | 685 | atomic_dec(&ch->kthreads_idle); |
@@ -749,6 +696,8 @@ xpc_kthread_start(void *args) | |||
749 | struct xpc_channel *ch; | 696 | struct xpc_channel *ch; |
750 | int n_needed; | 697 | int n_needed; |
751 | unsigned long irq_flags; | 698 | unsigned long irq_flags; |
699 | int (*n_of_deliverable_payloads) (struct xpc_channel *) = | ||
700 | xpc_arch_ops.n_of_deliverable_payloads; | ||
752 | 701 | ||
753 | dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n", | 702 | dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n", |
754 | partid, ch_number); | 703 | partid, ch_number); |
@@ -777,7 +726,7 @@ xpc_kthread_start(void *args) | |||
777 | * additional kthreads to help deliver them. We only | 726 | * additional kthreads to help deliver them. We only |
778 | * need one less than total #of messages to deliver. | 727 | * need one less than total #of messages to deliver. |
779 | */ | 728 | */ |
780 | n_needed = xpc_n_of_deliverable_payloads(ch) - 1; | 729 | n_needed = n_of_deliverable_payloads(ch) - 1; |
781 | if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING)) | 730 | if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING)) |
782 | xpc_activate_kthreads(ch, n_needed); | 731 | xpc_activate_kthreads(ch, n_needed); |
783 | 732 | ||
@@ -805,7 +754,7 @@ xpc_kthread_start(void *args) | |||
805 | 754 | ||
806 | if (atomic_dec_return(&ch->kthreads_assigned) == 0 && | 755 | if (atomic_dec_return(&ch->kthreads_assigned) == 0 && |
807 | atomic_dec_return(&part->nchannels_engaged) == 0) { | 756 | atomic_dec_return(&part->nchannels_engaged) == 0) { |
808 | xpc_indicate_partition_disengaged(part); | 757 | xpc_arch_ops.indicate_partition_disengaged(part); |
809 | } | 758 | } |
810 | 759 | ||
811 | xpc_msgqueue_deref(ch); | 760 | xpc_msgqueue_deref(ch); |
@@ -837,6 +786,8 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, | |||
837 | u64 args = XPC_PACK_ARGS(ch->partid, ch->number); | 786 | u64 args = XPC_PACK_ARGS(ch->partid, ch->number); |
838 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | 787 | struct xpc_partition *part = &xpc_partitions[ch->partid]; |
839 | struct task_struct *kthread; | 788 | struct task_struct *kthread; |
789 | void (*indicate_partition_disengaged) (struct xpc_partition *) = | ||
790 | xpc_arch_ops.indicate_partition_disengaged; | ||
840 | 791 | ||
841 | while (needed-- > 0) { | 792 | while (needed-- > 0) { |
842 | 793 | ||
@@ -858,7 +809,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, | |||
858 | 809 | ||
859 | } else if (atomic_inc_return(&ch->kthreads_assigned) == 1 && | 810 | } else if (atomic_inc_return(&ch->kthreads_assigned) == 1 && |
860 | atomic_inc_return(&part->nchannels_engaged) == 1) { | 811 | atomic_inc_return(&part->nchannels_engaged) == 1) { |
861 | xpc_indicate_partition_engaged(part); | 812 | xpc_arch_ops.indicate_partition_engaged(part); |
862 | } | 813 | } |
863 | (void)xpc_part_ref(part); | 814 | (void)xpc_part_ref(part); |
864 | xpc_msgqueue_ref(ch); | 815 | xpc_msgqueue_ref(ch); |
@@ -880,7 +831,7 @@ xpc_create_kthreads(struct xpc_channel *ch, int needed, | |||
880 | 831 | ||
881 | if (atomic_dec_return(&ch->kthreads_assigned) == 0 && | 832 | if (atomic_dec_return(&ch->kthreads_assigned) == 0 && |
882 | atomic_dec_return(&part->nchannels_engaged) == 0) { | 833 | atomic_dec_return(&part->nchannels_engaged) == 0) { |
883 | xpc_indicate_partition_disengaged(part); | 834 | indicate_partition_disengaged(part); |
884 | } | 835 | } |
885 | xpc_msgqueue_deref(ch); | 836 | xpc_msgqueue_deref(ch); |
886 | xpc_part_deref(part); | 837 | xpc_part_deref(part); |
@@ -993,13 +944,13 @@ xpc_setup_partitions(void) | |||
993 | atomic_set(&part->references, 0); | 944 | atomic_set(&part->references, 0); |
994 | } | 945 | } |
995 | 946 | ||
996 | return xpc_setup_partitions_sn(); | 947 | return xpc_arch_ops.setup_partitions(); |
997 | } | 948 | } |
998 | 949 | ||
999 | static void | 950 | static void |
1000 | xpc_teardown_partitions(void) | 951 | xpc_teardown_partitions(void) |
1001 | { | 952 | { |
1002 | xpc_teardown_partitions_sn(); | 953 | xpc_arch_ops.teardown_partitions(); |
1003 | kfree(xpc_partitions); | 954 | kfree(xpc_partitions); |
1004 | } | 955 | } |
1005 | 956 | ||
@@ -1055,7 +1006,7 @@ xpc_do_exit(enum xp_retval reason) | |||
1055 | disengage_timeout = part->disengage_timeout; | 1006 | disengage_timeout = part->disengage_timeout; |
1056 | } | 1007 | } |
1057 | 1008 | ||
1058 | if (xpc_any_partition_engaged()) { | 1009 | if (xpc_arch_ops.any_partition_engaged()) { |
1059 | if (time_is_before_jiffies(printmsg_time)) { | 1010 | if (time_is_before_jiffies(printmsg_time)) { |
1060 | dev_info(xpc_part, "waiting for remote " | 1011 | dev_info(xpc_part, "waiting for remote " |
1061 | "partitions to deactivate, timeout in " | 1012 | "partitions to deactivate, timeout in " |
@@ -1086,8 +1037,7 @@ xpc_do_exit(enum xp_retval reason) | |||
1086 | 1037 | ||
1087 | } while (1); | 1038 | } while (1); |
1088 | 1039 | ||
1089 | DBUG_ON(xpc_any_partition_engaged()); | 1040 | DBUG_ON(xpc_arch_ops.any_partition_engaged()); |
1090 | DBUG_ON(xpc_any_hbs_allowed() != 0); | ||
1091 | 1041 | ||
1092 | xpc_teardown_rsvd_page(); | 1042 | xpc_teardown_rsvd_page(); |
1093 | 1043 | ||
@@ -1152,15 +1102,15 @@ xpc_die_deactivate(void) | |||
1152 | /* keep xpc_hb_checker thread from doing anything (just in case) */ | 1102 | /* keep xpc_hb_checker thread from doing anything (just in case) */ |
1153 | xpc_exiting = 1; | 1103 | xpc_exiting = 1; |
1154 | 1104 | ||
1155 | xpc_disallow_all_hbs(); /*indicate we're deactivated */ | 1105 | xpc_arch_ops.disallow_all_hbs(); /*indicate we're deactivated */ |
1156 | 1106 | ||
1157 | for (partid = 0; partid < xp_max_npartitions; partid++) { | 1107 | for (partid = 0; partid < xp_max_npartitions; partid++) { |
1158 | part = &xpc_partitions[partid]; | 1108 | part = &xpc_partitions[partid]; |
1159 | 1109 | ||
1160 | if (xpc_partition_engaged(partid) || | 1110 | if (xpc_arch_ops.partition_engaged(partid) || |
1161 | part->act_state != XPC_P_AS_INACTIVE) { | 1111 | part->act_state != XPC_P_AS_INACTIVE) { |
1162 | xpc_request_partition_deactivation(part); | 1112 | xpc_arch_ops.request_partition_deactivation(part); |
1163 | xpc_indicate_partition_disengaged(part); | 1113 | xpc_arch_ops.indicate_partition_disengaged(part); |
1164 | } | 1114 | } |
1165 | } | 1115 | } |
1166 | 1116 | ||
@@ -1177,7 +1127,7 @@ xpc_die_deactivate(void) | |||
1177 | wait_to_print = XPC_DEACTIVATE_PRINTMSG_INTERVAL * 1000 * 5; | 1127 | wait_to_print = XPC_DEACTIVATE_PRINTMSG_INTERVAL * 1000 * 5; |
1178 | 1128 | ||
1179 | while (1) { | 1129 | while (1) { |
1180 | any_engaged = xpc_any_partition_engaged(); | 1130 | any_engaged = xpc_arch_ops.any_partition_engaged(); |
1181 | if (!any_engaged) { | 1131 | if (!any_engaged) { |
1182 | dev_info(xpc_part, "all partitions have deactivated\n"); | 1132 | dev_info(xpc_part, "all partitions have deactivated\n"); |
1183 | break; | 1133 | break; |
@@ -1186,7 +1136,7 @@ xpc_die_deactivate(void) | |||
1186 | if (!keep_waiting--) { | 1136 | if (!keep_waiting--) { |
1187 | for (partid = 0; partid < xp_max_npartitions; | 1137 | for (partid = 0; partid < xp_max_npartitions; |
1188 | partid++) { | 1138 | partid++) { |
1189 | if (xpc_partition_engaged(partid)) { | 1139 | if (xpc_arch_ops.partition_engaged(partid)) { |
1190 | dev_info(xpc_part, "deactivate from " | 1140 | dev_info(xpc_part, "deactivate from " |
1191 | "remote partition %d timed " | 1141 | "remote partition %d timed " |
1192 | "out\n", partid); | 1142 | "out\n", partid); |
@@ -1233,7 +1183,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) | |||
1233 | /* fall through */ | 1183 | /* fall through */ |
1234 | case DIE_MCA_MONARCH_ENTER: | 1184 | case DIE_MCA_MONARCH_ENTER: |
1235 | case DIE_INIT_MONARCH_ENTER: | 1185 | case DIE_INIT_MONARCH_ENTER: |
1236 | xpc_offline_heartbeat(); | 1186 | xpc_arch_ops.offline_heartbeat(); |
1237 | break; | 1187 | break; |
1238 | 1188 | ||
1239 | case DIE_KDEBUG_LEAVE: | 1189 | case DIE_KDEBUG_LEAVE: |
@@ -1244,7 +1194,7 @@ xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) | |||
1244 | /* fall through */ | 1194 | /* fall through */ |
1245 | case DIE_MCA_MONARCH_LEAVE: | 1195 | case DIE_MCA_MONARCH_LEAVE: |
1246 | case DIE_INIT_MONARCH_LEAVE: | 1196 | case DIE_INIT_MONARCH_LEAVE: |
1247 | xpc_online_heartbeat(); | 1197 | xpc_arch_ops.online_heartbeat(); |
1248 | break; | 1198 | break; |
1249 | } | 1199 | } |
1250 | #else | 1200 | #else |
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index 6722f6fe4dc7..65877bc5edaa 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c | |||
@@ -70,6 +70,9 @@ xpc_get_rsvd_page_pa(int nasid) | |||
70 | size_t buf_len = 0; | 70 | size_t buf_len = 0; |
71 | void *buf = buf; | 71 | void *buf = buf; |
72 | void *buf_base = NULL; | 72 | void *buf_base = NULL; |
73 | enum xp_retval (*get_partition_rsvd_page_pa) | ||
74 | (void *, u64 *, unsigned long *, size_t *) = | ||
75 | xpc_arch_ops.get_partition_rsvd_page_pa; | ||
73 | 76 | ||
74 | while (1) { | 77 | while (1) { |
75 | 78 | ||
@@ -79,8 +82,7 @@ xpc_get_rsvd_page_pa(int nasid) | |||
79 | * ??? function or have two versions? Rename rp_pa for UV to | 82 | * ??? function or have two versions? Rename rp_pa for UV to |
80 | * ??? rp_gpa? | 83 | * ??? rp_gpa? |
81 | */ | 84 | */ |
82 | ret = xpc_get_partition_rsvd_page_pa(buf, &cookie, &rp_pa, | 85 | ret = get_partition_rsvd_page_pa(buf, &cookie, &rp_pa, &len); |
83 | &len); | ||
84 | 86 | ||
85 | dev_dbg(xpc_part, "SAL returned with ret=%d, cookie=0x%016lx, " | 87 | dev_dbg(xpc_part, "SAL returned with ret=%d, cookie=0x%016lx, " |
86 | "address=0x%016lx, len=0x%016lx\n", ret, | 88 | "address=0x%016lx, len=0x%016lx\n", ret, |
@@ -172,7 +174,7 @@ xpc_setup_rsvd_page(void) | |||
172 | xpc_part_nasids = XPC_RP_PART_NASIDS(rp); | 174 | xpc_part_nasids = XPC_RP_PART_NASIDS(rp); |
173 | xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp); | 175 | xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp); |
174 | 176 | ||
175 | ret = xpc_setup_rsvd_page_sn(rp); | 177 | ret = xpc_arch_ops.setup_rsvd_page(rp); |
176 | if (ret != 0) | 178 | if (ret != 0) |
177 | return ret; | 179 | return ret; |
178 | 180 | ||
@@ -264,7 +266,7 @@ xpc_partition_disengaged(struct xpc_partition *part) | |||
264 | short partid = XPC_PARTID(part); | 266 | short partid = XPC_PARTID(part); |
265 | int disengaged; | 267 | int disengaged; |
266 | 268 | ||
267 | disengaged = !xpc_partition_engaged(partid); | 269 | disengaged = !xpc_arch_ops.partition_engaged(partid); |
268 | if (part->disengage_timeout) { | 270 | if (part->disengage_timeout) { |
269 | if (!disengaged) { | 271 | if (!disengaged) { |
270 | if (time_is_after_jiffies(part->disengage_timeout)) { | 272 | if (time_is_after_jiffies(part->disengage_timeout)) { |
@@ -280,7 +282,7 @@ xpc_partition_disengaged(struct xpc_partition *part) | |||
280 | dev_info(xpc_part, "deactivate request to remote " | 282 | dev_info(xpc_part, "deactivate request to remote " |
281 | "partition %d timed out\n", partid); | 283 | "partition %d timed out\n", partid); |
282 | xpc_disengage_timedout = 1; | 284 | xpc_disengage_timedout = 1; |
283 | xpc_assume_partition_disengaged(partid); | 285 | xpc_arch_ops.assume_partition_disengaged(partid); |
284 | disengaged = 1; | 286 | disengaged = 1; |
285 | } | 287 | } |
286 | part->disengage_timeout = 0; | 288 | part->disengage_timeout = 0; |
@@ -294,7 +296,7 @@ xpc_partition_disengaged(struct xpc_partition *part) | |||
294 | if (part->act_state != XPC_P_AS_INACTIVE) | 296 | if (part->act_state != XPC_P_AS_INACTIVE) |
295 | xpc_wakeup_channel_mgr(part); | 297 | xpc_wakeup_channel_mgr(part); |
296 | 298 | ||
297 | xpc_cancel_partition_deactivation_request(part); | 299 | xpc_arch_ops.cancel_partition_deactivation_request(part); |
298 | } | 300 | } |
299 | return disengaged; | 301 | return disengaged; |
300 | } | 302 | } |
@@ -339,7 +341,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, | |||
339 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | 341 | spin_unlock_irqrestore(&part->act_lock, irq_flags); |
340 | if (reason == xpReactivating) { | 342 | if (reason == xpReactivating) { |
341 | /* we interrupt ourselves to reactivate partition */ | 343 | /* we interrupt ourselves to reactivate partition */ |
342 | xpc_request_partition_reactivation(part); | 344 | xpc_arch_ops.request_partition_reactivation(part); |
343 | } | 345 | } |
344 | return; | 346 | return; |
345 | } | 347 | } |
@@ -358,7 +360,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part, | |||
358 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | 360 | spin_unlock_irqrestore(&part->act_lock, irq_flags); |
359 | 361 | ||
360 | /* ask remote partition to deactivate with regard to us */ | 362 | /* ask remote partition to deactivate with regard to us */ |
361 | xpc_request_partition_deactivation(part); | 363 | xpc_arch_ops.request_partition_deactivation(part); |
362 | 364 | ||
363 | /* set a timelimit on the disengage phase of the deactivation request */ | 365 | /* set a timelimit on the disengage phase of the deactivation request */ |
364 | part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ); | 366 | part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ); |
@@ -496,7 +498,7 @@ xpc_discovery(void) | |||
496 | continue; | 498 | continue; |
497 | } | 499 | } |
498 | 500 | ||
499 | xpc_request_partition_activation(remote_rp, | 501 | xpc_arch_ops.request_partition_activation(remote_rp, |
500 | remote_rp_pa, nasid); | 502 | remote_rp_pa, nasid); |
501 | } | 503 | } |
502 | } | 504 | } |
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index eaaa964942de..915a3b495da5 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* | 9 | /* |
@@ -60,14 +60,14 @@ static struct xpc_vars_sn2 *xpc_vars_sn2; | |||
60 | static struct xpc_vars_part_sn2 *xpc_vars_part_sn2; | 60 | static struct xpc_vars_part_sn2 *xpc_vars_part_sn2; |
61 | 61 | ||
62 | static int | 62 | static int |
63 | xpc_setup_partitions_sn_sn2(void) | 63 | xpc_setup_partitions_sn2(void) |
64 | { | 64 | { |
65 | /* nothing needs to be done */ | 65 | /* nothing needs to be done */ |
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | 68 | ||
69 | static void | 69 | static void |
70 | xpc_teardown_partitions_sn_sn2(void) | 70 | xpc_teardown_partitions_sn2(void) |
71 | { | 71 | { |
72 | /* nothing needs to be done */ | 72 | /* nothing needs to be done */ |
73 | } | 73 | } |
@@ -431,6 +431,13 @@ xpc_send_chctl_openreply_sn2(struct xpc_channel *ch, unsigned long *irq_flags) | |||
431 | } | 431 | } |
432 | 432 | ||
433 | static void | 433 | static void |
434 | xpc_send_chctl_opencomplete_sn2(struct xpc_channel *ch, | ||
435 | unsigned long *irq_flags) | ||
436 | { | ||
437 | XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENCOMPLETE, irq_flags); | ||
438 | } | ||
439 | |||
440 | static void | ||
434 | xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch) | 441 | xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch) |
435 | { | 442 | { |
436 | XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL); | 443 | XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL); |
@@ -621,7 +628,7 @@ xpc_get_partition_rsvd_page_pa_sn2(void *buf, u64 *cookie, unsigned long *rp_pa, | |||
621 | 628 | ||
622 | 629 | ||
623 | static int | 630 | static int |
624 | xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp) | 631 | xpc_setup_rsvd_page_sn2(struct xpc_rsvd_page *rp) |
625 | { | 632 | { |
626 | struct amo *amos_page; | 633 | struct amo *amos_page; |
627 | int i; | 634 | int i; |
@@ -629,7 +636,7 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp) | |||
629 | 636 | ||
630 | xpc_vars_sn2 = XPC_RP_VARS(rp); | 637 | xpc_vars_sn2 = XPC_RP_VARS(rp); |
631 | 638 | ||
632 | rp->sn.vars_pa = xp_pa(xpc_vars_sn2); | 639 | rp->sn.sn2.vars_pa = xp_pa(xpc_vars_sn2); |
633 | 640 | ||
634 | /* vars_part array follows immediately after vars */ | 641 | /* vars_part array follows immediately after vars */ |
635 | xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) + | 642 | xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) + |
@@ -693,6 +700,33 @@ xpc_setup_rsvd_page_sn_sn2(struct xpc_rsvd_page *rp) | |||
693 | return 0; | 700 | return 0; |
694 | } | 701 | } |
695 | 702 | ||
703 | static int | ||
704 | xpc_hb_allowed_sn2(short partid, void *heartbeating_to_mask) | ||
705 | { | ||
706 | return test_bit(partid, heartbeating_to_mask); | ||
707 | } | ||
708 | |||
709 | static void | ||
710 | xpc_allow_hb_sn2(short partid) | ||
711 | { | ||
712 | DBUG_ON(xpc_vars_sn2 == NULL); | ||
713 | set_bit(partid, xpc_vars_sn2->heartbeating_to_mask); | ||
714 | } | ||
715 | |||
716 | static void | ||
717 | xpc_disallow_hb_sn2(short partid) | ||
718 | { | ||
719 | DBUG_ON(xpc_vars_sn2 == NULL); | ||
720 | clear_bit(partid, xpc_vars_sn2->heartbeating_to_mask); | ||
721 | } | ||
722 | |||
723 | static void | ||
724 | xpc_disallow_all_hbs_sn2(void) | ||
725 | { | ||
726 | DBUG_ON(xpc_vars_sn2 == NULL); | ||
727 | bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, xp_max_npartitions); | ||
728 | } | ||
729 | |||
696 | static void | 730 | static void |
697 | xpc_increment_heartbeat_sn2(void) | 731 | xpc_increment_heartbeat_sn2(void) |
698 | { | 732 | { |
@@ -719,7 +753,6 @@ xpc_heartbeat_init_sn2(void) | |||
719 | DBUG_ON(xpc_vars_sn2 == NULL); | 753 | DBUG_ON(xpc_vars_sn2 == NULL); |
720 | 754 | ||
721 | bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2); | 755 | bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2); |
722 | xpc_heartbeating_to_mask = &xpc_vars_sn2->heartbeating_to_mask[0]; | ||
723 | xpc_online_heartbeat_sn2(); | 756 | xpc_online_heartbeat_sn2(); |
724 | } | 757 | } |
725 | 758 | ||
@@ -751,9 +784,9 @@ xpc_get_remote_heartbeat_sn2(struct xpc_partition *part) | |||
751 | remote_vars->heartbeating_to_mask[0]); | 784 | remote_vars->heartbeating_to_mask[0]); |
752 | 785 | ||
753 | if ((remote_vars->heartbeat == part->last_heartbeat && | 786 | if ((remote_vars->heartbeat == part->last_heartbeat && |
754 | remote_vars->heartbeat_offline == 0) || | 787 | !remote_vars->heartbeat_offline) || |
755 | !xpc_hb_allowed(sn_partition_id, | 788 | !xpc_hb_allowed_sn2(sn_partition_id, |
756 | &remote_vars->heartbeating_to_mask)) { | 789 | remote_vars->heartbeating_to_mask)) { |
757 | ret = xpNoHeartbeat; | 790 | ret = xpNoHeartbeat; |
758 | } else { | 791 | } else { |
759 | part->last_heartbeat = remote_vars->heartbeat; | 792 | part->last_heartbeat = remote_vars->heartbeat; |
@@ -972,7 +1005,7 @@ xpc_identify_activate_IRQ_req_sn2(int nasid) | |||
972 | return; | 1005 | return; |
973 | } | 1006 | } |
974 | 1007 | ||
975 | remote_vars_pa = remote_rp->sn.vars_pa; | 1008 | remote_vars_pa = remote_rp->sn.sn2.vars_pa; |
976 | remote_rp_version = remote_rp->version; | 1009 | remote_rp_version = remote_rp->version; |
977 | remote_rp_ts_jiffies = remote_rp->ts_jiffies; | 1010 | remote_rp_ts_jiffies = remote_rp->ts_jiffies; |
978 | 1011 | ||
@@ -1129,7 +1162,7 @@ xpc_process_activate_IRQ_rcvd_sn2(void) | |||
1129 | * Setup the channel structures that are sn2 specific. | 1162 | * Setup the channel structures that are sn2 specific. |
1130 | */ | 1163 | */ |
1131 | static enum xp_retval | 1164 | static enum xp_retval |
1132 | xpc_setup_ch_structures_sn_sn2(struct xpc_partition *part) | 1165 | xpc_setup_ch_structures_sn2(struct xpc_partition *part) |
1133 | { | 1166 | { |
1134 | struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; | 1167 | struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; |
1135 | struct xpc_channel_sn2 *ch_sn2; | 1168 | struct xpc_channel_sn2 *ch_sn2; |
@@ -1251,7 +1284,7 @@ out_1: | |||
1251 | * Teardown the channel structures that are sn2 specific. | 1284 | * Teardown the channel structures that are sn2 specific. |
1252 | */ | 1285 | */ |
1253 | static void | 1286 | static void |
1254 | xpc_teardown_ch_structures_sn_sn2(struct xpc_partition *part) | 1287 | xpc_teardown_ch_structures_sn2(struct xpc_partition *part) |
1255 | { | 1288 | { |
1256 | struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; | 1289 | struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2; |
1257 | short partid = XPC_PARTID(part); | 1290 | short partid = XPC_PARTID(part); |
@@ -2315,61 +2348,70 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload) | |||
2315 | xpc_acknowledge_msgs_sn2(ch, get, msg->flags); | 2348 | xpc_acknowledge_msgs_sn2(ch, get, msg->flags); |
2316 | } | 2349 | } |
2317 | 2350 | ||
2351 | static struct xpc_arch_operations xpc_arch_ops_sn2 = { | ||
2352 | .setup_partitions = xpc_setup_partitions_sn2, | ||
2353 | .teardown_partitions = xpc_teardown_partitions_sn2, | ||
2354 | .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2, | ||
2355 | .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2, | ||
2356 | .setup_rsvd_page = xpc_setup_rsvd_page_sn2, | ||
2357 | |||
2358 | .allow_hb = xpc_allow_hb_sn2, | ||
2359 | .disallow_hb = xpc_disallow_hb_sn2, | ||
2360 | .disallow_all_hbs = xpc_disallow_all_hbs_sn2, | ||
2361 | .increment_heartbeat = xpc_increment_heartbeat_sn2, | ||
2362 | .offline_heartbeat = xpc_offline_heartbeat_sn2, | ||
2363 | .online_heartbeat = xpc_online_heartbeat_sn2, | ||
2364 | .heartbeat_init = xpc_heartbeat_init_sn2, | ||
2365 | .heartbeat_exit = xpc_heartbeat_exit_sn2, | ||
2366 | .get_remote_heartbeat = xpc_get_remote_heartbeat_sn2, | ||
2367 | |||
2368 | .request_partition_activation = | ||
2369 | xpc_request_partition_activation_sn2, | ||
2370 | .request_partition_reactivation = | ||
2371 | xpc_request_partition_reactivation_sn2, | ||
2372 | .request_partition_deactivation = | ||
2373 | xpc_request_partition_deactivation_sn2, | ||
2374 | .cancel_partition_deactivation_request = | ||
2375 | xpc_cancel_partition_deactivation_request_sn2, | ||
2376 | |||
2377 | .setup_ch_structures = xpc_setup_ch_structures_sn2, | ||
2378 | .teardown_ch_structures = xpc_teardown_ch_structures_sn2, | ||
2379 | |||
2380 | .make_first_contact = xpc_make_first_contact_sn2, | ||
2381 | |||
2382 | .get_chctl_all_flags = xpc_get_chctl_all_flags_sn2, | ||
2383 | .send_chctl_closerequest = xpc_send_chctl_closerequest_sn2, | ||
2384 | .send_chctl_closereply = xpc_send_chctl_closereply_sn2, | ||
2385 | .send_chctl_openrequest = xpc_send_chctl_openrequest_sn2, | ||
2386 | .send_chctl_openreply = xpc_send_chctl_openreply_sn2, | ||
2387 | .send_chctl_opencomplete = xpc_send_chctl_opencomplete_sn2, | ||
2388 | .process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2, | ||
2389 | |||
2390 | .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2, | ||
2391 | |||
2392 | .setup_msg_structures = xpc_setup_msg_structures_sn2, | ||
2393 | .teardown_msg_structures = xpc_teardown_msg_structures_sn2, | ||
2394 | |||
2395 | .indicate_partition_engaged = xpc_indicate_partition_engaged_sn2, | ||
2396 | .indicate_partition_disengaged = xpc_indicate_partition_disengaged_sn2, | ||
2397 | .partition_engaged = xpc_partition_engaged_sn2, | ||
2398 | .any_partition_engaged = xpc_any_partition_engaged_sn2, | ||
2399 | .assume_partition_disengaged = xpc_assume_partition_disengaged_sn2, | ||
2400 | |||
2401 | .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2, | ||
2402 | .send_payload = xpc_send_payload_sn2, | ||
2403 | .get_deliverable_payload = xpc_get_deliverable_payload_sn2, | ||
2404 | .received_payload = xpc_received_payload_sn2, | ||
2405 | .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2, | ||
2406 | }; | ||
2407 | |||
2318 | int | 2408 | int |
2319 | xpc_init_sn2(void) | 2409 | xpc_init_sn2(void) |
2320 | { | 2410 | { |
2321 | int ret; | 2411 | int ret; |
2322 | size_t buf_size; | 2412 | size_t buf_size; |
2323 | 2413 | ||
2324 | xpc_setup_partitions_sn = xpc_setup_partitions_sn_sn2; | 2414 | xpc_arch_ops = xpc_arch_ops_sn2; |
2325 | xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_sn2; | ||
2326 | xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2; | ||
2327 | xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2; | ||
2328 | xpc_increment_heartbeat = xpc_increment_heartbeat_sn2; | ||
2329 | xpc_offline_heartbeat = xpc_offline_heartbeat_sn2; | ||
2330 | xpc_online_heartbeat = xpc_online_heartbeat_sn2; | ||
2331 | xpc_heartbeat_init = xpc_heartbeat_init_sn2; | ||
2332 | xpc_heartbeat_exit = xpc_heartbeat_exit_sn2; | ||
2333 | xpc_get_remote_heartbeat = xpc_get_remote_heartbeat_sn2; | ||
2334 | |||
2335 | xpc_request_partition_activation = xpc_request_partition_activation_sn2; | ||
2336 | xpc_request_partition_reactivation = | ||
2337 | xpc_request_partition_reactivation_sn2; | ||
2338 | xpc_request_partition_deactivation = | ||
2339 | xpc_request_partition_deactivation_sn2; | ||
2340 | xpc_cancel_partition_deactivation_request = | ||
2341 | xpc_cancel_partition_deactivation_request_sn2; | ||
2342 | |||
2343 | xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2; | ||
2344 | xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_sn2; | ||
2345 | xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_sn2; | ||
2346 | xpc_make_first_contact = xpc_make_first_contact_sn2; | ||
2347 | |||
2348 | xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_sn2; | ||
2349 | xpc_send_chctl_closerequest = xpc_send_chctl_closerequest_sn2; | ||
2350 | xpc_send_chctl_closereply = xpc_send_chctl_closereply_sn2; | ||
2351 | xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_sn2; | ||
2352 | xpc_send_chctl_openreply = xpc_send_chctl_openreply_sn2; | ||
2353 | |||
2354 | xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2; | ||
2355 | |||
2356 | xpc_setup_msg_structures = xpc_setup_msg_structures_sn2; | ||
2357 | xpc_teardown_msg_structures = xpc_teardown_msg_structures_sn2; | ||
2358 | |||
2359 | xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2; | ||
2360 | xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2; | ||
2361 | xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2; | ||
2362 | xpc_get_deliverable_payload = xpc_get_deliverable_payload_sn2; | ||
2363 | |||
2364 | xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_sn2; | ||
2365 | xpc_indicate_partition_disengaged = | ||
2366 | xpc_indicate_partition_disengaged_sn2; | ||
2367 | xpc_partition_engaged = xpc_partition_engaged_sn2; | ||
2368 | xpc_any_partition_engaged = xpc_any_partition_engaged_sn2; | ||
2369 | xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_sn2; | ||
2370 | |||
2371 | xpc_send_payload = xpc_send_payload_sn2; | ||
2372 | xpc_received_payload = xpc_received_payload_sn2; | ||
2373 | 2415 | ||
2374 | if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) { | 2416 | if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) { |
2375 | dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is " | 2417 | dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is " |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index f7fff4727edb..9172fcdee4e2 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
@@ -46,8 +46,7 @@ struct uv_IO_APIC_route_entry { | |||
46 | }; | 46 | }; |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | static atomic64_t xpc_heartbeat_uv; | 49 | static struct xpc_heartbeat_uv *xpc_heartbeat_uv; |
50 | static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV); | ||
51 | 50 | ||
52 | #define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES) | 51 | #define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES) |
53 | #define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ | 52 | #define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \ |
@@ -63,7 +62,7 @@ static struct xpc_gru_mq_uv *xpc_activate_mq_uv; | |||
63 | static struct xpc_gru_mq_uv *xpc_notify_mq_uv; | 62 | static struct xpc_gru_mq_uv *xpc_notify_mq_uv; |
64 | 63 | ||
65 | static int | 64 | static int |
66 | xpc_setup_partitions_sn_uv(void) | 65 | xpc_setup_partitions_uv(void) |
67 | { | 66 | { |
68 | short partid; | 67 | short partid; |
69 | struct xpc_partition_uv *part_uv; | 68 | struct xpc_partition_uv *part_uv; |
@@ -79,7 +78,7 @@ xpc_setup_partitions_sn_uv(void) | |||
79 | } | 78 | } |
80 | 79 | ||
81 | static void | 80 | static void |
82 | xpc_teardown_partitions_sn_uv(void) | 81 | xpc_teardown_partitions_uv(void) |
83 | { | 82 | { |
84 | short partid; | 83 | short partid; |
85 | struct xpc_partition_uv *part_uv; | 84 | struct xpc_partition_uv *part_uv; |
@@ -423,41 +422,6 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, | |||
423 | /* syncing of remote_act_state was just done above */ | 422 | /* syncing of remote_act_state was just done above */ |
424 | break; | 423 | break; |
425 | 424 | ||
426 | case XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV: { | ||
427 | struct xpc_activate_mq_msg_heartbeat_req_uv *msg; | ||
428 | |||
429 | msg = container_of(msg_hdr, | ||
430 | struct xpc_activate_mq_msg_heartbeat_req_uv, | ||
431 | hdr); | ||
432 | part_uv->heartbeat = msg->heartbeat; | ||
433 | break; | ||
434 | } | ||
435 | case XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV: { | ||
436 | struct xpc_activate_mq_msg_heartbeat_req_uv *msg; | ||
437 | |||
438 | msg = container_of(msg_hdr, | ||
439 | struct xpc_activate_mq_msg_heartbeat_req_uv, | ||
440 | hdr); | ||
441 | part_uv->heartbeat = msg->heartbeat; | ||
442 | |||
443 | spin_lock_irqsave(&part_uv->flags_lock, irq_flags); | ||
444 | part_uv->flags |= XPC_P_HEARTBEAT_OFFLINE_UV; | ||
445 | spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); | ||
446 | break; | ||
447 | } | ||
448 | case XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV: { | ||
449 | struct xpc_activate_mq_msg_heartbeat_req_uv *msg; | ||
450 | |||
451 | msg = container_of(msg_hdr, | ||
452 | struct xpc_activate_mq_msg_heartbeat_req_uv, | ||
453 | hdr); | ||
454 | part_uv->heartbeat = msg->heartbeat; | ||
455 | |||
456 | spin_lock_irqsave(&part_uv->flags_lock, irq_flags); | ||
457 | part_uv->flags &= ~XPC_P_HEARTBEAT_OFFLINE_UV; | ||
458 | spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); | ||
459 | break; | ||
460 | } | ||
461 | case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: { | 425 | case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: { |
462 | struct xpc_activate_mq_msg_activate_req_uv *msg; | 426 | struct xpc_activate_mq_msg_activate_req_uv *msg; |
463 | 427 | ||
@@ -475,6 +439,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, | |||
475 | part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; | 439 | part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV; |
476 | part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ | 440 | part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */ |
477 | part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; | 441 | part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies; |
442 | part_uv->heartbeat_gpa = msg->heartbeat_gpa; | ||
478 | 443 | ||
479 | if (msg->activate_gru_mq_desc_gpa != | 444 | if (msg->activate_gru_mq_desc_gpa != |
480 | part_uv->activate_gru_mq_desc_gpa) { | 445 | part_uv->activate_gru_mq_desc_gpa) { |
@@ -569,6 +534,17 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, | |||
569 | xpc_wakeup_channel_mgr(part); | 534 | xpc_wakeup_channel_mgr(part); |
570 | break; | 535 | break; |
571 | } | 536 | } |
537 | case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: { | ||
538 | struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg; | ||
539 | |||
540 | msg = container_of(msg_hdr, struct | ||
541 | xpc_activate_mq_msg_chctl_opencomplete_uv, hdr); | ||
542 | spin_lock_irqsave(&part->chctl_lock, irq_flags); | ||
543 | part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE; | ||
544 | spin_unlock_irqrestore(&part->chctl_lock, irq_flags); | ||
545 | |||
546 | xpc_wakeup_channel_mgr(part); | ||
547 | } | ||
572 | case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV: | 548 | case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV: |
573 | spin_lock_irqsave(&part_uv->flags_lock, irq_flags); | 549 | spin_lock_irqsave(&part_uv->flags_lock, irq_flags); |
574 | part_uv->flags |= XPC_P_ENGAGED_UV; | 550 | part_uv->flags |= XPC_P_ENGAGED_UV; |
@@ -759,7 +735,7 @@ xpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req) | |||
759 | 735 | ||
760 | /* | 736 | /* |
761 | * !!! Make our side think that the remote partition sent an activate | 737 | * !!! Make our side think that the remote partition sent an activate |
762 | * !!! message our way by doing what the activate IRQ handler would | 738 | * !!! mq message our way by doing what the activate IRQ handler would |
763 | * !!! do had one really been sent. | 739 | * !!! do had one really been sent. |
764 | */ | 740 | */ |
765 | 741 | ||
@@ -806,90 +782,82 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa, | |||
806 | } | 782 | } |
807 | 783 | ||
808 | static int | 784 | static int |
809 | xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp) | 785 | xpc_setup_rsvd_page_uv(struct xpc_rsvd_page *rp) |
810 | { | 786 | { |
811 | rp->sn.activate_gru_mq_desc_gpa = | 787 | xpc_heartbeat_uv = |
788 | &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat; | ||
789 | rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv); | ||
790 | rp->sn.uv.activate_gru_mq_desc_gpa = | ||
812 | uv_gpa(xpc_activate_mq_uv->gru_mq_desc); | 791 | uv_gpa(xpc_activate_mq_uv->gru_mq_desc); |
813 | return 0; | 792 | return 0; |
814 | } | 793 | } |
815 | 794 | ||
816 | static void | 795 | static void |
817 | xpc_send_heartbeat_uv(int msg_type) | 796 | xpc_allow_hb_uv(short partid) |
818 | { | 797 | { |
819 | short partid; | 798 | } |
820 | struct xpc_partition *part; | ||
821 | struct xpc_activate_mq_msg_heartbeat_req_uv msg; | ||
822 | |||
823 | /* | ||
824 | * !!! On uv we're broadcasting a heartbeat message every 5 seconds. | ||
825 | * !!! Whereas on sn2 we're bte_copy'ng the heartbeat info every 20 | ||
826 | * !!! seconds. This is an increase in numalink traffic. | ||
827 | * ??? Is this good? | ||
828 | */ | ||
829 | |||
830 | msg.heartbeat = atomic64_inc_return(&xpc_heartbeat_uv); | ||
831 | |||
832 | partid = find_first_bit(xpc_heartbeating_to_mask_uv, | ||
833 | XP_MAX_NPARTITIONS_UV); | ||
834 | |||
835 | while (partid < XP_MAX_NPARTITIONS_UV) { | ||
836 | part = &xpc_partitions[partid]; | ||
837 | 799 | ||
838 | xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), | 800 | static void |
839 | msg_type); | 801 | xpc_disallow_hb_uv(short partid) |
802 | { | ||
803 | } | ||
840 | 804 | ||
841 | partid = find_next_bit(xpc_heartbeating_to_mask_uv, | 805 | static void |
842 | XP_MAX_NPARTITIONS_UV, partid + 1); | 806 | xpc_disallow_all_hbs_uv(void) |
843 | } | 807 | { |
844 | } | 808 | } |
845 | 809 | ||
846 | static void | 810 | static void |
847 | xpc_increment_heartbeat_uv(void) | 811 | xpc_increment_heartbeat_uv(void) |
848 | { | 812 | { |
849 | xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV); | 813 | xpc_heartbeat_uv->value++; |
850 | } | 814 | } |
851 | 815 | ||
852 | static void | 816 | static void |
853 | xpc_offline_heartbeat_uv(void) | 817 | xpc_offline_heartbeat_uv(void) |
854 | { | 818 | { |
855 | xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV); | 819 | xpc_increment_heartbeat_uv(); |
820 | xpc_heartbeat_uv->offline = 1; | ||
856 | } | 821 | } |
857 | 822 | ||
858 | static void | 823 | static void |
859 | xpc_online_heartbeat_uv(void) | 824 | xpc_online_heartbeat_uv(void) |
860 | { | 825 | { |
861 | xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV); | 826 | xpc_increment_heartbeat_uv(); |
827 | xpc_heartbeat_uv->offline = 0; | ||
862 | } | 828 | } |
863 | 829 | ||
864 | static void | 830 | static void |
865 | xpc_heartbeat_init_uv(void) | 831 | xpc_heartbeat_init_uv(void) |
866 | { | 832 | { |
867 | atomic64_set(&xpc_heartbeat_uv, 0); | 833 | xpc_heartbeat_uv->value = 1; |
868 | bitmap_zero(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV); | 834 | xpc_heartbeat_uv->offline = 0; |
869 | xpc_heartbeating_to_mask = &xpc_heartbeating_to_mask_uv[0]; | ||
870 | } | 835 | } |
871 | 836 | ||
872 | static void | 837 | static void |
873 | xpc_heartbeat_exit_uv(void) | 838 | xpc_heartbeat_exit_uv(void) |
874 | { | 839 | { |
875 | xpc_send_heartbeat_uv(XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV); | 840 | xpc_offline_heartbeat_uv(); |
876 | } | 841 | } |
877 | 842 | ||
878 | static enum xp_retval | 843 | static enum xp_retval |
879 | xpc_get_remote_heartbeat_uv(struct xpc_partition *part) | 844 | xpc_get_remote_heartbeat_uv(struct xpc_partition *part) |
880 | { | 845 | { |
881 | struct xpc_partition_uv *part_uv = &part->sn.uv; | 846 | struct xpc_partition_uv *part_uv = &part->sn.uv; |
882 | enum xp_retval ret = xpNoHeartbeat; | 847 | enum xp_retval ret; |
883 | 848 | ||
884 | if (part_uv->remote_act_state != XPC_P_AS_INACTIVE && | 849 | ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat), |
885 | part_uv->remote_act_state != XPC_P_AS_DEACTIVATING) { | 850 | part_uv->heartbeat_gpa, |
851 | sizeof(struct xpc_heartbeat_uv)); | ||
852 | if (ret != xpSuccess) | ||
853 | return ret; | ||
886 | 854 | ||
887 | if (part_uv->heartbeat != part->last_heartbeat || | 855 | if (part_uv->cached_heartbeat.value == part->last_heartbeat && |
888 | (part_uv->flags & XPC_P_HEARTBEAT_OFFLINE_UV)) { | 856 | !part_uv->cached_heartbeat.offline) { |
889 | 857 | ||
890 | part->last_heartbeat = part_uv->heartbeat; | 858 | ret = xpNoHeartbeat; |
891 | ret = xpSuccess; | 859 | } else { |
892 | } | 860 | part->last_heartbeat = part_uv->cached_heartbeat.value; |
893 | } | 861 | } |
894 | return ret; | 862 | return ret; |
895 | } | 863 | } |
@@ -904,8 +872,9 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp, | |||
904 | 872 | ||
905 | part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */ | 873 | part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */ |
906 | part->remote_rp_ts_jiffies = remote_rp->ts_jiffies; | 874 | part->remote_rp_ts_jiffies = remote_rp->ts_jiffies; |
875 | part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa; | ||
907 | part->sn.uv.activate_gru_mq_desc_gpa = | 876 | part->sn.uv.activate_gru_mq_desc_gpa = |
908 | remote_rp->sn.activate_gru_mq_desc_gpa; | 877 | remote_rp->sn.uv.activate_gru_mq_desc_gpa; |
909 | 878 | ||
910 | /* | 879 | /* |
911 | * ??? Is it a good idea to make this conditional on what is | 880 | * ??? Is it a good idea to make this conditional on what is |
@@ -913,8 +882,9 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp, | |||
913 | */ | 882 | */ |
914 | if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) { | 883 | if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) { |
915 | msg.rp_gpa = uv_gpa(xpc_rsvd_page); | 884 | msg.rp_gpa = uv_gpa(xpc_rsvd_page); |
885 | msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa; | ||
916 | msg.activate_gru_mq_desc_gpa = | 886 | msg.activate_gru_mq_desc_gpa = |
917 | xpc_rsvd_page->sn.activate_gru_mq_desc_gpa; | 887 | xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa; |
918 | xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), | 888 | xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg), |
919 | XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV); | 889 | XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV); |
920 | } | 890 | } |
@@ -1010,7 +980,7 @@ xpc_n_of_fifo_entries_uv(struct xpc_fifo_head_uv *head) | |||
1010 | * Setup the channel structures that are uv specific. | 980 | * Setup the channel structures that are uv specific. |
1011 | */ | 981 | */ |
1012 | static enum xp_retval | 982 | static enum xp_retval |
1013 | xpc_setup_ch_structures_sn_uv(struct xpc_partition *part) | 983 | xpc_setup_ch_structures_uv(struct xpc_partition *part) |
1014 | { | 984 | { |
1015 | struct xpc_channel_uv *ch_uv; | 985 | struct xpc_channel_uv *ch_uv; |
1016 | int ch_number; | 986 | int ch_number; |
@@ -1029,7 +999,7 @@ xpc_setup_ch_structures_sn_uv(struct xpc_partition *part) | |||
1029 | * Teardown the channel structures that are uv specific. | 999 | * Teardown the channel structures that are uv specific. |
1030 | */ | 1000 | */ |
1031 | static void | 1001 | static void |
1032 | xpc_teardown_ch_structures_sn_uv(struct xpc_partition *part) | 1002 | xpc_teardown_ch_structures_uv(struct xpc_partition *part) |
1033 | { | 1003 | { |
1034 | /* nothing needs to be done */ | 1004 | /* nothing needs to be done */ |
1035 | return; | 1005 | return; |
@@ -1243,6 +1213,16 @@ xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags) | |||
1243 | } | 1213 | } |
1244 | 1214 | ||
1245 | static void | 1215 | static void |
1216 | xpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags) | ||
1217 | { | ||
1218 | struct xpc_activate_mq_msg_chctl_opencomplete_uv msg; | ||
1219 | |||
1220 | msg.ch_number = ch->number; | ||
1221 | xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), | ||
1222 | XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV); | ||
1223 | } | ||
1224 | |||
1225 | static void | ||
1246 | xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) | 1226 | xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) |
1247 | { | 1227 | { |
1248 | unsigned long irq_flags; | 1228 | unsigned long irq_flags; |
@@ -1669,58 +1649,67 @@ xpc_received_payload_uv(struct xpc_channel *ch, void *payload) | |||
1669 | msg->hdr.msg_slot_number += ch->remote_nentries; | 1649 | msg->hdr.msg_slot_number += ch->remote_nentries; |
1670 | } | 1650 | } |
1671 | 1651 | ||
1652 | static struct xpc_arch_operations xpc_arch_ops_uv = { | ||
1653 | .setup_partitions = xpc_setup_partitions_uv, | ||
1654 | .teardown_partitions = xpc_teardown_partitions_uv, | ||
1655 | .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv, | ||
1656 | .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv, | ||
1657 | .setup_rsvd_page = xpc_setup_rsvd_page_uv, | ||
1658 | |||
1659 | .allow_hb = xpc_allow_hb_uv, | ||
1660 | .disallow_hb = xpc_disallow_hb_uv, | ||
1661 | .disallow_all_hbs = xpc_disallow_all_hbs_uv, | ||
1662 | .increment_heartbeat = xpc_increment_heartbeat_uv, | ||
1663 | .offline_heartbeat = xpc_offline_heartbeat_uv, | ||
1664 | .online_heartbeat = xpc_online_heartbeat_uv, | ||
1665 | .heartbeat_init = xpc_heartbeat_init_uv, | ||
1666 | .heartbeat_exit = xpc_heartbeat_exit_uv, | ||
1667 | .get_remote_heartbeat = xpc_get_remote_heartbeat_uv, | ||
1668 | |||
1669 | .request_partition_activation = | ||
1670 | xpc_request_partition_activation_uv, | ||
1671 | .request_partition_reactivation = | ||
1672 | xpc_request_partition_reactivation_uv, | ||
1673 | .request_partition_deactivation = | ||
1674 | xpc_request_partition_deactivation_uv, | ||
1675 | .cancel_partition_deactivation_request = | ||
1676 | xpc_cancel_partition_deactivation_request_uv, | ||
1677 | |||
1678 | .setup_ch_structures = xpc_setup_ch_structures_uv, | ||
1679 | .teardown_ch_structures = xpc_teardown_ch_structures_uv, | ||
1680 | |||
1681 | .make_first_contact = xpc_make_first_contact_uv, | ||
1682 | |||
1683 | .get_chctl_all_flags = xpc_get_chctl_all_flags_uv, | ||
1684 | .send_chctl_closerequest = xpc_send_chctl_closerequest_uv, | ||
1685 | .send_chctl_closereply = xpc_send_chctl_closereply_uv, | ||
1686 | .send_chctl_openrequest = xpc_send_chctl_openrequest_uv, | ||
1687 | .send_chctl_openreply = xpc_send_chctl_openreply_uv, | ||
1688 | .send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv, | ||
1689 | .process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv, | ||
1690 | |||
1691 | .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv, | ||
1692 | |||
1693 | .setup_msg_structures = xpc_setup_msg_structures_uv, | ||
1694 | .teardown_msg_structures = xpc_teardown_msg_structures_uv, | ||
1695 | |||
1696 | .indicate_partition_engaged = xpc_indicate_partition_engaged_uv, | ||
1697 | .indicate_partition_disengaged = xpc_indicate_partition_disengaged_uv, | ||
1698 | .assume_partition_disengaged = xpc_assume_partition_disengaged_uv, | ||
1699 | .partition_engaged = xpc_partition_engaged_uv, | ||
1700 | .any_partition_engaged = xpc_any_partition_engaged_uv, | ||
1701 | |||
1702 | .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv, | ||
1703 | .send_payload = xpc_send_payload_uv, | ||
1704 | .get_deliverable_payload = xpc_get_deliverable_payload_uv, | ||
1705 | .received_payload = xpc_received_payload_uv, | ||
1706 | .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, | ||
1707 | }; | ||
1708 | |||
1672 | int | 1709 | int |
1673 | xpc_init_uv(void) | 1710 | xpc_init_uv(void) |
1674 | { | 1711 | { |
1675 | xpc_setup_partitions_sn = xpc_setup_partitions_sn_uv; | 1712 | xpc_arch_ops = xpc_arch_ops_uv; |
1676 | xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_uv; | ||
1677 | xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv; | ||
1678 | xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv; | ||
1679 | xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv; | ||
1680 | xpc_increment_heartbeat = xpc_increment_heartbeat_uv; | ||
1681 | xpc_offline_heartbeat = xpc_offline_heartbeat_uv; | ||
1682 | xpc_online_heartbeat = xpc_online_heartbeat_uv; | ||
1683 | xpc_heartbeat_init = xpc_heartbeat_init_uv; | ||
1684 | xpc_heartbeat_exit = xpc_heartbeat_exit_uv; | ||
1685 | xpc_get_remote_heartbeat = xpc_get_remote_heartbeat_uv; | ||
1686 | |||
1687 | xpc_request_partition_activation = xpc_request_partition_activation_uv; | ||
1688 | xpc_request_partition_reactivation = | ||
1689 | xpc_request_partition_reactivation_uv; | ||
1690 | xpc_request_partition_deactivation = | ||
1691 | xpc_request_partition_deactivation_uv; | ||
1692 | xpc_cancel_partition_deactivation_request = | ||
1693 | xpc_cancel_partition_deactivation_request_uv; | ||
1694 | |||
1695 | xpc_setup_ch_structures_sn = xpc_setup_ch_structures_sn_uv; | ||
1696 | xpc_teardown_ch_structures_sn = xpc_teardown_ch_structures_sn_uv; | ||
1697 | |||
1698 | xpc_make_first_contact = xpc_make_first_contact_uv; | ||
1699 | |||
1700 | xpc_get_chctl_all_flags = xpc_get_chctl_all_flags_uv; | ||
1701 | xpc_send_chctl_closerequest = xpc_send_chctl_closerequest_uv; | ||
1702 | xpc_send_chctl_closereply = xpc_send_chctl_closereply_uv; | ||
1703 | xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_uv; | ||
1704 | xpc_send_chctl_openreply = xpc_send_chctl_openreply_uv; | ||
1705 | |||
1706 | xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv; | ||
1707 | |||
1708 | xpc_setup_msg_structures = xpc_setup_msg_structures_uv; | ||
1709 | xpc_teardown_msg_structures = xpc_teardown_msg_structures_uv; | ||
1710 | |||
1711 | xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_uv; | ||
1712 | xpc_indicate_partition_disengaged = | ||
1713 | xpc_indicate_partition_disengaged_uv; | ||
1714 | xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_uv; | ||
1715 | xpc_partition_engaged = xpc_partition_engaged_uv; | ||
1716 | xpc_any_partition_engaged = xpc_any_partition_engaged_uv; | ||
1717 | |||
1718 | xpc_n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv; | ||
1719 | xpc_process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv; | ||
1720 | xpc_send_payload = xpc_send_payload_uv; | ||
1721 | xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv; | ||
1722 | xpc_get_deliverable_payload = xpc_get_deliverable_payload_uv; | ||
1723 | xpc_received_payload = xpc_received_payload_uv; | ||
1724 | 1713 | ||
1725 | if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { | 1714 | if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { |
1726 | dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n", | 1715 | dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n", |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 7c5b257ce8e4..29acd06b1c39 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -332,7 +332,7 @@ static void cafe_select_chip(struct mtd_info *mtd, int chipnr) | |||
332 | cafe->ctl1 &= ~CTRL1_CHIPSELECT; | 332 | cafe->ctl1 &= ~CTRL1_CHIPSELECT; |
333 | } | 333 | } |
334 | 334 | ||
335 | static int cafe_nand_interrupt(int irq, void *id) | 335 | static irqreturn_t cafe_nand_interrupt(int irq, void *id) |
336 | { | 336 | { |
337 | struct mtd_info *mtd = id; | 337 | struct mtd_info *mtd = id; |
338 | struct cafe_priv *cafe = mtd->priv; | 338 | struct cafe_priv *cafe = mtd->priv; |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 29df398b7727..1fc45431a620 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -1383,6 +1383,11 @@ static void rtl8139_hw_start (struct net_device *dev) | |||
1383 | RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); | 1383 | RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); |
1384 | RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4))); | 1384 | RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4))); |
1385 | 1385 | ||
1386 | tp->cur_rx = 0; | ||
1387 | |||
1388 | /* init Rx ring buffer DMA address */ | ||
1389 | RTL_W32_F (RxBuf, tp->rx_ring_dma); | ||
1390 | |||
1386 | /* Must enable Tx/Rx before setting transfer thresholds! */ | 1391 | /* Must enable Tx/Rx before setting transfer thresholds! */ |
1387 | RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb); | 1392 | RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb); |
1388 | 1393 | ||
@@ -1390,8 +1395,6 @@ static void rtl8139_hw_start (struct net_device *dev) | |||
1390 | RTL_W32 (RxConfig, tp->rx_config); | 1395 | RTL_W32 (RxConfig, tp->rx_config); |
1391 | RTL_W32 (TxConfig, rtl8139_tx_config); | 1396 | RTL_W32 (TxConfig, rtl8139_tx_config); |
1392 | 1397 | ||
1393 | tp->cur_rx = 0; | ||
1394 | |||
1395 | rtl_check_media (dev, 1); | 1398 | rtl_check_media (dev, 1); |
1396 | 1399 | ||
1397 | if (tp->chipset >= CH_8139B) { | 1400 | if (tp->chipset >= CH_8139B) { |
@@ -1406,9 +1409,6 @@ static void rtl8139_hw_start (struct net_device *dev) | |||
1406 | /* Lock Config[01234] and BMCR register writes */ | 1409 | /* Lock Config[01234] and BMCR register writes */ |
1407 | RTL_W8 (Cfg9346, Cfg9346_Lock); | 1410 | RTL_W8 (Cfg9346, Cfg9346_Lock); |
1408 | 1411 | ||
1409 | /* init Rx ring buffer DMA address */ | ||
1410 | RTL_W32_F (RxBuf, tp->rx_ring_dma); | ||
1411 | |||
1412 | /* init Tx buffer DMA addresses */ | 1412 | /* init Tx buffer DMA addresses */ |
1413 | for (i = 0; i < NUM_TX_DESC; i++) | 1413 | for (i = 0; i < NUM_TX_DESC; i++) |
1414 | RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs)); | 1414 | RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs)); |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9e921544ba20..214a92d1ef75 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -28,9 +28,9 @@ if NETDEVICES | |||
28 | 28 | ||
29 | config COMPAT_NET_DEV_OPS | 29 | config COMPAT_NET_DEV_OPS |
30 | default y | 30 | default y |
31 | bool "Enable older network device API compatiablity" | 31 | bool "Enable older network device API compatibility" |
32 | ---help--- | 32 | ---help--- |
33 | This option enables kernel compatiability with older network devices | 33 | This option enables kernel compatibility with older network devices |
34 | that do not use net_device_ops interface. | 34 | that do not use net_device_ops interface. |
35 | 35 | ||
36 | If unsure, say Y. | 36 | If unsure, say Y. |
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index d0d0c2fee054..02f64d578641 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c | |||
@@ -692,6 +692,17 @@ static struct zorro_driver a2065_driver = { | |||
692 | .remove = __devexit_p(a2065_remove_one), | 692 | .remove = __devexit_p(a2065_remove_one), |
693 | }; | 693 | }; |
694 | 694 | ||
695 | static const struct net_device_ops lance_netdev_ops = { | ||
696 | .ndo_open = lance_open, | ||
697 | .ndo_stop = lance_close, | ||
698 | .ndo_start_xmit = lance_start_xmit, | ||
699 | .ndo_tx_timeout = lance_tx_timeout, | ||
700 | .ndo_set_multicast_list = lance_set_multicast, | ||
701 | .ndo_validate_addr = eth_validate_addr, | ||
702 | .ndo_change_mtu = eth_change_mtu, | ||
703 | .ndo_set_mac_address = eth_mac_addr, | ||
704 | }; | ||
705 | |||
695 | static int __devinit a2065_init_one(struct zorro_dev *z, | 706 | static int __devinit a2065_init_one(struct zorro_dev *z, |
696 | const struct zorro_device_id *ent) | 707 | const struct zorro_device_id *ent) |
697 | { | 708 | { |
@@ -753,12 +764,8 @@ static int __devinit a2065_init_one(struct zorro_dev *z, | |||
753 | priv->rx_ring_mod_mask = RX_RING_MOD_MASK; | 764 | priv->rx_ring_mod_mask = RX_RING_MOD_MASK; |
754 | priv->tx_ring_mod_mask = TX_RING_MOD_MASK; | 765 | priv->tx_ring_mod_mask = TX_RING_MOD_MASK; |
755 | 766 | ||
756 | dev->open = &lance_open; | 767 | dev->netdev_ops = &lance_netdev_ops; |
757 | dev->stop = &lance_close; | ||
758 | dev->hard_start_xmit = &lance_start_xmit; | ||
759 | dev->tx_timeout = &lance_tx_timeout; | ||
760 | dev->watchdog_timeo = 5*HZ; | 768 | dev->watchdog_timeo = 5*HZ; |
761 | dev->set_multicast_list = &lance_set_multicast; | ||
762 | dev->dma = 0; | 769 | dev->dma = 0; |
763 | 770 | ||
764 | init_timer(&priv->multicast_timer); | 771 | init_timer(&priv->multicast_timer); |
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index e1d72e06f3e1..58e8d522e5bc 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c | |||
@@ -155,6 +155,18 @@ static struct zorro_driver ariadne_driver = { | |||
155 | .remove = __devexit_p(ariadne_remove_one), | 155 | .remove = __devexit_p(ariadne_remove_one), |
156 | }; | 156 | }; |
157 | 157 | ||
158 | static const struct net_device_ops ariadne_netdev_ops = { | ||
159 | .ndo_open = ariadne_open, | ||
160 | .ndo_stop = ariadne_close, | ||
161 | .ndo_start_xmit = ariadne_start_xmit, | ||
162 | .ndo_tx_timeout = ariadne_tx_timeout, | ||
163 | .ndo_get_stats = ariadne_get_stats, | ||
164 | .ndo_set_multicast_list = set_multicast_list, | ||
165 | .ndo_validate_addr = eth_validate_addr, | ||
166 | .ndo_change_mtu = eth_change_mtu, | ||
167 | .ndo_set_mac_address = eth_mac_addr, | ||
168 | }; | ||
169 | |||
158 | static int __devinit ariadne_init_one(struct zorro_dev *z, | 170 | static int __devinit ariadne_init_one(struct zorro_dev *z, |
159 | const struct zorro_device_id *ent) | 171 | const struct zorro_device_id *ent) |
160 | { | 172 | { |
@@ -197,13 +209,8 @@ static int __devinit ariadne_init_one(struct zorro_dev *z, | |||
197 | dev->mem_start = ZTWO_VADDR(mem_start); | 209 | dev->mem_start = ZTWO_VADDR(mem_start); |
198 | dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE; | 210 | dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE; |
199 | 211 | ||
200 | dev->open = &ariadne_open; | 212 | dev->netdev_ops = &ariadne_netdev_ops; |
201 | dev->stop = &ariadne_close; | ||
202 | dev->hard_start_xmit = &ariadne_start_xmit; | ||
203 | dev->tx_timeout = &ariadne_tx_timeout; | ||
204 | dev->watchdog_timeo = 5*HZ; | 213 | dev->watchdog_timeo = 5*HZ; |
205 | dev->get_stats = &ariadne_get_stats; | ||
206 | dev->set_multicast_list = &set_multicast_list; | ||
207 | 214 | ||
208 | err = register_netdev(dev); | 215 | err = register_netdev(dev); |
209 | if (err) { | 216 | if (err) { |
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 4bc6901b3819..627bc75da17d 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c | |||
@@ -665,6 +665,20 @@ static void __init am79c961_banner(void) | |||
665 | if (net_debug && version_printed++ == 0) | 665 | if (net_debug && version_printed++ == 0) |
666 | printk(KERN_INFO "%s", version); | 666 | printk(KERN_INFO "%s", version); |
667 | } | 667 | } |
668 | static const struct net_device_ops am79c961_netdev_ops = { | ||
669 | .ndo_open = am79c961_open, | ||
670 | .ndo_stop = am79c961_close, | ||
671 | .ndo_start_xmit = am79c961_sendpacket, | ||
672 | .ndo_get_stats = am79c961_getstats, | ||
673 | .ndo_set_multicast_list = am79c961_setmulticastlist, | ||
674 | .ndo_tx_timeout = am79c961_timeout, | ||
675 | .ndo_validate_addr = eth_validate_addr, | ||
676 | .ndo_change_mtu = eth_change_mtu, | ||
677 | .ndo_set_mac_address = eth_mac_addr, | ||
678 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
679 | .ndo_poll_controller = am79c961_poll_controller, | ||
680 | #endif | ||
681 | }; | ||
668 | 682 | ||
669 | static int __init am79c961_probe(struct platform_device *pdev) | 683 | static int __init am79c961_probe(struct platform_device *pdev) |
670 | { | 684 | { |
@@ -732,15 +746,7 @@ static int __init am79c961_probe(struct platform_device *pdev) | |||
732 | if (am79c961_hw_init(dev)) | 746 | if (am79c961_hw_init(dev)) |
733 | goto release; | 747 | goto release; |
734 | 748 | ||
735 | dev->open = am79c961_open; | 749 | dev->netdev_ops = &am79c961_netdev_ops; |
736 | dev->stop = am79c961_close; | ||
737 | dev->hard_start_xmit = am79c961_sendpacket; | ||
738 | dev->get_stats = am79c961_getstats; | ||
739 | dev->set_multicast_list = am79c961_setmulticastlist; | ||
740 | dev->tx_timeout = am79c961_timeout; | ||
741 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
742 | dev->poll_controller = am79c961_poll_controller; | ||
743 | #endif | ||
744 | 750 | ||
745 | ret = register_netdev(dev); | 751 | ret = register_netdev(dev); |
746 | if (ret == 0) { | 752 | if (ret == 0) { |
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 442938d50380..7f4bc8ae5462 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c | |||
@@ -577,7 +577,7 @@ static void at91ether_sethashtable(struct net_device *dev) | |||
577 | /* | 577 | /* |
578 | * Enable/Disable promiscuous and multicast modes. | 578 | * Enable/Disable promiscuous and multicast modes. |
579 | */ | 579 | */ |
580 | static void at91ether_set_rx_mode(struct net_device *dev) | 580 | static void at91ether_set_multicast_list(struct net_device *dev) |
581 | { | 581 | { |
582 | unsigned long cfg; | 582 | unsigned long cfg; |
583 | 583 | ||
@@ -808,7 +808,7 @@ static int at91ether_close(struct net_device *dev) | |||
808 | /* | 808 | /* |
809 | * Transmit packet. | 809 | * Transmit packet. |
810 | */ | 810 | */ |
811 | static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) | 811 | static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev) |
812 | { | 812 | { |
813 | struct at91_private *lp = netdev_priv(dev); | 813 | struct at91_private *lp = netdev_priv(dev); |
814 | 814 | ||
@@ -828,7 +828,7 @@ static int at91ether_tx(struct sk_buff *skb, struct net_device *dev) | |||
828 | 828 | ||
829 | dev->trans_start = jiffies; | 829 | dev->trans_start = jiffies; |
830 | } else { | 830 | } else { |
831 | printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n"); | 831 | printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n"); |
832 | return 1; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb) | 832 | return 1; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb) |
833 | on this skb, he also reports -ENETDOWN and printk's, so either | 833 | on this skb, he also reports -ENETDOWN and printk's, so either |
834 | we free and return(0) or don't free and return 1 */ | 834 | we free and return(0) or don't free and return 1 */ |
@@ -965,6 +965,21 @@ static void at91ether_poll_controller(struct net_device *dev) | |||
965 | } | 965 | } |
966 | #endif | 966 | #endif |
967 | 967 | ||
968 | static const struct net_device_ops at91ether_netdev_ops = { | ||
969 | .ndo_open = at91ether_open, | ||
970 | .ndo_stop = at91ether_close, | ||
971 | .ndo_start_xmit = at91ether_start_xmit, | ||
972 | .ndo_get_stats = at91ether_stats, | ||
973 | .ndo_set_multicast_list = at91ether_set_multicast_list, | ||
974 | .ndo_set_mac_address = set_mac_address, | ||
975 | .ndo_do_ioctl = at91ether_ioctl, | ||
976 | .ndo_validate_addr = eth_validate_addr, | ||
977 | .ndo_change_mtu = eth_change_mtu, | ||
978 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
979 | .ndo_poll_controller = at91ether_poll_controller, | ||
980 | #endif | ||
981 | }; | ||
982 | |||
968 | /* | 983 | /* |
969 | * Initialize the ethernet interface | 984 | * Initialize the ethernet interface |
970 | */ | 985 | */ |
@@ -1005,17 +1020,8 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add | |||
1005 | spin_lock_init(&lp->lock); | 1020 | spin_lock_init(&lp->lock); |
1006 | 1021 | ||
1007 | ether_setup(dev); | 1022 | ether_setup(dev); |
1008 | dev->open = at91ether_open; | 1023 | dev->netdev_ops = &at91ether_netdev_ops; |
1009 | dev->stop = at91ether_close; | ||
1010 | dev->hard_start_xmit = at91ether_tx; | ||
1011 | dev->get_stats = at91ether_stats; | ||
1012 | dev->set_multicast_list = at91ether_set_rx_mode; | ||
1013 | dev->set_mac_address = set_mac_address; | ||
1014 | dev->ethtool_ops = &at91ether_ethtool_ops; | 1024 | dev->ethtool_ops = &at91ether_ethtool_ops; |
1015 | dev->do_ioctl = at91ether_ioctl; | ||
1016 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1017 | dev->poll_controller = at91ether_poll_controller; | ||
1018 | #endif | ||
1019 | 1025 | ||
1020 | SET_NETDEV_DEV(dev, &pdev->dev); | 1026 | SET_NETDEV_DEV(dev, &pdev->dev); |
1021 | 1027 | ||
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index cc7708775da0..b72b3d639f6e 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c | |||
@@ -153,7 +153,7 @@ struct ep93xx_descs | |||
153 | struct ep93xx_priv | 153 | struct ep93xx_priv |
154 | { | 154 | { |
155 | struct resource *res; | 155 | struct resource *res; |
156 | void *base_addr; | 156 | void __iomem *base_addr; |
157 | int irq; | 157 | int irq; |
158 | 158 | ||
159 | struct ep93xx_descs *descs; | 159 | struct ep93xx_descs *descs; |
@@ -770,7 +770,18 @@ static struct ethtool_ops ep93xx_ethtool_ops = { | |||
770 | .get_link = ep93xx_get_link, | 770 | .get_link = ep93xx_get_link, |
771 | }; | 771 | }; |
772 | 772 | ||
773 | struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) | 773 | static const struct net_device_ops ep93xx_netdev_ops = { |
774 | .ndo_open = ep93xx_open, | ||
775 | .ndo_stop = ep93xx_close, | ||
776 | .ndo_start_xmit = ep93xx_xmit, | ||
777 | .ndo_get_stats = ep93xx_get_stats, | ||
778 | .ndo_do_ioctl = ep93xx_ioctl, | ||
779 | .ndo_validate_addr = eth_validate_addr, | ||
780 | .ndo_change_mtu = eth_change_mtu, | ||
781 | .ndo_set_mac_address = eth_mac_addr, | ||
782 | }; | ||
783 | |||
784 | static struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) | ||
774 | { | 785 | { |
775 | struct net_device *dev; | 786 | struct net_device *dev; |
776 | 787 | ||
@@ -780,12 +791,8 @@ struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data) | |||
780 | 791 | ||
781 | memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN); | 792 | memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN); |
782 | 793 | ||
783 | dev->get_stats = ep93xx_get_stats; | ||
784 | dev->ethtool_ops = &ep93xx_ethtool_ops; | 794 | dev->ethtool_ops = &ep93xx_ethtool_ops; |
785 | dev->hard_start_xmit = ep93xx_xmit; | 795 | dev->netdev_ops = &ep93xx_netdev_ops; |
786 | dev->open = ep93xx_open; | ||
787 | dev->stop = ep93xx_close; | ||
788 | dev->do_ioctl = ep93xx_ioctl; | ||
789 | 796 | ||
790 | dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; | 797 | dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; |
791 | 798 | ||
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index e380de454463..edf770f639fa 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c | |||
@@ -991,6 +991,18 @@ static void __devinit ether1_banner(void) | |||
991 | printk(KERN_INFO "%s", version); | 991 | printk(KERN_INFO "%s", version); |
992 | } | 992 | } |
993 | 993 | ||
994 | static const struct net_device_ops ether1_netdev_ops = { | ||
995 | .ndo_open = ether1_open, | ||
996 | .ndo_stop = ether1_close, | ||
997 | .ndo_start_xmit = ether1_sendpacket, | ||
998 | .ndo_get_stats = ether1_getstats, | ||
999 | .ndo_set_multicast_list = ether1_setmulticastlist, | ||
1000 | .ndo_tx_timeout = ether1_timeout, | ||
1001 | .ndo_validate_addr = eth_validate_addr, | ||
1002 | .ndo_change_mtu = eth_change_mtu, | ||
1003 | .ndo_set_mac_address = eth_mac_addr, | ||
1004 | }; | ||
1005 | |||
994 | static int __devinit | 1006 | static int __devinit |
995 | ether1_probe(struct expansion_card *ec, const struct ecard_id *id) | 1007 | ether1_probe(struct expansion_card *ec, const struct ecard_id *id) |
996 | { | 1008 | { |
@@ -1031,12 +1043,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
1031 | goto free; | 1043 | goto free; |
1032 | } | 1044 | } |
1033 | 1045 | ||
1034 | dev->open = ether1_open; | 1046 | dev->netdev_ops = ðer1_netdev_ops; |
1035 | dev->stop = ether1_close; | ||
1036 | dev->hard_start_xmit = ether1_sendpacket; | ||
1037 | dev->get_stats = ether1_getstats; | ||
1038 | dev->set_multicast_list = ether1_setmulticastlist; | ||
1039 | dev->tx_timeout = ether1_timeout; | ||
1040 | dev->watchdog_timeo = 5 * HZ / 100; | 1047 | dev->watchdog_timeo = 5 * HZ / 100; |
1041 | 1048 | ||
1042 | ret = register_netdev(dev); | 1049 | ret = register_netdev(dev); |
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index 21a7bef12d3b..ec8a1ae1e887 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c | |||
@@ -770,6 +770,18 @@ static void __devinit ether3_banner(void) | |||
770 | printk(KERN_INFO "%s", version); | 770 | printk(KERN_INFO "%s", version); |
771 | } | 771 | } |
772 | 772 | ||
773 | static const struct net_device_ops ether3_netdev_ops = { | ||
774 | .ndo_open = ether3_open, | ||
775 | .ndo_stop = ether3_close, | ||
776 | .ndo_start_xmit = ether3_sendpacket, | ||
777 | .ndo_get_stats = ether3_getstats, | ||
778 | .ndo_set_multicast_list = ether3_setmulticastlist, | ||
779 | .ndo_tx_timeout = ether3_timeout, | ||
780 | .ndo_validate_addr = eth_validate_addr, | ||
781 | .ndo_change_mtu = eth_change_mtu, | ||
782 | .ndo_set_mac_address = eth_mac_addr, | ||
783 | }; | ||
784 | |||
773 | static int __devinit | 785 | static int __devinit |
774 | ether3_probe(struct expansion_card *ec, const struct ecard_id *id) | 786 | ether3_probe(struct expansion_card *ec, const struct ecard_id *id) |
775 | { | 787 | { |
@@ -846,12 +858,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
846 | goto free; | 858 | goto free; |
847 | } | 859 | } |
848 | 860 | ||
849 | dev->open = ether3_open; | 861 | dev->netdev_ops = ðer3_netdev_ops; |
850 | dev->stop = ether3_close; | ||
851 | dev->hard_start_xmit = ether3_sendpacket; | ||
852 | dev->get_stats = ether3_getstats; | ||
853 | dev->set_multicast_list = ether3_setmulticastlist; | ||
854 | dev->tx_timeout = ether3_timeout; | ||
855 | dev->watchdog_timeo = 5 * HZ / 100; | 862 | dev->watchdog_timeo = 5 * HZ / 100; |
856 | 863 | ||
857 | ret = register_netdev(dev); | 864 | ret = register_netdev(dev); |
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 2d81f6afcb58..5425ab0c38c0 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c | |||
@@ -453,6 +453,16 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag, | |||
453 | return( ret ); | 453 | return( ret ); |
454 | } | 454 | } |
455 | 455 | ||
456 | static const struct net_device_ops lance_netdev_ops = { | ||
457 | .ndo_open = lance_open, | ||
458 | .ndo_stop = lance_close, | ||
459 | .ndo_start_xmit = lance_start_xmit, | ||
460 | .ndo_set_multicast_list = set_multicast_list, | ||
461 | .ndo_set_mac_address = lance_set_mac_address, | ||
462 | .ndo_tx_timeout = lance_tx_timeout, | ||
463 | .ndo_validate_addr = eth_validate_addr, | ||
464 | .ndo_change_mtu = eth_change_mtu, | ||
465 | }; | ||
456 | 466 | ||
457 | static unsigned long __init lance_probe1( struct net_device *dev, | 467 | static unsigned long __init lance_probe1( struct net_device *dev, |
458 | struct lance_addr *init_rec ) | 468 | struct lance_addr *init_rec ) |
@@ -623,15 +633,9 @@ static unsigned long __init lance_probe1( struct net_device *dev, | |||
623 | if (did_version++ == 0) | 633 | if (did_version++ == 0) |
624 | DPRINTK( 1, ( version )); | 634 | DPRINTK( 1, ( version )); |
625 | 635 | ||
626 | /* The LANCE-specific entries in the device structure. */ | 636 | dev->netdev_ops = &lance_netdev_ops; |
627 | dev->open = &lance_open; | ||
628 | dev->hard_start_xmit = &lance_start_xmit; | ||
629 | dev->stop = &lance_close; | ||
630 | dev->set_multicast_list = &set_multicast_list; | ||
631 | dev->set_mac_address = &lance_set_mac_address; | ||
632 | 637 | ||
633 | /* XXX MSch */ | 638 | /* XXX MSch */ |
634 | dev->tx_timeout = lance_tx_timeout; | ||
635 | dev->watchdog_timeo = TX_TIMEOUT; | 639 | dev->watchdog_timeo = TX_TIMEOUT; |
636 | 640 | ||
637 | return( 1 ); | 641 | return( 1 ); |
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index deb7b53167ee..83a12125b94e 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
@@ -2532,8 +2532,8 @@ static int __devinit atl1c_probe(struct pci_dev *pdev, | |||
2532 | * various kernel subsystems to support the mechanics required by a | 2532 | * various kernel subsystems to support the mechanics required by a |
2533 | * fixed-high-32-bit system. | 2533 | * fixed-high-32-bit system. |
2534 | */ | 2534 | */ |
2535 | if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) || | 2535 | if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) || |
2536 | (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) { | 2536 | (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) { |
2537 | dev_err(&pdev->dev, "No usable DMA configuration,aborting\n"); | 2537 | dev_err(&pdev->dev, "No usable DMA configuration,aborting\n"); |
2538 | goto err_dma; | 2538 | goto err_dma; |
2539 | } | 2539 | } |
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 4274e4ac963b..d58c105fc779 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -1004,12 +1004,12 @@ static void au1000_tx_timeout(struct net_device *dev) | |||
1004 | netif_wake_queue(dev); | 1004 | netif_wake_queue(dev); |
1005 | } | 1005 | } |
1006 | 1006 | ||
1007 | static void set_rx_mode(struct net_device *dev) | 1007 | static void au1000_multicast_list(struct net_device *dev) |
1008 | { | 1008 | { |
1009 | struct au1000_private *aup = netdev_priv(dev); | 1009 | struct au1000_private *aup = netdev_priv(dev); |
1010 | 1010 | ||
1011 | if (au1000_debug > 4) | 1011 | if (au1000_debug > 4) |
1012 | printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags); | 1012 | printk("%s: au1000_multicast_list: flags=%x\n", dev->name, dev->flags); |
1013 | 1013 | ||
1014 | if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ | 1014 | if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ |
1015 | aup->mac->control |= MAC_PROMISCUOUS; | 1015 | aup->mac->control |= MAC_PROMISCUOUS; |
@@ -1047,6 +1047,18 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
1047 | return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); | 1047 | return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | static const struct net_device_ops au1000_netdev_ops = { | ||
1051 | .ndo_open = au1000_open, | ||
1052 | .ndo_stop = au1000_close, | ||
1053 | .ndo_start_xmit = au1000_tx, | ||
1054 | .ndo_set_multicast_list = au1000_multicast_list, | ||
1055 | .ndo_do_ioctl = au1000_ioctl, | ||
1056 | .ndo_tx_timeout = au1000_tx_timeout, | ||
1057 | .ndo_set_mac_address = eth_mac_addr, | ||
1058 | .ndo_validate_addr = eth_validate_addr, | ||
1059 | .ndo_change_mtu = eth_change_mtu, | ||
1060 | }; | ||
1061 | |||
1050 | static struct net_device * au1000_probe(int port_num) | 1062 | static struct net_device * au1000_probe(int port_num) |
1051 | { | 1063 | { |
1052 | static unsigned version_printed = 0; | 1064 | static unsigned version_printed = 0; |
@@ -1197,13 +1209,8 @@ static struct net_device * au1000_probe(int port_num) | |||
1197 | 1209 | ||
1198 | dev->base_addr = base; | 1210 | dev->base_addr = base; |
1199 | dev->irq = irq; | 1211 | dev->irq = irq; |
1200 | dev->open = au1000_open; | 1212 | dev->netdev_ops = &au1000_netdev_ops; |
1201 | dev->hard_start_xmit = au1000_tx; | ||
1202 | dev->stop = au1000_close; | ||
1203 | dev->set_multicast_list = &set_rx_mode; | ||
1204 | dev->do_ioctl = &au1000_ioctl; | ||
1205 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | 1213 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); |
1206 | dev->tx_timeout = au1000_tx_timeout; | ||
1207 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | 1214 | dev->watchdog_timeo = ETH_TX_TIMEOUT; |
1208 | 1215 | ||
1209 | /* | 1216 | /* |
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 04f4b73fa8d8..9592f22e4c8c 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -319,7 +319,7 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) | |||
319 | 319 | ||
320 | be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause, | 320 | be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause, |
321 | &ecmd->rx_pause); | 321 | &ecmd->rx_pause); |
322 | ecmd->autoneg = AUTONEG_ENABLE; | 322 | ecmd->autoneg = 0; |
323 | } | 323 | } |
324 | 324 | ||
325 | static int | 325 | static int |
@@ -328,7 +328,7 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd) | |||
328 | struct be_adapter *adapter = netdev_priv(netdev); | 328 | struct be_adapter *adapter = netdev_priv(netdev); |
329 | int status; | 329 | int status; |
330 | 330 | ||
331 | if (ecmd->autoneg != AUTONEG_ENABLE) | 331 | if (ecmd->autoneg != 0) |
332 | return -EINVAL; | 332 | return -EINVAL; |
333 | 333 | ||
334 | status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause, | 334 | status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause, |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 9b75aa630062..30d0c81c989e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -1821,11 +1821,11 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
1821 | 1821 | ||
1822 | be_msix_enable(adapter); | 1822 | be_msix_enable(adapter); |
1823 | 1823 | ||
1824 | status = pci_set_dma_mask(pdev, DMA_64BIT_MASK); | 1824 | status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); |
1825 | if (!status) { | 1825 | if (!status) { |
1826 | netdev->features |= NETIF_F_HIGHDMA; | 1826 | netdev->features |= NETIF_F_HIGHDMA; |
1827 | } else { | 1827 | } else { |
1828 | status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 1828 | status = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
1829 | if (status) { | 1829 | if (status) { |
1830 | dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); | 1830 | dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); |
1831 | goto free_netdev; | 1831 | goto free_netdev; |
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 9afe8092dfc4..9f971ed6b58d 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
@@ -979,6 +979,20 @@ static int bfin_mac_open(struct net_device *dev) | |||
979 | return 0; | 979 | return 0; |
980 | } | 980 | } |
981 | 981 | ||
982 | static const struct net_device_ops bfin_mac_netdev_ops = { | ||
983 | .ndo_open = bfin_mac_open, | ||
984 | .ndo_stop = bfin_mac_close, | ||
985 | .ndo_start_xmit = bfin_mac_hard_start_xmit, | ||
986 | .ndo_set_mac_address = bfin_mac_set_mac_address, | ||
987 | .ndo_tx_timeout = bfin_mac_timeout, | ||
988 | .ndo_set_multicast_list = bfin_mac_set_multicast_list, | ||
989 | .ndo_validate_addr = eth_validate_addr, | ||
990 | .ndo_change_mtu = eth_change_mtu, | ||
991 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
992 | .ndo_poll_controller = bfin_mac_poll, | ||
993 | #endif | ||
994 | }; | ||
995 | |||
982 | /* | 996 | /* |
983 | * | 997 | * |
984 | * this makes the board clean up everything that it can | 998 | * this makes the board clean up everything that it can |
@@ -1086,15 +1100,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) | |||
1086 | /* Fill in the fields of the device structure with ethernet values. */ | 1100 | /* Fill in the fields of the device structure with ethernet values. */ |
1087 | ether_setup(ndev); | 1101 | ether_setup(ndev); |
1088 | 1102 | ||
1089 | ndev->open = bfin_mac_open; | 1103 | ndev->netdev_ops = &bfin_mac_netdev_ops; |
1090 | ndev->stop = bfin_mac_close; | ||
1091 | ndev->hard_start_xmit = bfin_mac_hard_start_xmit; | ||
1092 | ndev->set_mac_address = bfin_mac_set_mac_address; | ||
1093 | ndev->tx_timeout = bfin_mac_timeout; | ||
1094 | ndev->set_multicast_list = bfin_mac_set_multicast_list; | ||
1095 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1096 | ndev->poll_controller = bfin_mac_poll; | ||
1097 | #endif | ||
1098 | ndev->ethtool_ops = &bfin_mac_ethtool_ops; | 1104 | ndev->ethtool_ops = &bfin_mac_ethtool_ops; |
1099 | 1105 | ||
1100 | spin_lock_init(&lp->lock); | 1106 | spin_lock_init(&lp->lock); |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 8dc6fbb9a41e..553a89919778 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -370,8 +370,6 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct | |||
370 | 370 | ||
371 | if (arp->op_code == htons(ARPOP_REPLY)) { | 371 | if (arp->op_code == htons(ARPOP_REPLY)) { |
372 | /* update rx hash table for this ARP */ | 372 | /* update rx hash table for this ARP */ |
373 | printk("rar: update orig %s bond_dev %s\n", orig_dev->name, | ||
374 | bond_dev->name); | ||
375 | bond = netdev_priv(bond_dev); | 373 | bond = netdev_priv(bond_dev); |
376 | rlb_update_entry_from_arp(bond, arp); | 374 | rlb_update_entry_from_arp(bond, arp); |
377 | pr_debug("Server received an ARP Reply from client\n"); | 375 | pr_debug("Server received an ARP Reply from client\n"); |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 99610f358c40..63369b6b14d4 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2570,7 +2570,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2570 | 2570 | ||
2571 | for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { | 2571 | for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { |
2572 | if (!targets[i]) | 2572 | if (!targets[i]) |
2573 | continue; | 2573 | break; |
2574 | pr_debug("basa: target %x\n", targets[i]); | 2574 | pr_debug("basa: target %x\n", targets[i]); |
2575 | if (list_empty(&bond->vlan_list)) { | 2575 | if (list_empty(&bond->vlan_list)) { |
2576 | pr_debug("basa: empty vlan: arp_send\n"); | 2576 | pr_debug("basa: empty vlan: arp_send\n"); |
@@ -2677,7 +2677,6 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 | |||
2677 | int i; | 2677 | int i; |
2678 | __be32 *targets = bond->params.arp_targets; | 2678 | __be32 *targets = bond->params.arp_targets; |
2679 | 2679 | ||
2680 | targets = bond->params.arp_targets; | ||
2681 | for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { | 2680 | for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { |
2682 | pr_debug("bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d\n", | 2681 | pr_debug("bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d\n", |
2683 | &sip, &tip, i, &targets[i], bond_has_this_ip(bond, tip)); | 2682 | &sip, &tip, i, &targets[i], bond_has_this_ip(bond, tip)); |
@@ -3303,7 +3302,7 @@ static void bond_info_show_master(struct seq_file *seq) | |||
3303 | 3302 | ||
3304 | for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) { | 3303 | for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) { |
3305 | if (!bond->params.arp_targets[i]) | 3304 | if (!bond->params.arp_targets[i]) |
3306 | continue; | 3305 | break; |
3307 | if (printed) | 3306 | if (printed) |
3308 | seq_printf(seq, ","); | 3307 | seq_printf(seq, ","); |
3309 | seq_printf(seq, " %pI4", &bond->params.arp_targets[i]); | 3308 | seq_printf(seq, " %pI4", &bond->params.arp_targets[i]); |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 18cf4787874c..d28731535226 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -684,17 +684,15 @@ static ssize_t bonding_store_arp_targets(struct device *d, | |||
684 | goto out; | 684 | goto out; |
685 | } | 685 | } |
686 | /* look for an empty slot to put the target in, and check for dupes */ | 686 | /* look for an empty slot to put the target in, and check for dupes */ |
687 | for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { | 687 | for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) { |
688 | if (targets[i] == newtarget) { /* duplicate */ | 688 | if (targets[i] == newtarget) { /* duplicate */ |
689 | printk(KERN_ERR DRV_NAME | 689 | printk(KERN_ERR DRV_NAME |
690 | ": %s: ARP target %pI4 is already present\n", | 690 | ": %s: ARP target %pI4 is already present\n", |
691 | bond->dev->name, &newtarget); | 691 | bond->dev->name, &newtarget); |
692 | if (done) | ||
693 | targets[i] = 0; | ||
694 | ret = -EINVAL; | 692 | ret = -EINVAL; |
695 | goto out; | 693 | goto out; |
696 | } | 694 | } |
697 | if (targets[i] == 0 && !done) { | 695 | if (targets[i] == 0) { |
698 | printk(KERN_INFO DRV_NAME | 696 | printk(KERN_INFO DRV_NAME |
699 | ": %s: adding ARP target %pI4.\n", | 697 | ": %s: adding ARP target %pI4.\n", |
700 | bond->dev->name, &newtarget); | 698 | bond->dev->name, &newtarget); |
@@ -720,12 +718,16 @@ static ssize_t bonding_store_arp_targets(struct device *d, | |||
720 | goto out; | 718 | goto out; |
721 | } | 719 | } |
722 | 720 | ||
723 | for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { | 721 | for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) { |
724 | if (targets[i] == newtarget) { | 722 | if (targets[i] == newtarget) { |
723 | int j; | ||
725 | printk(KERN_INFO DRV_NAME | 724 | printk(KERN_INFO DRV_NAME |
726 | ": %s: removing ARP target %pI4.\n", | 725 | ": %s: removing ARP target %pI4.\n", |
727 | bond->dev->name, &newtarget); | 726 | bond->dev->name, &newtarget); |
728 | targets[i] = 0; | 727 | for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++) |
728 | targets[j] = targets[j+1]; | ||
729 | |||
730 | targets[j] = 0; | ||
729 | done = 1; | 731 | done = 1; |
730 | } | 732 | } |
731 | } | 733 | } |
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index c9806c58b2fd..7a18dc7e5c7f 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c | |||
@@ -257,6 +257,23 @@ struct transceiver_ops transceivers[] = | |||
257 | 257 | ||
258 | struct transceiver_ops* transceiver = &transceivers[0]; | 258 | struct transceiver_ops* transceiver = &transceivers[0]; |
259 | 259 | ||
260 | static const struct net_device_ops e100_netdev_ops = { | ||
261 | .ndo_open = e100_open, | ||
262 | .ndo_stop = e100_close, | ||
263 | .ndo_start_xmit = e100_send_packet, | ||
264 | .ndo_tx_timeout = e100_tx_timeout, | ||
265 | .ndo_get_stats = e100_get_stats, | ||
266 | .ndo_set_multicast_list = set_multicast_list, | ||
267 | .ndo_do_ioctl = e100_ioctl, | ||
268 | .ndo_set_mac_address = e100_set_mac_address, | ||
269 | .ndo_validate_addr = eth_validate_addr, | ||
270 | .ndo_change_mtu = eth_change_mtu, | ||
271 | .ndo_set_config = e100_set_config, | ||
272 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
273 | .ndo_poll_controller = e100_netpoll, | ||
274 | #endif | ||
275 | }; | ||
276 | |||
260 | #define tx_done(dev) (*R_DMA_CH0_CMD == 0) | 277 | #define tx_done(dev) (*R_DMA_CH0_CMD == 0) |
261 | 278 | ||
262 | /* | 279 | /* |
@@ -300,19 +317,8 @@ etrax_ethernet_init(void) | |||
300 | 317 | ||
301 | /* fill in our handlers so the network layer can talk to us in the future */ | 318 | /* fill in our handlers so the network layer can talk to us in the future */ |
302 | 319 | ||
303 | dev->open = e100_open; | ||
304 | dev->hard_start_xmit = e100_send_packet; | ||
305 | dev->stop = e100_close; | ||
306 | dev->get_stats = e100_get_stats; | ||
307 | dev->set_multicast_list = set_multicast_list; | ||
308 | dev->set_mac_address = e100_set_mac_address; | ||
309 | dev->ethtool_ops = &e100_ethtool_ops; | 320 | dev->ethtool_ops = &e100_ethtool_ops; |
310 | dev->do_ioctl = e100_ioctl; | 321 | dev->netdev_ops = &e100_netdev_ops; |
311 | dev->set_config = e100_set_config; | ||
312 | dev->tx_timeout = e100_tx_timeout; | ||
313 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
314 | dev->poll_controller = e100_netpoll; | ||
315 | #endif | ||
316 | 322 | ||
317 | spin_lock_init(&np->lock); | 323 | spin_lock_init(&np->lock); |
318 | spin_lock_init(&np->led_lock); | 324 | spin_lock_init(&np->led_lock); |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index ab0e5febef83..7ea48414c6cb 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -1117,8 +1117,8 @@ static void cxgb_down(struct adapter *adapter) | |||
1117 | spin_unlock_irq(&adapter->work_lock); | 1117 | spin_unlock_irq(&adapter->work_lock); |
1118 | 1118 | ||
1119 | free_irq_resources(adapter); | 1119 | free_irq_resources(adapter); |
1120 | flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ | ||
1121 | quiesce_rx(adapter); | 1120 | quiesce_rx(adapter); |
1121 | flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ | ||
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | static void schedule_chk_task(struct adapter *adap) | 1124 | static void schedule_chk_task(struct adapter *adap) |
@@ -1187,6 +1187,9 @@ static int offload_close(struct t3cdev *tdev) | |||
1187 | 1187 | ||
1188 | sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group); | 1188 | sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group); |
1189 | 1189 | ||
1190 | /* Flush work scheduled while releasing TIDs */ | ||
1191 | flush_scheduled_work(); | ||
1192 | |||
1190 | tdev->lldev = NULL; | 1193 | tdev->lldev = NULL; |
1191 | cxgb3_set_dummy_ops(tdev); | 1194 | cxgb3_set_dummy_ops(tdev); |
1192 | t3_tp_set_offload_mode(adapter, 0); | 1195 | t3_tp_set_offload_mode(adapter, 0); |
@@ -1232,6 +1235,10 @@ static int cxgb_close(struct net_device *dev) | |||
1232 | struct port_info *pi = netdev_priv(dev); | 1235 | struct port_info *pi = netdev_priv(dev); |
1233 | struct adapter *adapter = pi->adapter; | 1236 | struct adapter *adapter = pi->adapter; |
1234 | 1237 | ||
1238 | |||
1239 | if (!adapter->open_device_map) | ||
1240 | return 0; | ||
1241 | |||
1235 | /* Stop link fault interrupts */ | 1242 | /* Stop link fault interrupts */ |
1236 | t3_xgm_intr_disable(adapter, pi->port_id); | 1243 | t3_xgm_intr_disable(adapter, pi->port_id); |
1237 | t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); | 1244 | t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); |
@@ -1247,8 +1254,7 @@ static int cxgb_close(struct net_device *dev) | |||
1247 | spin_unlock_irq(&adapter->work_lock); | 1254 | spin_unlock_irq(&adapter->work_lock); |
1248 | 1255 | ||
1249 | if (!(adapter->open_device_map & PORT_MASK)) | 1256 | if (!(adapter->open_device_map & PORT_MASK)) |
1250 | cancel_rearming_delayed_workqueue(cxgb3_wq, | 1257 | cancel_delayed_work_sync(&adapter->adap_check_task); |
1251 | &adapter->adap_check_task); | ||
1252 | 1258 | ||
1253 | if (!adapter->open_device_map) | 1259 | if (!adapter->open_device_map) |
1254 | cxgb_down(adapter); | 1260 | cxgb_down(adapter); |
@@ -2493,6 +2499,7 @@ static void check_link_status(struct adapter *adapter) | |||
2493 | 2499 | ||
2494 | spin_lock_irq(&adapter->work_lock); | 2500 | spin_lock_irq(&adapter->work_lock); |
2495 | if (p->link_fault) { | 2501 | if (p->link_fault) { |
2502 | t3_link_fault(adapter, i); | ||
2496 | spin_unlock_irq(&adapter->work_lock); | 2503 | spin_unlock_irq(&adapter->work_lock); |
2497 | continue; | 2504 | continue; |
2498 | } | 2505 | } |
@@ -2554,9 +2561,7 @@ static void t3_adap_check_task(struct work_struct *work) | |||
2554 | 2561 | ||
2555 | adapter->check_task_cnt++; | 2562 | adapter->check_task_cnt++; |
2556 | 2563 | ||
2557 | /* Check link status for PHYs without interrupts */ | 2564 | check_link_status(adapter); |
2558 | if (p->linkpoll_period) | ||
2559 | check_link_status(adapter); | ||
2560 | 2565 | ||
2561 | /* Accumulate MAC stats if needed */ | 2566 | /* Accumulate MAC stats if needed */ |
2562 | if (!p->linkpoll_period || | 2567 | if (!p->linkpoll_period || |
@@ -2680,21 +2685,6 @@ void t3_os_ext_intr_handler(struct adapter *adapter) | |||
2680 | spin_unlock(&adapter->work_lock); | 2685 | spin_unlock(&adapter->work_lock); |
2681 | } | 2686 | } |
2682 | 2687 | ||
2683 | static void link_fault_task(struct work_struct *work) | ||
2684 | { | ||
2685 | struct adapter *adapter = container_of(work, struct adapter, | ||
2686 | link_fault_handler_task); | ||
2687 | int i; | ||
2688 | |||
2689 | for_each_port(adapter, i) { | ||
2690 | struct net_device *netdev = adapter->port[i]; | ||
2691 | struct port_info *pi = netdev_priv(netdev); | ||
2692 | |||
2693 | if (pi->link_fault) | ||
2694 | t3_link_fault(adapter, i); | ||
2695 | } | ||
2696 | } | ||
2697 | |||
2698 | void t3_os_link_fault_handler(struct adapter *adapter, int port_id) | 2688 | void t3_os_link_fault_handler(struct adapter *adapter, int port_id) |
2699 | { | 2689 | { |
2700 | struct net_device *netdev = adapter->port[port_id]; | 2690 | struct net_device *netdev = adapter->port[port_id]; |
@@ -2702,7 +2692,6 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id) | |||
2702 | 2692 | ||
2703 | spin_lock(&adapter->work_lock); | 2693 | spin_lock(&adapter->work_lock); |
2704 | pi->link_fault = 1; | 2694 | pi->link_fault = 1; |
2705 | queue_work(cxgb3_wq, &adapter->link_fault_handler_task); | ||
2706 | spin_unlock(&adapter->work_lock); | 2695 | spin_unlock(&adapter->work_lock); |
2707 | } | 2696 | } |
2708 | 2697 | ||
@@ -2838,6 +2827,9 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, | |||
2838 | struct adapter *adapter = pci_get_drvdata(pdev); | 2827 | struct adapter *adapter = pci_get_drvdata(pdev); |
2839 | int ret; | 2828 | int ret; |
2840 | 2829 | ||
2830 | if (state == pci_channel_io_perm_failure) | ||
2831 | return PCI_ERS_RESULT_DISCONNECT; | ||
2832 | |||
2841 | ret = t3_adapter_error(adapter, 0); | 2833 | ret = t3_adapter_error(adapter, 0); |
2842 | 2834 | ||
2843 | /* Request a slot reset. */ | 2835 | /* Request a slot reset. */ |
@@ -2932,8 +2924,13 @@ static int __devinit cxgb_enable_msix(struct adapter *adap) | |||
2932 | while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0) | 2924 | while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0) |
2933 | vectors = err; | 2925 | vectors = err; |
2934 | 2926 | ||
2935 | if (!err && vectors < (adap->params.nports + 1)) | 2927 | if (err < 0) |
2928 | pci_disable_msix(adap->pdev); | ||
2929 | |||
2930 | if (!err && vectors < (adap->params.nports + 1)) { | ||
2931 | pci_disable_msix(adap->pdev); | ||
2936 | err = -1; | 2932 | err = -1; |
2933 | } | ||
2937 | 2934 | ||
2938 | if (!err) { | 2935 | if (!err) { |
2939 | for (i = 0; i < vectors; ++i) | 2936 | for (i = 0; i < vectors; ++i) |
@@ -3082,7 +3079,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3082 | 3079 | ||
3083 | INIT_LIST_HEAD(&adapter->adapter_list); | 3080 | INIT_LIST_HEAD(&adapter->adapter_list); |
3084 | INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); | 3081 | INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); |
3085 | INIT_WORK(&adapter->link_fault_handler_task, link_fault_task); | ||
3086 | INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task); | 3082 | INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task); |
3087 | INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); | 3083 | INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); |
3088 | 3084 | ||
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 31ed31a3428b..e1bd690ff831 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -1202,7 +1202,6 @@ void t3_link_changed(struct adapter *adapter, int port_id) | |||
1202 | struct cphy *phy = &pi->phy; | 1202 | struct cphy *phy = &pi->phy; |
1203 | struct cmac *mac = &pi->mac; | 1203 | struct cmac *mac = &pi->mac; |
1204 | struct link_config *lc = &pi->link_config; | 1204 | struct link_config *lc = &pi->link_config; |
1205 | int force_link_down = 0; | ||
1206 | 1205 | ||
1207 | phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); | 1206 | phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); |
1208 | 1207 | ||
@@ -1218,14 +1217,9 @@ void t3_link_changed(struct adapter *adapter, int port_id) | |||
1218 | status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); | 1217 | status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); |
1219 | if (status & F_LINKFAULTCHANGE) { | 1218 | if (status & F_LINKFAULTCHANGE) { |
1220 | mac->stats.link_faults++; | 1219 | mac->stats.link_faults++; |
1221 | force_link_down = 1; | 1220 | pi->link_fault = 1; |
1222 | } | 1221 | } |
1223 | t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); | 1222 | t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); |
1224 | |||
1225 | if (force_link_down) { | ||
1226 | t3_os_link_fault_handler(adapter, port_id); | ||
1227 | return; | ||
1228 | } | ||
1229 | } | 1223 | } |
1230 | 1224 | ||
1231 | if (lc->requested_fc & PAUSE_AUTONEG) | 1225 | if (lc->requested_fc & PAUSE_AUTONEG) |
@@ -1292,9 +1286,6 @@ void t3_link_fault(struct adapter *adapter, int port_id) | |||
1292 | /* Account link faults only when the phy reports a link up */ | 1286 | /* Account link faults only when the phy reports a link up */ |
1293 | if (link_ok) | 1287 | if (link_ok) |
1294 | mac->stats.link_faults++; | 1288 | mac->stats.link_faults++; |
1295 | |||
1296 | msleep(1000); | ||
1297 | t3_os_link_fault_handler(adapter, port_id); | ||
1298 | } else { | 1289 | } else { |
1299 | if (link_ok) | 1290 | if (link_ok) |
1300 | t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, | 1291 | t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, |
diff --git a/drivers/net/declance.c b/drivers/net/declance.c index 861c867fca87..b62405a69180 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c | |||
@@ -1010,6 +1010,17 @@ static void lance_set_multicast_retry(unsigned long _opaque) | |||
1010 | lance_set_multicast(dev); | 1010 | lance_set_multicast(dev); |
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | static const struct net_device_ops lance_netdev_ops = { | ||
1014 | .ndo_open = lance_open, | ||
1015 | .ndo_stop = lance_close, | ||
1016 | .ndo_start_xmit = lance_start_xmit, | ||
1017 | .ndo_tx_timeout = lance_tx_timeout, | ||
1018 | .ndo_set_multicast_list = lance_set_multicast, | ||
1019 | .ndo_change_mtu = eth_change_mtu, | ||
1020 | .ndo_validate_addr = eth_validate_addr, | ||
1021 | .ndo_set_mac_address = eth_mac_addr, | ||
1022 | }; | ||
1023 | |||
1013 | static int __init dec_lance_probe(struct device *bdev, const int type) | 1024 | static int __init dec_lance_probe(struct device *bdev, const int type) |
1014 | { | 1025 | { |
1015 | static unsigned version_printed; | 1026 | static unsigned version_printed; |
@@ -1223,12 +1234,8 @@ static int __init dec_lance_probe(struct device *bdev, const int type) | |||
1223 | 1234 | ||
1224 | printk(", addr = %pM, irq = %d\n", dev->dev_addr, dev->irq); | 1235 | printk(", addr = %pM, irq = %d\n", dev->dev_addr, dev->irq); |
1225 | 1236 | ||
1226 | dev->open = &lance_open; | 1237 | dev->netdev_ops = &lance_netdev_ops; |
1227 | dev->stop = &lance_close; | ||
1228 | dev->hard_start_xmit = &lance_start_xmit; | ||
1229 | dev->tx_timeout = &lance_tx_timeout; | ||
1230 | dev->watchdog_timeo = 5*HZ; | 1238 | dev->watchdog_timeo = 5*HZ; |
1231 | dev->set_multicast_list = &lance_set_multicast; | ||
1232 | 1239 | ||
1233 | /* lp->ll is the location of the registers for lance card */ | 1240 | /* lp->ll is the location of the registers for lance card */ |
1234 | lp->ll = ll; | 1241 | lp->ll = ll; |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ddc5c533e89c..6a46ceed9436 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -156,8 +156,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); | |||
156 | static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); | 156 | static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); |
157 | static void e1000_restore_vlan(struct e1000_adapter *adapter); | 157 | static void e1000_restore_vlan(struct e1000_adapter *adapter); |
158 | 158 | ||
159 | static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); | ||
160 | #ifdef CONFIG_PM | 159 | #ifdef CONFIG_PM |
160 | static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); | ||
161 | static int e1000_resume(struct pci_dev *pdev); | 161 | static int e1000_resume(struct pci_dev *pdev); |
162 | #endif | 162 | #endif |
163 | static void e1000_shutdown(struct pci_dev *pdev); | 163 | static void e1000_shutdown(struct pci_dev *pdev); |
@@ -3834,7 +3834,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3834 | struct e1000_buffer *buffer_info; | 3834 | struct e1000_buffer *buffer_info; |
3835 | unsigned int i, eop; | 3835 | unsigned int i, eop; |
3836 | unsigned int count = 0; | 3836 | unsigned int count = 0; |
3837 | bool cleaned; | ||
3838 | unsigned int total_tx_bytes=0, total_tx_packets=0; | 3837 | unsigned int total_tx_bytes=0, total_tx_packets=0; |
3839 | 3838 | ||
3840 | i = tx_ring->next_to_clean; | 3839 | i = tx_ring->next_to_clean; |
@@ -3843,7 +3842,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3843 | 3842 | ||
3844 | while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && | 3843 | while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && |
3845 | (count < tx_ring->count)) { | 3844 | (count < tx_ring->count)) { |
3846 | for (cleaned = false; !cleaned; count++) { | 3845 | bool cleaned = false; |
3846 | for ( ; !cleaned; count++) { | ||
3847 | tx_desc = E1000_TX_DESC(*tx_ring, i); | 3847 | tx_desc = E1000_TX_DESC(*tx_ring, i); |
3848 | buffer_info = &tx_ring->buffer_info[i]; | 3848 | buffer_info = &tx_ring->buffer_info[i]; |
3849 | cleaned = (i == eop); | 3849 | cleaned = (i == eop); |
@@ -3871,7 +3871,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
3871 | tx_ring->next_to_clean = i; | 3871 | tx_ring->next_to_clean = i; |
3872 | 3872 | ||
3873 | #define TX_WAKE_THRESHOLD 32 | 3873 | #define TX_WAKE_THRESHOLD 32 |
3874 | if (unlikely(cleaned && netif_carrier_ok(netdev) && | 3874 | if (unlikely(count && netif_carrier_ok(netdev) && |
3875 | E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) { | 3875 | E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) { |
3876 | /* Make sure that anybody stopping the queue after this | 3876 | /* Make sure that anybody stopping the queue after this |
3877 | * sees the new next_to_clean. | 3877 | * sees the new next_to_clean. |
@@ -4601,7 +4601,7 @@ int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) | |||
4601 | return 0; | 4601 | return 0; |
4602 | } | 4602 | } |
4603 | 4603 | ||
4604 | static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | 4604 | static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) |
4605 | { | 4605 | { |
4606 | struct net_device *netdev = pci_get_drvdata(pdev); | 4606 | struct net_device *netdev = pci_get_drvdata(pdev); |
4607 | struct e1000_adapter *adapter = netdev_priv(netdev); | 4607 | struct e1000_adapter *adapter = netdev_priv(netdev); |
@@ -4664,22 +4664,18 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4664 | 4664 | ||
4665 | ew32(WUC, E1000_WUC_PME_EN); | 4665 | ew32(WUC, E1000_WUC_PME_EN); |
4666 | ew32(WUFC, wufc); | 4666 | ew32(WUFC, wufc); |
4667 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
4668 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
4669 | } else { | 4667 | } else { |
4670 | ew32(WUC, 0); | 4668 | ew32(WUC, 0); |
4671 | ew32(WUFC, 0); | 4669 | ew32(WUFC, 0); |
4672 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
4673 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
4674 | } | 4670 | } |
4675 | 4671 | ||
4676 | e1000_release_manageability(adapter); | 4672 | e1000_release_manageability(adapter); |
4677 | 4673 | ||
4674 | *enable_wake = !!wufc; | ||
4675 | |||
4678 | /* make sure adapter isn't asleep if manageability is enabled */ | 4676 | /* make sure adapter isn't asleep if manageability is enabled */ |
4679 | if (adapter->en_mng_pt) { | 4677 | if (adapter->en_mng_pt) |
4680 | pci_enable_wake(pdev, PCI_D3hot, 1); | 4678 | *enable_wake = true; |
4681 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
4682 | } | ||
4683 | 4679 | ||
4684 | if (hw->phy_type == e1000_phy_igp_3) | 4680 | if (hw->phy_type == e1000_phy_igp_3) |
4685 | e1000_phy_powerdown_workaround(hw); | 4681 | e1000_phy_powerdown_workaround(hw); |
@@ -4693,12 +4689,29 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4693 | 4689 | ||
4694 | pci_disable_device(pdev); | 4690 | pci_disable_device(pdev); |
4695 | 4691 | ||
4696 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
4697 | |||
4698 | return 0; | 4692 | return 0; |
4699 | } | 4693 | } |
4700 | 4694 | ||
4701 | #ifdef CONFIG_PM | 4695 | #ifdef CONFIG_PM |
4696 | static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | ||
4697 | { | ||
4698 | int retval; | ||
4699 | bool wake; | ||
4700 | |||
4701 | retval = __e1000_shutdown(pdev, &wake); | ||
4702 | if (retval) | ||
4703 | return retval; | ||
4704 | |||
4705 | if (wake) { | ||
4706 | pci_prepare_to_sleep(pdev); | ||
4707 | } else { | ||
4708 | pci_wake_from_d3(pdev, false); | ||
4709 | pci_set_power_state(pdev, PCI_D3hot); | ||
4710 | } | ||
4711 | |||
4712 | return 0; | ||
4713 | } | ||
4714 | |||
4702 | static int e1000_resume(struct pci_dev *pdev) | 4715 | static int e1000_resume(struct pci_dev *pdev) |
4703 | { | 4716 | { |
4704 | struct net_device *netdev = pci_get_drvdata(pdev); | 4717 | struct net_device *netdev = pci_get_drvdata(pdev); |
@@ -4753,7 +4766,14 @@ static int e1000_resume(struct pci_dev *pdev) | |||
4753 | 4766 | ||
4754 | static void e1000_shutdown(struct pci_dev *pdev) | 4767 | static void e1000_shutdown(struct pci_dev *pdev) |
4755 | { | 4768 | { |
4756 | e1000_suspend(pdev, PMSG_SUSPEND); | 4769 | bool wake; |
4770 | |||
4771 | __e1000_shutdown(pdev, &wake); | ||
4772 | |||
4773 | if (system_state == SYSTEM_POWER_OFF) { | ||
4774 | pci_wake_from_d3(pdev, wake); | ||
4775 | pci_set_power_state(pdev, PCI_D3hot); | ||
4776 | } | ||
4757 | } | 4777 | } |
4758 | 4778 | ||
4759 | #ifdef CONFIG_NET_POLL_CONTROLLER | 4779 | #ifdef CONFIG_NET_POLL_CONTROLLER |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 409b58cad0e5..ca82f19a7ed1 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -621,7 +621,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
621 | struct e1000_buffer *buffer_info; | 621 | struct e1000_buffer *buffer_info; |
622 | unsigned int i, eop; | 622 | unsigned int i, eop; |
623 | unsigned int count = 0; | 623 | unsigned int count = 0; |
624 | bool cleaned; | ||
625 | unsigned int total_tx_bytes = 0, total_tx_packets = 0; | 624 | unsigned int total_tx_bytes = 0, total_tx_packets = 0; |
626 | 625 | ||
627 | i = tx_ring->next_to_clean; | 626 | i = tx_ring->next_to_clean; |
@@ -630,7 +629,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
630 | 629 | ||
631 | while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && | 630 | while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && |
632 | (count < tx_ring->count)) { | 631 | (count < tx_ring->count)) { |
633 | for (cleaned = 0; !cleaned; count++) { | 632 | bool cleaned = false; |
633 | for (; !cleaned; count++) { | ||
634 | tx_desc = E1000_TX_DESC(*tx_ring, i); | 634 | tx_desc = E1000_TX_DESC(*tx_ring, i); |
635 | buffer_info = &tx_ring->buffer_info[i]; | 635 | buffer_info = &tx_ring->buffer_info[i]; |
636 | cleaned = (i == eop); | 636 | cleaned = (i == eop); |
@@ -661,8 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
661 | tx_ring->next_to_clean = i; | 661 | tx_ring->next_to_clean = i; |
662 | 662 | ||
663 | #define TX_WAKE_THRESHOLD 32 | 663 | #define TX_WAKE_THRESHOLD 32 |
664 | if (cleaned && netif_carrier_ok(netdev) && | 664 | if (count && netif_carrier_ok(netdev) && |
665 | e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) { | 665 | e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) { |
666 | /* Make sure that anybody stopping the queue after this | 666 | /* Make sure that anybody stopping the queue after this |
667 | * sees the new next_to_clean. | 667 | * sees the new next_to_clean. |
668 | */ | 668 | */ |
@@ -4346,7 +4346,7 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | |||
4346 | } | 4346 | } |
4347 | } | 4347 | } |
4348 | 4348 | ||
4349 | static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | 4349 | static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) |
4350 | { | 4350 | { |
4351 | struct net_device *netdev = pci_get_drvdata(pdev); | 4351 | struct net_device *netdev = pci_get_drvdata(pdev); |
4352 | struct e1000_adapter *adapter = netdev_priv(netdev); | 4352 | struct e1000_adapter *adapter = netdev_priv(netdev); |
@@ -4409,20 +4409,16 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4409 | 4409 | ||
4410 | ew32(WUC, E1000_WUC_PME_EN); | 4410 | ew32(WUC, E1000_WUC_PME_EN); |
4411 | ew32(WUFC, wufc); | 4411 | ew32(WUFC, wufc); |
4412 | pci_enable_wake(pdev, PCI_D3hot, 1); | ||
4413 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
4414 | } else { | 4412 | } else { |
4415 | ew32(WUC, 0); | 4413 | ew32(WUC, 0); |
4416 | ew32(WUFC, 0); | 4414 | ew32(WUFC, 0); |
4417 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
4418 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
4419 | } | 4415 | } |
4420 | 4416 | ||
4417 | *enable_wake = !!wufc; | ||
4418 | |||
4421 | /* make sure adapter isn't asleep if manageability is enabled */ | 4419 | /* make sure adapter isn't asleep if manageability is enabled */ |
4422 | if (adapter->flags & FLAG_MNG_PT_ENABLED) { | 4420 | if (adapter->flags & FLAG_MNG_PT_ENABLED) |
4423 | pci_enable_wake(pdev, PCI_D3hot, 1); | 4421 | *enable_wake = true; |
4424 | pci_enable_wake(pdev, PCI_D3cold, 1); | ||
4425 | } | ||
4426 | 4422 | ||
4427 | if (adapter->hw.phy.type == e1000_phy_igp_3) | 4423 | if (adapter->hw.phy.type == e1000_phy_igp_3) |
4428 | e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); | 4424 | e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); |
@@ -4435,6 +4431,26 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4435 | 4431 | ||
4436 | pci_disable_device(pdev); | 4432 | pci_disable_device(pdev); |
4437 | 4433 | ||
4434 | return 0; | ||
4435 | } | ||
4436 | |||
4437 | static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake) | ||
4438 | { | ||
4439 | if (sleep && wake) { | ||
4440 | pci_prepare_to_sleep(pdev); | ||
4441 | return; | ||
4442 | } | ||
4443 | |||
4444 | pci_wake_from_d3(pdev, wake); | ||
4445 | pci_set_power_state(pdev, PCI_D3hot); | ||
4446 | } | ||
4447 | |||
4448 | static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, | ||
4449 | bool wake) | ||
4450 | { | ||
4451 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
4452 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
4453 | |||
4438 | /* | 4454 | /* |
4439 | * The pci-e switch on some quad port adapters will report a | 4455 | * The pci-e switch on some quad port adapters will report a |
4440 | * correctable error when the MAC transitions from D0 to D3. To | 4456 | * correctable error when the MAC transitions from D0 to D3. To |
@@ -4450,14 +4466,12 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4450 | pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, | 4466 | pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, |
4451 | (devctl & ~PCI_EXP_DEVCTL_CERE)); | 4467 | (devctl & ~PCI_EXP_DEVCTL_CERE)); |
4452 | 4468 | ||
4453 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 4469 | e1000_power_off(pdev, sleep, wake); |
4454 | 4470 | ||
4455 | pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl); | 4471 | pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl); |
4456 | } else { | 4472 | } else { |
4457 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 4473 | e1000_power_off(pdev, sleep, wake); |
4458 | } | 4474 | } |
4459 | |||
4460 | return 0; | ||
4461 | } | 4475 | } |
4462 | 4476 | ||
4463 | static void e1000e_disable_l1aspm(struct pci_dev *pdev) | 4477 | static void e1000e_disable_l1aspm(struct pci_dev *pdev) |
@@ -4486,6 +4500,18 @@ static void e1000e_disable_l1aspm(struct pci_dev *pdev) | |||
4486 | } | 4500 | } |
4487 | 4501 | ||
4488 | #ifdef CONFIG_PM | 4502 | #ifdef CONFIG_PM |
4503 | static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) | ||
4504 | { | ||
4505 | int retval; | ||
4506 | bool wake; | ||
4507 | |||
4508 | retval = __e1000_shutdown(pdev, &wake); | ||
4509 | if (!retval) | ||
4510 | e1000_complete_shutdown(pdev, true, wake); | ||
4511 | |||
4512 | return retval; | ||
4513 | } | ||
4514 | |||
4489 | static int e1000_resume(struct pci_dev *pdev) | 4515 | static int e1000_resume(struct pci_dev *pdev) |
4490 | { | 4516 | { |
4491 | struct net_device *netdev = pci_get_drvdata(pdev); | 4517 | struct net_device *netdev = pci_get_drvdata(pdev); |
@@ -4549,7 +4575,12 @@ static int e1000_resume(struct pci_dev *pdev) | |||
4549 | 4575 | ||
4550 | static void e1000_shutdown(struct pci_dev *pdev) | 4576 | static void e1000_shutdown(struct pci_dev *pdev) |
4551 | { | 4577 | { |
4552 | e1000_suspend(pdev, PMSG_SUSPEND); | 4578 | bool wake = false; |
4579 | |||
4580 | __e1000_shutdown(pdev, &wake); | ||
4581 | |||
4582 | if (system_state == SYSTEM_POWER_OFF) | ||
4583 | e1000_complete_shutdown(pdev, false, wake); | ||
4553 | } | 4584 | } |
4554 | 4585 | ||
4555 | #ifdef CONFIG_NET_POLL_CONTROLLER | 4586 | #ifdef CONFIG_NET_POLL_CONTROLLER |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index ac0c5b438e0a..604c844d0769 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -3080,7 +3080,8 @@ static const struct net_device_ops ehea_netdev_ops = { | |||
3080 | .ndo_change_mtu = ehea_change_mtu, | 3080 | .ndo_change_mtu = ehea_change_mtu, |
3081 | .ndo_vlan_rx_register = ehea_vlan_rx_register, | 3081 | .ndo_vlan_rx_register = ehea_vlan_rx_register, |
3082 | .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid, | 3082 | .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid, |
3083 | .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid | 3083 | .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid, |
3084 | .ndo_tx_timeout = ehea_tx_watchdog, | ||
3084 | }; | 3085 | }; |
3085 | 3086 | ||
3086 | struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | 3087 | struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, |
@@ -3142,7 +3143,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
3142 | | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | 3143 | | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX |
3143 | | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER | 3144 | | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER |
3144 | | NETIF_F_LLTX; | 3145 | | NETIF_F_LLTX; |
3145 | dev->tx_timeout = &ehea_tx_watchdog; | ||
3146 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; | 3146 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; |
3147 | 3147 | ||
3148 | INIT_WORK(&port->reset_task, ehea_reset_port); | 3148 | INIT_WORK(&port->reset_task, ehea_reset_port); |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index d37465020bcc..11d5db16ed9c 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -3745,14 +3745,14 @@ static int nv_napi_poll(struct napi_struct *napi, int budget) | |||
3745 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); | 3745 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); |
3746 | } | 3746 | } |
3747 | spin_unlock_irqrestore(&np->lock, flags); | 3747 | spin_unlock_irqrestore(&np->lock, flags); |
3748 | __napi_complete(napi); | 3748 | napi_complete(napi); |
3749 | return rx_work; | 3749 | return rx_work; |
3750 | } | 3750 | } |
3751 | 3751 | ||
3752 | if (rx_work < budget) { | 3752 | if (rx_work < budget) { |
3753 | /* re-enable interrupts | 3753 | /* re-enable interrupts |
3754 | (msix not enabled in napi) */ | 3754 | (msix not enabled in napi) */ |
3755 | __napi_complete(napi); | 3755 | napi_complete(napi); |
3756 | 3756 | ||
3757 | writel(np->irqmask, base + NvRegIrqMask); | 3757 | writel(np->irqmask, base + NvRegIrqMask); |
3758 | } | 3758 | } |
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index b037ce9857bf..a9cbc3191a2a 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c | |||
@@ -1019,6 +1019,22 @@ out_put_phy: | |||
1019 | #define IS_FEC(match) 0 | 1019 | #define IS_FEC(match) 0 |
1020 | #endif | 1020 | #endif |
1021 | 1021 | ||
1022 | static const struct net_device_ops fs_enet_netdev_ops = { | ||
1023 | .ndo_open = fs_enet_open, | ||
1024 | .ndo_stop = fs_enet_close, | ||
1025 | .ndo_get_stats = fs_enet_get_stats, | ||
1026 | .ndo_start_xmit = fs_enet_start_xmit, | ||
1027 | .ndo_tx_timeout = fs_timeout, | ||
1028 | .ndo_set_multicast_list = fs_set_multicast_list, | ||
1029 | .ndo_do_ioctl = fs_ioctl, | ||
1030 | .ndo_validate_addr = eth_validate_addr, | ||
1031 | .ndo_set_mac_address = eth_mac_addr, | ||
1032 | .ndo_change_mtu = eth_change_mtu, | ||
1033 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1034 | .ndo_poll_controller = fs_enet_netpoll, | ||
1035 | #endif | ||
1036 | }; | ||
1037 | |||
1022 | static int __devinit fs_enet_probe(struct of_device *ofdev, | 1038 | static int __devinit fs_enet_probe(struct of_device *ofdev, |
1023 | const struct of_device_id *match) | 1039 | const struct of_device_id *match) |
1024 | { | 1040 | { |
@@ -1093,22 +1109,13 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, | |||
1093 | fep->tx_ring = fpi->tx_ring; | 1109 | fep->tx_ring = fpi->tx_ring; |
1094 | fep->rx_ring = fpi->rx_ring; | 1110 | fep->rx_ring = fpi->rx_ring; |
1095 | 1111 | ||
1096 | ndev->open = fs_enet_open; | 1112 | ndev->netdev_ops = &fs_enet_netdev_ops; |
1097 | ndev->hard_start_xmit = fs_enet_start_xmit; | ||
1098 | ndev->tx_timeout = fs_timeout; | ||
1099 | ndev->watchdog_timeo = 2 * HZ; | 1113 | ndev->watchdog_timeo = 2 * HZ; |
1100 | ndev->stop = fs_enet_close; | ||
1101 | ndev->get_stats = fs_enet_get_stats; | ||
1102 | ndev->set_multicast_list = fs_set_multicast_list; | ||
1103 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1104 | ndev->poll_controller = fs_enet_netpoll; | ||
1105 | #endif | ||
1106 | if (fpi->use_napi) | 1114 | if (fpi->use_napi) |
1107 | netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, | 1115 | netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, |
1108 | fpi->napi_weight); | 1116 | fpi->napi_weight); |
1109 | 1117 | ||
1110 | ndev->ethtool_ops = &fs_ethtool_ops; | 1118 | ndev->ethtool_ops = &fs_ethtool_ops; |
1111 | ndev->do_ioctl = fs_ioctl; | ||
1112 | 1119 | ||
1113 | init_timer(&fep->phy_timer_list); | 1120 | init_timer(&fep->phy_timer_list); |
1114 | 1121 | ||
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 65f55877be95..b2c49679bba7 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -1583,8 +1583,10 @@ static void gfar_reset_task(struct work_struct *work) | |||
1583 | struct net_device *dev = priv->ndev; | 1583 | struct net_device *dev = priv->ndev; |
1584 | 1584 | ||
1585 | if (dev->flags & IFF_UP) { | 1585 | if (dev->flags & IFF_UP) { |
1586 | netif_stop_queue(dev); | ||
1586 | stop_gfar(dev); | 1587 | stop_gfar(dev); |
1587 | startup_gfar(dev); | 1588 | startup_gfar(dev); |
1589 | netif_start_queue(dev); | ||
1588 | } | 1590 | } |
1589 | 1591 | ||
1590 | netif_tx_schedule_all(dev); | 1592 | netif_tx_schedule_all(dev); |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 77e4b5b52fc8..806533c831c7 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -2686,6 +2686,32 @@ static int __devinit emac_init_config(struct emac_instance *dev) | |||
2686 | return 0; | 2686 | return 0; |
2687 | } | 2687 | } |
2688 | 2688 | ||
2689 | static const struct net_device_ops emac_netdev_ops = { | ||
2690 | .ndo_open = emac_open, | ||
2691 | .ndo_stop = emac_close, | ||
2692 | .ndo_get_stats = emac_stats, | ||
2693 | .ndo_set_multicast_list = emac_set_multicast_list, | ||
2694 | .ndo_do_ioctl = emac_ioctl, | ||
2695 | .ndo_tx_timeout = emac_tx_timeout, | ||
2696 | .ndo_validate_addr = eth_validate_addr, | ||
2697 | .ndo_set_mac_address = eth_mac_addr, | ||
2698 | .ndo_start_xmit = emac_start_xmit, | ||
2699 | .ndo_change_mtu = eth_change_mtu, | ||
2700 | }; | ||
2701 | |||
2702 | static const struct net_device_ops emac_gige_netdev_ops = { | ||
2703 | .ndo_open = emac_open, | ||
2704 | .ndo_stop = emac_close, | ||
2705 | .ndo_get_stats = emac_stats, | ||
2706 | .ndo_set_multicast_list = emac_set_multicast_list, | ||
2707 | .ndo_do_ioctl = emac_ioctl, | ||
2708 | .ndo_tx_timeout = emac_tx_timeout, | ||
2709 | .ndo_validate_addr = eth_validate_addr, | ||
2710 | .ndo_set_mac_address = eth_mac_addr, | ||
2711 | .ndo_start_xmit = emac_start_xmit_sg, | ||
2712 | .ndo_change_mtu = emac_change_mtu, | ||
2713 | }; | ||
2714 | |||
2689 | static int __devinit emac_probe(struct of_device *ofdev, | 2715 | static int __devinit emac_probe(struct of_device *ofdev, |
2690 | const struct of_device_id *match) | 2716 | const struct of_device_id *match) |
2691 | { | 2717 | { |
@@ -2827,23 +2853,14 @@ static int __devinit emac_probe(struct of_device *ofdev, | |||
2827 | if (err != 0) | 2853 | if (err != 0) |
2828 | goto err_detach_tah; | 2854 | goto err_detach_tah; |
2829 | 2855 | ||
2830 | /* Fill in the driver function table */ | ||
2831 | ndev->open = &emac_open; | ||
2832 | if (dev->tah_dev) | 2856 | if (dev->tah_dev) |
2833 | ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 2857 | ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; |
2834 | ndev->tx_timeout = &emac_tx_timeout; | ||
2835 | ndev->watchdog_timeo = 5 * HZ; | 2858 | ndev->watchdog_timeo = 5 * HZ; |
2836 | ndev->stop = &emac_close; | ||
2837 | ndev->get_stats = &emac_stats; | ||
2838 | ndev->set_multicast_list = &emac_set_multicast_list; | ||
2839 | ndev->do_ioctl = &emac_ioctl; | ||
2840 | if (emac_phy_supports_gige(dev->phy_mode)) { | 2859 | if (emac_phy_supports_gige(dev->phy_mode)) { |
2841 | ndev->hard_start_xmit = &emac_start_xmit_sg; | 2860 | ndev->netdev_ops = &emac_gige_netdev_ops; |
2842 | ndev->change_mtu = &emac_change_mtu; | ||
2843 | dev->commac.ops = &emac_commac_sg_ops; | 2861 | dev->commac.ops = &emac_commac_sg_ops; |
2844 | } else { | 2862 | } else |
2845 | ndev->hard_start_xmit = &emac_start_xmit; | 2863 | ndev->netdev_ops = &emac_netdev_ops; |
2846 | } | ||
2847 | SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); | 2864 | SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); |
2848 | 2865 | ||
2849 | netif_carrier_off(ndev); | 2866 | netif_carrier_off(ndev); |
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index f4c315b5a900..472f3f124840 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c | |||
@@ -111,7 +111,7 @@ void igb_clear_vfta(struct e1000_hw *hw) | |||
111 | * Writes value at the given offset in the register array which stores | 111 | * Writes value at the given offset in the register array which stores |
112 | * the VLAN filter table. | 112 | * the VLAN filter table. |
113 | **/ | 113 | **/ |
114 | void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) | 114 | static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) |
115 | { | 115 | { |
116 | array_wr32(E1000_VFTA, offset, value); | 116 | array_wr32(E1000_VFTA, offset, value); |
117 | wrfl(); | 117 | wrfl(); |
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h index a34de5269637..1d690b4c9ae4 100644 --- a/drivers/net/igb/e1000_mac.h +++ b/drivers/net/igb/e1000_mac.h | |||
@@ -66,7 +66,6 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); | |||
66 | s32 igb_check_alt_mac_addr(struct e1000_hw *hw); | 66 | s32 igb_check_alt_mac_addr(struct e1000_hw *hw); |
67 | void igb_reset_adaptive(struct e1000_hw *hw); | 67 | void igb_reset_adaptive(struct e1000_hw *hw); |
68 | void igb_update_adaptive(struct e1000_hw *hw); | 68 | void igb_update_adaptive(struct e1000_hw *hw); |
69 | void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value); | ||
70 | 69 | ||
71 | bool igb_enable_mng_pass_thru(struct e1000_hw *hw); | 70 | bool igb_enable_mng_pass_thru(struct e1000_hw *hw); |
72 | 71 | ||
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c index fe71c7ddaa05..840782fb5736 100644 --- a/drivers/net/igb/e1000_mbx.c +++ b/drivers/net/igb/e1000_mbx.c | |||
@@ -188,7 +188,7 @@ out: | |||
188 | * returns SUCCESS if it successfully received a message notification and | 188 | * returns SUCCESS if it successfully received a message notification and |
189 | * copied it into the receive buffer. | 189 | * copied it into the receive buffer. |
190 | **/ | 190 | **/ |
191 | s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) | 191 | static s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) |
192 | { | 192 | { |
193 | struct e1000_mbx_info *mbx = &hw->mbx; | 193 | struct e1000_mbx_info *mbx = &hw->mbx; |
194 | s32 ret_val = -E1000_ERR_MBX; | 194 | s32 ret_val = -E1000_ERR_MBX; |
@@ -214,7 +214,7 @@ out: | |||
214 | * returns SUCCESS if it successfully copied message into the buffer and | 214 | * returns SUCCESS if it successfully copied message into the buffer and |
215 | * received an ack to that message within delay * timeout period | 215 | * received an ack to that message within delay * timeout period |
216 | **/ | 216 | **/ |
217 | s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) | 217 | static s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) |
218 | { | 218 | { |
219 | struct e1000_mbx_info *mbx = &hw->mbx; | 219 | struct e1000_mbx_info *mbx = &hw->mbx; |
220 | s32 ret_val = 0; | 220 | s32 ret_val = 0; |
@@ -232,19 +232,6 @@ out: | |||
232 | return ret_val; | 232 | return ret_val; |
233 | } | 233 | } |
234 | 234 | ||
235 | /** | ||
236 | * e1000_init_mbx_ops_generic - Initialize NVM function pointers | ||
237 | * @hw: pointer to the HW structure | ||
238 | * | ||
239 | * Setups up the function pointers to no-op functions | ||
240 | **/ | ||
241 | void e1000_init_mbx_ops_generic(struct e1000_hw *hw) | ||
242 | { | ||
243 | struct e1000_mbx_info *mbx = &hw->mbx; | ||
244 | mbx->ops.read_posted = igb_read_posted_mbx; | ||
245 | mbx->ops.write_posted = igb_write_posted_mbx; | ||
246 | } | ||
247 | |||
248 | static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask) | 235 | static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask) |
249 | { | 236 | { |
250 | u32 mbvficr = rd32(E1000_MBVFICR); | 237 | u32 mbvficr = rd32(E1000_MBVFICR); |
diff --git a/drivers/net/igb/e1000_mbx.h b/drivers/net/igb/e1000_mbx.h index 6ec9890a8f7a..ebc02ea3f198 100644 --- a/drivers/net/igb/e1000_mbx.h +++ b/drivers/net/igb/e1000_mbx.h | |||
@@ -67,8 +67,6 @@ | |||
67 | 67 | ||
68 | s32 igb_read_mbx(struct e1000_hw *, u32 *, u16, u16); | 68 | s32 igb_read_mbx(struct e1000_hw *, u32 *, u16, u16); |
69 | s32 igb_write_mbx(struct e1000_hw *, u32 *, u16, u16); | 69 | s32 igb_write_mbx(struct e1000_hw *, u32 *, u16, u16); |
70 | s32 igb_read_posted_mbx(struct e1000_hw *, u32 *, u16, u16); | ||
71 | s32 igb_write_posted_mbx(struct e1000_hw *, u32 *, u16, u16); | ||
72 | s32 igb_check_for_msg(struct e1000_hw *, u16); | 70 | s32 igb_check_for_msg(struct e1000_hw *, u16); |
73 | s32 igb_check_for_ack(struct e1000_hw *, u16); | 71 | s32 igb_check_for_ack(struct e1000_hw *, u16); |
74 | s32 igb_check_for_rst(struct e1000_hw *, u16); | 72 | s32 igb_check_for_rst(struct e1000_hw *, u16); |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index db7274e62228..08c801490c72 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -1261,25 +1261,32 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
1261 | int i; | 1261 | int i; |
1262 | unsigned char mac_addr[ETH_ALEN]; | 1262 | unsigned char mac_addr[ETH_ALEN]; |
1263 | 1263 | ||
1264 | if (num_vfs) | 1264 | if (num_vfs) { |
1265 | adapter->vf_data = kcalloc(num_vfs, | 1265 | adapter->vf_data = kcalloc(num_vfs, |
1266 | sizeof(struct vf_data_storage), | 1266 | sizeof(struct vf_data_storage), |
1267 | GFP_KERNEL); | 1267 | GFP_KERNEL); |
1268 | if (!adapter->vf_data) { | 1268 | if (!adapter->vf_data) { |
1269 | dev_err(&pdev->dev, "Could not allocate VF private " | 1269 | dev_err(&pdev->dev, |
1270 | "data - IOV enable failed\n"); | 1270 | "Could not allocate VF private data - " |
1271 | } else { | 1271 | "IOV enable failed\n"); |
1272 | err = pci_enable_sriov(pdev, num_vfs); | ||
1273 | if (!err) { | ||
1274 | adapter->vfs_allocated_count = num_vfs; | ||
1275 | dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs); | ||
1276 | for (i = 0; i < adapter->vfs_allocated_count; i++) { | ||
1277 | random_ether_addr(mac_addr); | ||
1278 | igb_set_vf_mac(adapter, i, mac_addr); | ||
1279 | } | ||
1280 | } else { | 1272 | } else { |
1281 | kfree(adapter->vf_data); | 1273 | err = pci_enable_sriov(pdev, num_vfs); |
1282 | adapter->vf_data = NULL; | 1274 | if (!err) { |
1275 | adapter->vfs_allocated_count = num_vfs; | ||
1276 | dev_info(&pdev->dev, | ||
1277 | "%d vfs allocated\n", | ||
1278 | num_vfs); | ||
1279 | for (i = 0; | ||
1280 | i < adapter->vfs_allocated_count; | ||
1281 | i++) { | ||
1282 | random_ether_addr(mac_addr); | ||
1283 | igb_set_vf_mac(adapter, i, | ||
1284 | mac_addr); | ||
1285 | } | ||
1286 | } else { | ||
1287 | kfree(adapter->vf_data); | ||
1288 | adapter->vf_data = NULL; | ||
1289 | } | ||
1283 | } | 1290 | } |
1284 | } | 1291 | } |
1285 | } | 1292 | } |
diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index 936ed2a9435f..4bff35e46871 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h | |||
@@ -321,14 +321,11 @@ extern void igbvf_set_ethtool_ops(struct net_device *); | |||
321 | extern int igbvf_up(struct igbvf_adapter *); | 321 | extern int igbvf_up(struct igbvf_adapter *); |
322 | extern void igbvf_down(struct igbvf_adapter *); | 322 | extern void igbvf_down(struct igbvf_adapter *); |
323 | extern void igbvf_reinit_locked(struct igbvf_adapter *); | 323 | extern void igbvf_reinit_locked(struct igbvf_adapter *); |
324 | extern void igbvf_reset(struct igbvf_adapter *); | ||
325 | extern int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *); | 324 | extern int igbvf_setup_rx_resources(struct igbvf_adapter *, struct igbvf_ring *); |
326 | extern int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *); | 325 | extern int igbvf_setup_tx_resources(struct igbvf_adapter *, struct igbvf_ring *); |
327 | extern void igbvf_free_rx_resources(struct igbvf_ring *); | 326 | extern void igbvf_free_rx_resources(struct igbvf_ring *); |
328 | extern void igbvf_free_tx_resources(struct igbvf_ring *); | 327 | extern void igbvf_free_tx_resources(struct igbvf_ring *); |
329 | extern void igbvf_update_stats(struct igbvf_adapter *); | 328 | extern void igbvf_update_stats(struct igbvf_adapter *); |
330 | extern void igbvf_set_interrupt_capability(struct igbvf_adapter *); | ||
331 | extern void igbvf_reset_interrupt_capability(struct igbvf_adapter *); | ||
332 | 329 | ||
333 | extern unsigned int copybreak; | 330 | extern unsigned int copybreak; |
334 | 331 | ||
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index c5648420dedf..b774666ad3cf 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c | |||
@@ -52,6 +52,9 @@ static const char igbvf_driver_string[] = | |||
52 | static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; | 52 | static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; |
53 | 53 | ||
54 | static int igbvf_poll(struct napi_struct *napi, int budget); | 54 | static int igbvf_poll(struct napi_struct *napi, int budget); |
55 | static void igbvf_reset(struct igbvf_adapter *); | ||
56 | static void igbvf_set_interrupt_capability(struct igbvf_adapter *); | ||
57 | static void igbvf_reset_interrupt_capability(struct igbvf_adapter *); | ||
55 | 58 | ||
56 | static struct igbvf_info igbvf_vf_info = { | 59 | static struct igbvf_info igbvf_vf_info = { |
57 | .mac = e1000_vfadapt, | 60 | .mac = e1000_vfadapt, |
@@ -990,7 +993,7 @@ static void igbvf_configure_msix(struct igbvf_adapter *adapter) | |||
990 | e1e_flush(); | 993 | e1e_flush(); |
991 | } | 994 | } |
992 | 995 | ||
993 | void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter) | 996 | static void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter) |
994 | { | 997 | { |
995 | if (adapter->msix_entries) { | 998 | if (adapter->msix_entries) { |
996 | pci_disable_msix(adapter->pdev); | 999 | pci_disable_msix(adapter->pdev); |
@@ -1005,7 +1008,7 @@ void igbvf_reset_interrupt_capability(struct igbvf_adapter *adapter) | |||
1005 | * Attempt to configure interrupts using the best available | 1008 | * Attempt to configure interrupts using the best available |
1006 | * capabilities of the hardware and kernel. | 1009 | * capabilities of the hardware and kernel. |
1007 | **/ | 1010 | **/ |
1008 | void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter) | 1011 | static void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter) |
1009 | { | 1012 | { |
1010 | int err = -ENOMEM; | 1013 | int err = -ENOMEM; |
1011 | int i; | 1014 | int i; |
@@ -1447,7 +1450,7 @@ static void igbvf_configure(struct igbvf_adapter *adapter) | |||
1447 | * set/changed during runtime. After reset the device needs to be | 1450 | * set/changed during runtime. After reset the device needs to be |
1448 | * properly configured for Rx, Tx etc. | 1451 | * properly configured for Rx, Tx etc. |
1449 | */ | 1452 | */ |
1450 | void igbvf_reset(struct igbvf_adapter *adapter) | 1453 | static void igbvf_reset(struct igbvf_adapter *adapter) |
1451 | { | 1454 | { |
1452 | struct e1000_mac_info *mac = &adapter->hw.mac; | 1455 | struct e1000_mac_info *mac = &adapter->hw.mac; |
1453 | struct net_device *netdev = adapter->netdev; | 1456 | struct net_device *netdev = adapter->netdev; |
diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c index aa246c93279d..2a4faf9ade69 100644 --- a/drivers/net/igbvf/vf.c +++ b/drivers/net/igbvf/vf.c | |||
@@ -44,7 +44,7 @@ static s32 e1000_set_vfta_vf(struct e1000_hw *, u16, bool); | |||
44 | * e1000_init_mac_params_vf - Inits MAC params | 44 | * e1000_init_mac_params_vf - Inits MAC params |
45 | * @hw: pointer to the HW structure | 45 | * @hw: pointer to the HW structure |
46 | **/ | 46 | **/ |
47 | s32 e1000_init_mac_params_vf(struct e1000_hw *hw) | 47 | static s32 e1000_init_mac_params_vf(struct e1000_hw *hw) |
48 | { | 48 | { |
49 | struct e1000_mac_info *mac = &hw->mac; | 49 | struct e1000_mac_info *mac = &hw->mac; |
50 | 50 | ||
diff --git a/drivers/net/igbvf/vf.h b/drivers/net/igbvf/vf.h index ec07228f9478..1e8ce3741a67 100644 --- a/drivers/net/igbvf/vf.h +++ b/drivers/net/igbvf/vf.h | |||
@@ -259,7 +259,6 @@ struct e1000_hw { | |||
259 | /* These functions must be implemented by drivers */ | 259 | /* These functions must be implemented by drivers */ |
260 | void e1000_rlpml_set_vf(struct e1000_hw *, u16); | 260 | void e1000_rlpml_set_vf(struct e1000_hw *, u16); |
261 | void e1000_init_function_pointers_vf(struct e1000_hw *hw); | 261 | void e1000_init_function_pointers_vf(struct e1000_hw *hw); |
262 | s32 e1000_init_mac_params_vf(struct e1000_hw *hw); | ||
263 | 262 | ||
264 | 263 | ||
265 | #endif /* _E1000_VF_H_ */ | 264 | #endif /* _E1000_VF_H_ */ |
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index cbc63ff13add..c5593f4665a4 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c | |||
@@ -1214,6 +1214,19 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) | |||
1214 | } | 1214 | } |
1215 | #endif | 1215 | #endif |
1216 | 1216 | ||
1217 | static const struct net_device_ops ioc3_netdev_ops = { | ||
1218 | .ndo_open = ioc3_open, | ||
1219 | .ndo_stop = ioc3_close, | ||
1220 | .ndo_start_xmit = ioc3_start_xmit, | ||
1221 | .ndo_tx_timeout = ioc3_timeout, | ||
1222 | .ndo_get_stats = ioc3_get_stats, | ||
1223 | .ndo_set_multicast_list = ioc3_set_multicast_list, | ||
1224 | .ndo_do_ioctl = ioc3_ioctl, | ||
1225 | .ndo_validate_addr = eth_validate_addr, | ||
1226 | .ndo_set_mac_address = ioc3_set_mac_address, | ||
1227 | .ndo_change_mtu = eth_change_mtu, | ||
1228 | }; | ||
1229 | |||
1217 | static int __devinit ioc3_probe(struct pci_dev *pdev, | 1230 | static int __devinit ioc3_probe(struct pci_dev *pdev, |
1218 | const struct pci_device_id *ent) | 1231 | const struct pci_device_id *ent) |
1219 | { | 1232 | { |
@@ -1310,15 +1323,8 @@ static int __devinit ioc3_probe(struct pci_dev *pdev, | |||
1310 | ioc3_get_eaddr(ip); | 1323 | ioc3_get_eaddr(ip); |
1311 | 1324 | ||
1312 | /* The IOC3-specific entries in the device structure. */ | 1325 | /* The IOC3-specific entries in the device structure. */ |
1313 | dev->open = ioc3_open; | ||
1314 | dev->hard_start_xmit = ioc3_start_xmit; | ||
1315 | dev->tx_timeout = ioc3_timeout; | ||
1316 | dev->watchdog_timeo = 5 * HZ; | 1326 | dev->watchdog_timeo = 5 * HZ; |
1317 | dev->stop = ioc3_close; | 1327 | dev->netdev_ops = &ioc3_netdev_ops; |
1318 | dev->get_stats = ioc3_get_stats; | ||
1319 | dev->do_ioctl = ioc3_ioctl; | ||
1320 | dev->set_multicast_list = ioc3_set_multicast_list; | ||
1321 | dev->set_mac_address = ioc3_set_mac_address; | ||
1322 | dev->ethtool_ops = &ioc3_ethtool_ops; | 1328 | dev->ethtool_ops = &ioc3_ethtool_ops; |
1323 | dev->features = NETIF_F_IP_CSUM; | 1329 | dev->features = NETIF_F_IP_CSUM; |
1324 | 1330 | ||
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c index 3126678bdd3c..73585fd8f29f 100644 --- a/drivers/net/isa-skeleton.c +++ b/drivers/net/isa-skeleton.c | |||
@@ -181,6 +181,18 @@ out: | |||
181 | } | 181 | } |
182 | #endif | 182 | #endif |
183 | 183 | ||
184 | static const struct net_device_ops netcard_netdev_ops = { | ||
185 | .ndo_open = net_open, | ||
186 | .ndo_stop = net_close, | ||
187 | .ndo_start_xmit = net_send_packet, | ||
188 | .ndo_get_stats = net_get_stats, | ||
189 | .ndo_set_multicast_list = set_multicast_list, | ||
190 | .ndo_tx_timeout = net_tx_timeout, | ||
191 | .ndo_validate_addr = eth_validate_addr, | ||
192 | .ndo_set_mac_address = eth_mac_addr, | ||
193 | .ndo_change_mtu = eth_change_mtu, | ||
194 | }; | ||
195 | |||
184 | /* | 196 | /* |
185 | * This is the real probe routine. Linux has a history of friendly device | 197 | * This is the real probe routine. Linux has a history of friendly device |
186 | * probes on the ISA bus. A good device probes avoids doing writes, and | 198 | * probes on the ISA bus. A good device probes avoids doing writes, and |
@@ -303,13 +315,7 @@ static int __init netcard_probe1(struct net_device *dev, int ioaddr) | |||
303 | np = netdev_priv(dev); | 315 | np = netdev_priv(dev); |
304 | spin_lock_init(&np->lock); | 316 | spin_lock_init(&np->lock); |
305 | 317 | ||
306 | dev->open = net_open; | 318 | dev->netdev_ops = &netcard_netdev_ops; |
307 | dev->stop = net_close; | ||
308 | dev->hard_start_xmit = net_send_packet; | ||
309 | dev->get_stats = net_get_stats; | ||
310 | dev->set_multicast_list = &set_multicast_list; | ||
311 | |||
312 | dev->tx_timeout = &net_tx_timeout; | ||
313 | dev->watchdog_timeo = MY_TX_TIMEOUT; | 319 | dev->watchdog_timeo = MY_TX_TIMEOUT; |
314 | 320 | ||
315 | err = register_netdev(dev); | 321 | err = register_netdev(dev); |
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index de4db0dc7879..4791238c3f6e 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -885,61 +885,6 @@ static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw) | |||
885 | } | 885 | } |
886 | 886 | ||
887 | /** | 887 | /** |
888 | * ixgbe_blink_led_start_82598 - Blink LED based on index. | ||
889 | * @hw: pointer to hardware structure | ||
890 | * @index: led number to blink | ||
891 | **/ | ||
892 | static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index) | ||
893 | { | ||
894 | ixgbe_link_speed speed = 0; | ||
895 | bool link_up = 0; | ||
896 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
897 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||
898 | |||
899 | /* | ||
900 | * Link must be up to auto-blink the LEDs on the 82598EB MAC; | ||
901 | * force it if link is down. | ||
902 | */ | ||
903 | hw->mac.ops.check_link(hw, &speed, &link_up, false); | ||
904 | |||
905 | if (!link_up) { | ||
906 | autoc_reg |= IXGBE_AUTOC_FLU; | ||
907 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | ||
908 | msleep(10); | ||
909 | } | ||
910 | |||
911 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | ||
912 | led_reg |= IXGBE_LED_BLINK(index); | ||
913 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | ||
914 | IXGBE_WRITE_FLUSH(hw); | ||
915 | |||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | /** | ||
920 | * ixgbe_blink_led_stop_82598 - Stop blinking LED based on index. | ||
921 | * @hw: pointer to hardware structure | ||
922 | * @index: led number to stop blinking | ||
923 | **/ | ||
924 | static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index) | ||
925 | { | ||
926 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
927 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||
928 | |||
929 | autoc_reg &= ~IXGBE_AUTOC_FLU; | ||
930 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | ||
931 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | ||
932 | |||
933 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | ||
934 | led_reg &= ~IXGBE_LED_BLINK(index); | ||
935 | led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); | ||
936 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | ||
937 | IXGBE_WRITE_FLUSH(hw); | ||
938 | |||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | /** | ||
943 | * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register | 888 | * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register |
944 | * @hw: pointer to hardware structure | 889 | * @hw: pointer to hardware structure |
945 | * @reg: analog register to read | 890 | * @reg: analog register to read |
@@ -1128,8 +1073,8 @@ static struct ixgbe_mac_operations mac_ops_82598 = { | |||
1128 | .get_link_capabilities = &ixgbe_get_link_capabilities_82598, | 1073 | .get_link_capabilities = &ixgbe_get_link_capabilities_82598, |
1129 | .led_on = &ixgbe_led_on_generic, | 1074 | .led_on = &ixgbe_led_on_generic, |
1130 | .led_off = &ixgbe_led_off_generic, | 1075 | .led_off = &ixgbe_led_off_generic, |
1131 | .blink_led_start = &ixgbe_blink_led_start_82598, | 1076 | .blink_led_start = &ixgbe_blink_led_start_generic, |
1132 | .blink_led_stop = &ixgbe_blink_led_stop_82598, | 1077 | .blink_led_stop = &ixgbe_blink_led_stop_generic, |
1133 | .set_rar = &ixgbe_set_rar_generic, | 1078 | .set_rar = &ixgbe_set_rar_generic, |
1134 | .clear_rar = &ixgbe_clear_rar_generic, | 1079 | .clear_rar = &ixgbe_clear_rar_generic, |
1135 | .set_vmdq = &ixgbe_set_vmdq_82598, | 1080 | .set_vmdq = &ixgbe_set_vmdq_82598, |
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index beae7e012609..29771fbaa42d 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -68,8 +68,6 @@ s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq); | |||
68 | s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, | 68 | s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, |
69 | u32 vind, bool vlan_on); | 69 | u32 vind, bool vlan_on); |
70 | s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw); | 70 | s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw); |
71 | s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index); | ||
72 | s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index); | ||
73 | s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw); | 71 | s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw); |
74 | s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val); | 72 | s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val); |
75 | s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val); | 73 | s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val); |
@@ -991,40 +989,6 @@ s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw) | |||
991 | } | 989 | } |
992 | 990 | ||
993 | /** | 991 | /** |
994 | * ixgbe_blink_led_start_82599 - Blink LED based on index. | ||
995 | * @hw: pointer to hardware structure | ||
996 | * @index: led number to blink | ||
997 | **/ | ||
998 | s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index) | ||
999 | { | ||
1000 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||
1001 | |||
1002 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | ||
1003 | led_reg |= IXGBE_LED_BLINK(index); | ||
1004 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | ||
1005 | IXGBE_WRITE_FLUSH(hw); | ||
1006 | |||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | /** | ||
1011 | * ixgbe_blink_led_stop_82599 - Stop blinking LED based on index. | ||
1012 | * @hw: pointer to hardware structure | ||
1013 | * @index: led number to stop blinking | ||
1014 | **/ | ||
1015 | s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index) | ||
1016 | { | ||
1017 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||
1018 | |||
1019 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | ||
1020 | led_reg &= ~IXGBE_LED_BLINK(index); | ||
1021 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | ||
1022 | IXGBE_WRITE_FLUSH(hw); | ||
1023 | |||
1024 | return 0; | ||
1025 | } | ||
1026 | |||
1027 | /** | ||
1028 | * ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array | 992 | * ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array |
1029 | * @hw: pointer to hardware structure | 993 | * @hw: pointer to hardware structure |
1030 | **/ | 994 | **/ |
@@ -1243,8 +1207,8 @@ static struct ixgbe_mac_operations mac_ops_82599 = { | |||
1243 | .get_link_capabilities = &ixgbe_get_link_capabilities_82599, | 1207 | .get_link_capabilities = &ixgbe_get_link_capabilities_82599, |
1244 | .led_on = &ixgbe_led_on_generic, | 1208 | .led_on = &ixgbe_led_on_generic, |
1245 | .led_off = &ixgbe_led_off_generic, | 1209 | .led_off = &ixgbe_led_off_generic, |
1246 | .blink_led_start = &ixgbe_blink_led_start_82599, | 1210 | .blink_led_start = &ixgbe_blink_led_start_generic, |
1247 | .blink_led_stop = &ixgbe_blink_led_stop_82599, | 1211 | .blink_led_stop = &ixgbe_blink_led_stop_generic, |
1248 | .set_rar = &ixgbe_set_rar_generic, | 1212 | .set_rar = &ixgbe_set_rar_generic, |
1249 | .clear_rar = &ixgbe_clear_rar_generic, | 1213 | .clear_rar = &ixgbe_clear_rar_generic, |
1250 | .set_vmdq = &ixgbe_set_vmdq_82599, | 1214 | .set_vmdq = &ixgbe_set_vmdq_82599, |
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 63ab6671d08e..5567519676d5 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
@@ -2071,3 +2071,58 @@ s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval) | |||
2071 | 2071 | ||
2072 | return 0; | 2072 | return 0; |
2073 | } | 2073 | } |
2074 | |||
2075 | /** | ||
2076 | * ixgbe_blink_led_start_generic - Blink LED based on index. | ||
2077 | * @hw: pointer to hardware structure | ||
2078 | * @index: led number to blink | ||
2079 | **/ | ||
2080 | s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) | ||
2081 | { | ||
2082 | ixgbe_link_speed speed = 0; | ||
2083 | bool link_up = 0; | ||
2084 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
2085 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||
2086 | |||
2087 | /* | ||
2088 | * Link must be up to auto-blink the LEDs; | ||
2089 | * Force it if link is down. | ||
2090 | */ | ||
2091 | hw->mac.ops.check_link(hw, &speed, &link_up, false); | ||
2092 | |||
2093 | if (!link_up) { | ||
2094 | autoc_reg |= IXGBE_AUTOC_FLU; | ||
2095 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | ||
2096 | msleep(10); | ||
2097 | } | ||
2098 | |||
2099 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | ||
2100 | led_reg |= IXGBE_LED_BLINK(index); | ||
2101 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | ||
2102 | IXGBE_WRITE_FLUSH(hw); | ||
2103 | |||
2104 | return 0; | ||
2105 | } | ||
2106 | |||
2107 | /** | ||
2108 | * ixgbe_blink_led_stop_generic - Stop blinking LED based on index. | ||
2109 | * @hw: pointer to hardware structure | ||
2110 | * @index: led number to stop blinking | ||
2111 | **/ | ||
2112 | s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) | ||
2113 | { | ||
2114 | u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); | ||
2115 | u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); | ||
2116 | |||
2117 | autoc_reg &= ~IXGBE_AUTOC_FLU; | ||
2118 | autoc_reg |= IXGBE_AUTOC_AN_RESTART; | ||
2119 | IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); | ||
2120 | |||
2121 | led_reg &= ~IXGBE_LED_MODE_MASK(index); | ||
2122 | led_reg &= ~IXGBE_LED_BLINK(index); | ||
2123 | led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); | ||
2124 | IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); | ||
2125 | IXGBE_WRITE_FLUSH(hw); | ||
2126 | |||
2127 | return 0; | ||
2128 | } | ||
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 24f73e719c3f..dd260890ad0a 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h | |||
@@ -76,6 +76,9 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw); | |||
76 | s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val); | 76 | s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val); |
77 | s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val); | 77 | s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val); |
78 | 78 | ||
79 | s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); | ||
80 | s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); | ||
81 | |||
79 | #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg))) | 82 | #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg))) |
80 | 83 | ||
81 | #ifndef writeq | 84 | #ifndef writeq |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 470b676c1dae..f4417fc3b0fd 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c | |||
@@ -290,7 +290,7 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, | |||
290 | s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, | 290 | s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, |
291 | struct ixgbe_dcb_config *dcb_config) | 291 | struct ixgbe_dcb_config *dcb_config) |
292 | { | 292 | { |
293 | u32 i, reg; | 293 | u32 i, reg, rx_pba_size; |
294 | 294 | ||
295 | /* If PFC is disabled globally then fall back to LFC. */ | 295 | /* If PFC is disabled globally then fall back to LFC. */ |
296 | if (!dcb_config->pfc_mode_enable) { | 296 | if (!dcb_config->pfc_mode_enable) { |
@@ -301,17 +301,23 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, | |||
301 | 301 | ||
302 | /* Configure PFC Tx thresholds per TC */ | 302 | /* Configure PFC Tx thresholds per TC */ |
303 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | 303 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
304 | /* Config and remember Tx */ | 304 | if (dcb_config->rx_pba_cfg == pba_equal) |
305 | rx_pba_size = IXGBE_RXPBSIZE_64KB; | ||
306 | else | ||
307 | rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB | ||
308 | : IXGBE_RXPBSIZE_48KB; | ||
309 | |||
310 | reg = ((rx_pba_size >> 5) & 0xFFE0); | ||
305 | if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || | 311 | if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || |
306 | dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) { | 312 | dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) |
307 | reg = hw->fc.high_water | IXGBE_FCRTH_FCEN; | 313 | reg |= IXGBE_FCRTL_XONE; |
308 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); | 314 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); |
309 | reg = hw->fc.low_water | IXGBE_FCRTL_XONE; | 315 | |
310 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); | 316 | reg = ((rx_pba_size >> 2) & 0xFFE0); |
311 | } else { | 317 | if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || |
312 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0); | 318 | dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) |
313 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0); | 319 | reg |= IXGBE_FCRTH_FCEN; |
314 | } | 320 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg); |
315 | } | 321 | } |
316 | 322 | ||
317 | /* Configure pause time (2 TCs per register) */ | 323 | /* Configure pause time (2 TCs per register) */ |
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index aafc120f164e..f0a20facc650 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -943,6 +943,24 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, | |||
943 | } | 943 | } |
944 | 944 | ||
945 | 945 | ||
946 | static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, | ||
947 | struct ethtool_wolinfo *wol) | ||
948 | { | ||
949 | struct ixgbe_hw *hw = &adapter->hw; | ||
950 | int retval = 1; | ||
951 | |||
952 | switch(hw->device_id) { | ||
953 | case IXGBE_DEV_ID_82599_KX4: | ||
954 | retval = 0; | ||
955 | break; | ||
956 | default: | ||
957 | wol->supported = 0; | ||
958 | retval = 0; | ||
959 | } | ||
960 | |||
961 | return retval; | ||
962 | } | ||
963 | |||
946 | static void ixgbe_get_wol(struct net_device *netdev, | 964 | static void ixgbe_get_wol(struct net_device *netdev, |
947 | struct ethtool_wolinfo *wol) | 965 | struct ethtool_wolinfo *wol) |
948 | { | 966 | { |
@@ -952,7 +970,8 @@ static void ixgbe_get_wol(struct net_device *netdev, | |||
952 | WAKE_BCAST | WAKE_MAGIC; | 970 | WAKE_BCAST | WAKE_MAGIC; |
953 | wol->wolopts = 0; | 971 | wol->wolopts = 0; |
954 | 972 | ||
955 | if (!device_can_wakeup(&adapter->pdev->dev)) | 973 | if (ixgbe_wol_exclusion(adapter, wol) || |
974 | !device_can_wakeup(&adapter->pdev->dev)) | ||
956 | return; | 975 | return; |
957 | 976 | ||
958 | if (adapter->wol & IXGBE_WUFC_EX) | 977 | if (adapter->wol & IXGBE_WUFC_EX) |
@@ -974,6 +993,9 @@ static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
974 | if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) | 993 | if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) |
975 | return -EOPNOTSUPP; | 994 | return -EOPNOTSUPP; |
976 | 995 | ||
996 | if (ixgbe_wol_exclusion(adapter, wol)) | ||
997 | return wol->wolopts ? -EOPNOTSUPP : 0; | ||
998 | |||
977 | adapter->wol = 0; | 999 | adapter->wol = 0; |
978 | 1000 | ||
979 | if (wol->wolopts & WAKE_UCAST) | 1001 | if (wol->wolopts & WAKE_UCAST) |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 9ef128ae6458..01884256f4c9 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -2723,17 +2723,21 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) | |||
2723 | **/ | 2723 | **/ |
2724 | static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) | 2724 | static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) |
2725 | { | 2725 | { |
2726 | /* Start with base case */ | ||
2727 | adapter->num_rx_queues = 1; | ||
2728 | adapter->num_tx_queues = 1; | ||
2729 | |||
2730 | #ifdef CONFIG_IXGBE_DCB | 2726 | #ifdef CONFIG_IXGBE_DCB |
2731 | if (ixgbe_set_dcb_queues(adapter)) | 2727 | if (ixgbe_set_dcb_queues(adapter)) |
2732 | return; | 2728 | goto done; |
2733 | 2729 | ||
2734 | #endif | 2730 | #endif |
2735 | if (ixgbe_set_rss_queues(adapter)) | 2731 | if (ixgbe_set_rss_queues(adapter)) |
2736 | return; | 2732 | goto done; |
2733 | |||
2734 | /* fallback to base case */ | ||
2735 | adapter->num_rx_queues = 1; | ||
2736 | adapter->num_tx_queues = 1; | ||
2737 | |||
2738 | done: | ||
2739 | /* Notify the stack of the (possibly) reduced Tx Queue count. */ | ||
2740 | adapter->netdev->real_num_tx_queues = adapter->num_tx_queues; | ||
2737 | } | 2741 | } |
2738 | 2742 | ||
2739 | static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, | 2743 | static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, |
@@ -2837,11 +2841,55 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) | |||
2837 | } | 2841 | } |
2838 | ret = true; | 2842 | ret = true; |
2839 | } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | 2843 | } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { |
2840 | for (i = 0; i < dcb_i; i++) { | 2844 | if (dcb_i == 8) { |
2841 | adapter->rx_ring[i].reg_idx = i << 4; | 2845 | /* |
2842 | adapter->tx_ring[i].reg_idx = i << 4; | 2846 | * Tx TC0 starts at: descriptor queue 0 |
2847 | * Tx TC1 starts at: descriptor queue 32 | ||
2848 | * Tx TC2 starts at: descriptor queue 64 | ||
2849 | * Tx TC3 starts at: descriptor queue 80 | ||
2850 | * Tx TC4 starts at: descriptor queue 96 | ||
2851 | * Tx TC5 starts at: descriptor queue 104 | ||
2852 | * Tx TC6 starts at: descriptor queue 112 | ||
2853 | * Tx TC7 starts at: descriptor queue 120 | ||
2854 | * | ||
2855 | * Rx TC0-TC7 are offset by 16 queues each | ||
2856 | */ | ||
2857 | for (i = 0; i < 3; i++) { | ||
2858 | adapter->tx_ring[i].reg_idx = i << 5; | ||
2859 | adapter->rx_ring[i].reg_idx = i << 4; | ||
2860 | } | ||
2861 | for ( ; i < 5; i++) { | ||
2862 | adapter->tx_ring[i].reg_idx = | ||
2863 | ((i + 2) << 4); | ||
2864 | adapter->rx_ring[i].reg_idx = i << 4; | ||
2865 | } | ||
2866 | for ( ; i < dcb_i; i++) { | ||
2867 | adapter->tx_ring[i].reg_idx = | ||
2868 | ((i + 8) << 3); | ||
2869 | adapter->rx_ring[i].reg_idx = i << 4; | ||
2870 | } | ||
2871 | |||
2872 | ret = true; | ||
2873 | } else if (dcb_i == 4) { | ||
2874 | /* | ||
2875 | * Tx TC0 starts at: descriptor queue 0 | ||
2876 | * Tx TC1 starts at: descriptor queue 64 | ||
2877 | * Tx TC2 starts at: descriptor queue 96 | ||
2878 | * Tx TC3 starts at: descriptor queue 112 | ||
2879 | * | ||
2880 | * Rx TC0-TC3 are offset by 32 queues each | ||
2881 | */ | ||
2882 | adapter->tx_ring[0].reg_idx = 0; | ||
2883 | adapter->tx_ring[1].reg_idx = 64; | ||
2884 | adapter->tx_ring[2].reg_idx = 96; | ||
2885 | adapter->tx_ring[3].reg_idx = 112; | ||
2886 | for (i = 0 ; i < dcb_i; i++) | ||
2887 | adapter->rx_ring[i].reg_idx = i << 5; | ||
2888 | |||
2889 | ret = true; | ||
2890 | } else { | ||
2891 | ret = false; | ||
2843 | } | 2892 | } |
2844 | ret = true; | ||
2845 | } else { | 2893 | } else { |
2846 | ret = false; | 2894 | ret = false; |
2847 | } | 2895 | } |
@@ -2992,9 +3040,6 @@ try_msi: | |||
2992 | } | 3040 | } |
2993 | 3041 | ||
2994 | out: | 3042 | out: |
2995 | /* Notify the stack of the (possibly) reduced Tx Queue count. */ | ||
2996 | adapter->netdev->real_num_tx_queues = adapter->num_tx_queues; | ||
2997 | |||
2998 | return err; | 3043 | return err; |
2999 | } | 3044 | } |
3000 | 3045 | ||
@@ -3611,9 +3656,9 @@ static int ixgbe_resume(struct pci_dev *pdev) | |||
3611 | 3656 | ||
3612 | return 0; | 3657 | return 0; |
3613 | } | 3658 | } |
3614 | |||
3615 | #endif /* CONFIG_PM */ | 3659 | #endif /* CONFIG_PM */ |
3616 | static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) | 3660 | |
3661 | static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) | ||
3617 | { | 3662 | { |
3618 | struct net_device *netdev = pci_get_drvdata(pdev); | 3663 | struct net_device *netdev = pci_get_drvdata(pdev); |
3619 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 3664 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
@@ -3672,18 +3717,46 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3672 | pci_enable_wake(pdev, PCI_D3cold, 0); | 3717 | pci_enable_wake(pdev, PCI_D3cold, 0); |
3673 | } | 3718 | } |
3674 | 3719 | ||
3720 | *enable_wake = !!wufc; | ||
3721 | |||
3675 | ixgbe_release_hw_control(adapter); | 3722 | ixgbe_release_hw_control(adapter); |
3676 | 3723 | ||
3677 | pci_disable_device(pdev); | 3724 | pci_disable_device(pdev); |
3678 | 3725 | ||
3679 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 3726 | return 0; |
3727 | } | ||
3728 | |||
3729 | #ifdef CONFIG_PM | ||
3730 | static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) | ||
3731 | { | ||
3732 | int retval; | ||
3733 | bool wake; | ||
3734 | |||
3735 | retval = __ixgbe_shutdown(pdev, &wake); | ||
3736 | if (retval) | ||
3737 | return retval; | ||
3738 | |||
3739 | if (wake) { | ||
3740 | pci_prepare_to_sleep(pdev); | ||
3741 | } else { | ||
3742 | pci_wake_from_d3(pdev, false); | ||
3743 | pci_set_power_state(pdev, PCI_D3hot); | ||
3744 | } | ||
3680 | 3745 | ||
3681 | return 0; | 3746 | return 0; |
3682 | } | 3747 | } |
3748 | #endif /* CONFIG_PM */ | ||
3683 | 3749 | ||
3684 | static void ixgbe_shutdown(struct pci_dev *pdev) | 3750 | static void ixgbe_shutdown(struct pci_dev *pdev) |
3685 | { | 3751 | { |
3686 | ixgbe_suspend(pdev, PMSG_SUSPEND); | 3752 | bool wake; |
3753 | |||
3754 | __ixgbe_shutdown(pdev, &wake); | ||
3755 | |||
3756 | if (system_state == SYSTEM_POWER_OFF) { | ||
3757 | pci_wake_from_d3(pdev, wake); | ||
3758 | pci_set_power_state(pdev, PCI_D3hot); | ||
3759 | } | ||
3687 | } | 3760 | } |
3688 | 3761 | ||
3689 | /** | 3762 | /** |
@@ -3917,7 +3990,7 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) | |||
3917 | } | 3990 | } |
3918 | hw->mac.ops.setup_sfp(hw); | 3991 | hw->mac.ops.setup_sfp(hw); |
3919 | 3992 | ||
3920 | if (!adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK) | 3993 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) |
3921 | /* This will also work for DA Twinax connections */ | 3994 | /* This will also work for DA Twinax connections */ |
3922 | schedule_work(&adapter->multispeed_fiber_task); | 3995 | schedule_work(&adapter->multispeed_fiber_task); |
3923 | adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK; | 3996 | adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK; |
@@ -4342,7 +4415,7 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
4342 | int count = 0; | 4415 | int count = 0; |
4343 | unsigned int f; | 4416 | unsigned int f; |
4344 | 4417 | ||
4345 | r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping; | 4418 | r_idx = skb->queue_mapping; |
4346 | tx_ring = &adapter->tx_ring[r_idx]; | 4419 | tx_ring = &adapter->tx_ring[r_idx]; |
4347 | 4420 | ||
4348 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { | 4421 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { |
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index ece35040288c..621a7c0c46ba 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c | |||
@@ -2591,13 +2591,13 @@ static int | |||
2591 | jme_pci_dma64(struct pci_dev *pdev) | 2591 | jme_pci_dma64(struct pci_dev *pdev) |
2592 | { | 2592 | { |
2593 | if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 && | 2593 | if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 && |
2594 | !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) | 2594 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) |
2595 | if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) | 2595 | if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) |
2596 | return 1; | 2596 | return 1; |
2597 | 2597 | ||
2598 | if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 && | 2598 | if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 && |
2599 | !pci_set_dma_mask(pdev, DMA_40BIT_MASK)) | 2599 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(40))) |
2600 | if (!pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK)) | 2600 | if (!pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40))) |
2601 | return 1; | 2601 | return 1; |
2602 | 2602 | ||
2603 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) | 2603 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) |
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index 380a1a54d530..384e072de2e7 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c | |||
@@ -168,6 +168,17 @@ writereg(struct net_device *dev, int portno, int value) | |||
168 | nubus_writew(swab16(value), dev->mem_start + portno); | 168 | nubus_writew(swab16(value), dev->mem_start + portno); |
169 | } | 169 | } |
170 | 170 | ||
171 | static const struct net_device_ops mac89x0_netdev_ops = { | ||
172 | .ndo_open = net_open, | ||
173 | .ndo_stop = net_close, | ||
174 | .ndo_start_xmit = net_send_packet, | ||
175 | .ndo_get_stats = net_get_stats, | ||
176 | .ndo_set_multicast_list = set_multicast_list, | ||
177 | .ndo_set_mac_address = set_mac_address, | ||
178 | .ndo_validate_addr = eth_validate_addr, | ||
179 | .ndo_change_mtu = eth_change_mtu, | ||
180 | }; | ||
181 | |||
171 | /* Probe for the CS8900 card in slot E. We won't bother looking | 182 | /* Probe for the CS8900 card in slot E. We won't bother looking |
172 | anywhere else until we have a really good reason to do so. */ | 183 | anywhere else until we have a really good reason to do so. */ |
173 | struct net_device * __init mac89x0_probe(int unit) | 184 | struct net_device * __init mac89x0_probe(int unit) |
@@ -280,12 +291,7 @@ struct net_device * __init mac89x0_probe(int unit) | |||
280 | 291 | ||
281 | printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr); | 292 | printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr); |
282 | 293 | ||
283 | dev->open = net_open; | 294 | dev->netdev_ops = &mac89x0_netdev_ops; |
284 | dev->stop = net_close; | ||
285 | dev->hard_start_xmit = net_send_packet; | ||
286 | dev->get_stats = net_get_stats; | ||
287 | dev->set_multicast_list = &set_multicast_list; | ||
288 | dev->set_mac_address = &set_mac_address; | ||
289 | 295 | ||
290 | err = register_netdev(dev); | 296 | err = register_netdev(dev); |
291 | if (err) | 297 | if (err) |
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index f50501013b1c..e82aee41d77e 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c | |||
@@ -316,10 +316,11 @@ static void macb_tx(struct macb *bp) | |||
316 | dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n", | 316 | dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n", |
317 | (unsigned long)status); | 317 | (unsigned long)status); |
318 | 318 | ||
319 | if (status & MACB_BIT(UND)) { | 319 | if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) { |
320 | int i; | 320 | int i; |
321 | printk(KERN_ERR "%s: TX underrun, resetting buffers\n", | 321 | printk(KERN_ERR "%s: TX %s, resetting buffers\n", |
322 | bp->dev->name); | 322 | bp->dev->name, status & MACB_BIT(UND) ? |
323 | "underrun" : "retry limit exceeded"); | ||
323 | 324 | ||
324 | /* Transfer ongoing, disable transmitter, to avoid confusion */ | 325 | /* Transfer ongoing, disable transmitter, to avoid confusion */ |
325 | if (status & MACB_BIT(TGO)) | 326 | if (status & MACB_BIT(TGO)) |
@@ -520,27 +521,10 @@ static int macb_poll(struct napi_struct *napi, int budget) | |||
520 | macb_writel(bp, RSR, status); | 521 | macb_writel(bp, RSR, status); |
521 | 522 | ||
522 | work_done = 0; | 523 | work_done = 0; |
523 | if (!status) { | ||
524 | /* | ||
525 | * This may happen if an interrupt was pending before | ||
526 | * this function was called last time, and no packets | ||
527 | * have been received since. | ||
528 | */ | ||
529 | napi_complete(napi); | ||
530 | goto out; | ||
531 | } | ||
532 | 524 | ||
533 | dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n", | 525 | dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n", |
534 | (unsigned long)status, budget); | 526 | (unsigned long)status, budget); |
535 | 527 | ||
536 | if (!(status & MACB_BIT(REC))) { | ||
537 | dev_warn(&bp->pdev->dev, | ||
538 | "No RX buffers complete, status = %02lx\n", | ||
539 | (unsigned long)status); | ||
540 | napi_complete(napi); | ||
541 | goto out; | ||
542 | } | ||
543 | |||
544 | work_done = macb_rx(bp, budget); | 528 | work_done = macb_rx(bp, budget); |
545 | if (work_done < budget) | 529 | if (work_done < budget) |
546 | napi_complete(napi); | 530 | napi_complete(napi); |
@@ -549,7 +533,6 @@ static int macb_poll(struct napi_struct *napi, int budget) | |||
549 | * We've done what we can to clean the buffers. Make sure we | 533 | * We've done what we can to clean the buffers. Make sure we |
550 | * get notified when new packets arrive. | 534 | * get notified when new packets arrive. |
551 | */ | 535 | */ |
552 | out: | ||
553 | macb_writel(bp, IER, MACB_RX_INT_FLAGS); | 536 | macb_writel(bp, IER, MACB_RX_INT_FLAGS); |
554 | 537 | ||
555 | /* TODO: Handle errors */ | 538 | /* TODO: Handle errors */ |
@@ -590,7 +573,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
590 | } | 573 | } |
591 | } | 574 | } |
592 | 575 | ||
593 | if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND))) | 576 | if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) | |
577 | MACB_BIT(ISR_RLE))) | ||
594 | macb_tx(bp); | 578 | macb_tx(bp); |
595 | 579 | ||
596 | /* | 580 | /* |
@@ -1100,6 +1084,18 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
1100 | return phy_mii_ioctl(phydev, if_mii(rq), cmd); | 1084 | return phy_mii_ioctl(phydev, if_mii(rq), cmd); |
1101 | } | 1085 | } |
1102 | 1086 | ||
1087 | static const struct net_device_ops macb_netdev_ops = { | ||
1088 | .ndo_open = macb_open, | ||
1089 | .ndo_stop = macb_close, | ||
1090 | .ndo_start_xmit = macb_start_xmit, | ||
1091 | .ndo_set_multicast_list = macb_set_rx_mode, | ||
1092 | .ndo_get_stats = macb_get_stats, | ||
1093 | .ndo_do_ioctl = macb_ioctl, | ||
1094 | .ndo_validate_addr = eth_validate_addr, | ||
1095 | .ndo_change_mtu = eth_change_mtu, | ||
1096 | .ndo_set_mac_address = eth_mac_addr, | ||
1097 | }; | ||
1098 | |||
1103 | static int __init macb_probe(struct platform_device *pdev) | 1099 | static int __init macb_probe(struct platform_device *pdev) |
1104 | { | 1100 | { |
1105 | struct eth_platform_data *pdata; | 1101 | struct eth_platform_data *pdata; |
@@ -1175,12 +1171,7 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1175 | goto err_out_iounmap; | 1171 | goto err_out_iounmap; |
1176 | } | 1172 | } |
1177 | 1173 | ||
1178 | dev->open = macb_open; | 1174 | dev->netdev_ops = &macb_netdev_ops; |
1179 | dev->stop = macb_close; | ||
1180 | dev->hard_start_xmit = macb_start_xmit; | ||
1181 | dev->get_stats = macb_get_stats; | ||
1182 | dev->set_multicast_list = macb_set_rx_mode; | ||
1183 | dev->do_ioctl = macb_ioctl; | ||
1184 | netif_napi_add(dev, &bp->napi, macb_poll, 64); | 1175 | netif_napi_add(dev, &bp->napi, macb_poll, 64); |
1185 | dev->ethtool_ops = &macb_ethtool_ops; | 1176 | dev->ethtool_ops = &macb_ethtool_ops; |
1186 | 1177 | ||
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 527166e35d56..acd143da161d 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c | |||
@@ -167,6 +167,18 @@ static int macsonic_close(struct net_device* dev) | |||
167 | return err; | 167 | return err; |
168 | } | 168 | } |
169 | 169 | ||
170 | static const struct net_device_ops macsonic_netdev_ops = { | ||
171 | .ndo_open = macsonic_open, | ||
172 | .ndo_stop = macsonic_close, | ||
173 | .ndo_start_xmit = sonic_send_packet, | ||
174 | .ndo_set_multicast_list = sonic_multicast_list, | ||
175 | .ndo_tx_timeout = sonic_tx_timeout, | ||
176 | .ndo_get_stats = sonic_get_stats, | ||
177 | .ndo_validate_addr = eth_validate_addr, | ||
178 | .ndo_change_mtu = eth_change_mtu, | ||
179 | .ndo_set_mac_address = eth_mac_addr, | ||
180 | }; | ||
181 | |||
170 | static int __init macsonic_init(struct net_device *dev) | 182 | static int __init macsonic_init(struct net_device *dev) |
171 | { | 183 | { |
172 | struct sonic_local* lp = netdev_priv(dev); | 184 | struct sonic_local* lp = netdev_priv(dev); |
@@ -198,12 +210,7 @@ static int __init macsonic_init(struct net_device *dev) | |||
198 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | 210 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS |
199 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | 211 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
200 | 212 | ||
201 | dev->open = macsonic_open; | 213 | dev->netdev_ops = &macsonic_netdev_ops; |
202 | dev->stop = macsonic_close; | ||
203 | dev->hard_start_xmit = sonic_send_packet; | ||
204 | dev->get_stats = sonic_get_stats; | ||
205 | dev->set_multicast_list = &sonic_multicast_list; | ||
206 | dev->tx_timeout = sonic_tx_timeout; | ||
207 | dev->watchdog_timeo = TX_TIMEOUT; | 214 | dev->watchdog_timeo = TX_TIMEOUT; |
208 | 215 | ||
209 | /* | 216 | /* |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 70d3ef4a2c5f..214a8cf2b708 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -376,7 +376,8 @@ static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev) | |||
376 | const struct macvlan_dev *vlan = netdev_priv(dev); | 376 | const struct macvlan_dev *vlan = netdev_priv(dev); |
377 | struct net_device *lowerdev = vlan->lowerdev; | 377 | struct net_device *lowerdev = vlan->lowerdev; |
378 | 378 | ||
379 | if (lowerdev->ethtool_ops->get_rx_csum == NULL) | 379 | if (lowerdev->ethtool_ops == NULL || |
380 | lowerdev->ethtool_ops->get_rx_csum == NULL) | ||
380 | return 0; | 381 | return 0; |
381 | return lowerdev->ethtool_ops->get_rx_csum(lowerdev); | 382 | return lowerdev->ethtool_ops->get_rx_csum(lowerdev); |
382 | } | 383 | } |
@@ -387,7 +388,8 @@ static int macvlan_ethtool_get_settings(struct net_device *dev, | |||
387 | const struct macvlan_dev *vlan = netdev_priv(dev); | 388 | const struct macvlan_dev *vlan = netdev_priv(dev); |
388 | struct net_device *lowerdev = vlan->lowerdev; | 389 | struct net_device *lowerdev = vlan->lowerdev; |
389 | 390 | ||
390 | if (!lowerdev->ethtool_ops->get_settings) | 391 | if (!lowerdev->ethtool_ops || |
392 | !lowerdev->ethtool_ops->get_settings) | ||
391 | return -EOPNOTSUPP; | 393 | return -EOPNOTSUPP; |
392 | 394 | ||
393 | return lowerdev->ethtool_ops->get_settings(lowerdev, cmd); | 395 | return lowerdev->ethtool_ops->get_settings(lowerdev, cmd); |
@@ -398,7 +400,8 @@ static u32 macvlan_ethtool_get_flags(struct net_device *dev) | |||
398 | const struct macvlan_dev *vlan = netdev_priv(dev); | 400 | const struct macvlan_dev *vlan = netdev_priv(dev); |
399 | struct net_device *lowerdev = vlan->lowerdev; | 401 | struct net_device *lowerdev = vlan->lowerdev; |
400 | 402 | ||
401 | if (!lowerdev->ethtool_ops->get_flags) | 403 | if (!lowerdev->ethtool_ops || |
404 | !lowerdev->ethtool_ops->get_flags) | ||
402 | return 0; | 405 | return 0; |
403 | return lowerdev->ethtool_ops->get_flags(lowerdev); | 406 | return lowerdev->ethtool_ops->get_flags(lowerdev); |
404 | } | 407 | } |
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index eda72dd2120f..510633fd57f6 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c | |||
@@ -181,7 +181,7 @@ static void *mlx4_en_add(struct mlx4_dev *dev) | |||
181 | mdev->workqueue = create_singlethread_workqueue("mlx4_en"); | 181 | mdev->workqueue = create_singlethread_workqueue("mlx4_en"); |
182 | if (!mdev->workqueue) { | 182 | if (!mdev->workqueue) { |
183 | err = -ENOMEM; | 183 | err = -ENOMEM; |
184 | goto err_close_nic; | 184 | goto err_mr; |
185 | } | 185 | } |
186 | 186 | ||
187 | /* At this stage all non-port specific tasks are complete: | 187 | /* At this stage all non-port specific tasks are complete: |
@@ -214,9 +214,8 @@ err_free_netdev: | |||
214 | flush_workqueue(mdev->workqueue); | 214 | flush_workqueue(mdev->workqueue); |
215 | 215 | ||
216 | /* Stop event queue before we drop down to release shared SW state */ | 216 | /* Stop event queue before we drop down to release shared SW state */ |
217 | |||
218 | err_close_nic: | ||
219 | destroy_workqueue(mdev->workqueue); | 217 | destroy_workqueue(mdev->workqueue); |
218 | |||
220 | err_mr: | 219 | err_mr: |
221 | mlx4_mr_free(dev, &mdev->mr); | 220 | mlx4_mr_free(dev, &mdev->mr); |
222 | err_uar: | 221 | err_uar: |
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index 303c23de6cac..438678ab2a10 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c | |||
@@ -348,11 +348,9 @@ static void mlx4_en_tx_timeout(struct net_device *dev) | |||
348 | if (netif_msg_timer(priv)) | 348 | if (netif_msg_timer(priv)) |
349 | mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port); | 349 | mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port); |
350 | 350 | ||
351 | if (netif_carrier_ok(dev)) { | 351 | priv->port_stats.tx_timeout++; |
352 | priv->port_stats.tx_timeout++; | 352 | mlx4_dbg(DRV, priv, "Scheduling watchdog\n"); |
353 | mlx4_dbg(DRV, priv, "Scheduling watchdog\n"); | 353 | queue_work(mdev->workqueue, &priv->watchdog_task); |
354 | queue_work(mdev->workqueue, &priv->watchdog_task); | ||
355 | } | ||
356 | } | 354 | } |
357 | 355 | ||
358 | 356 | ||
@@ -761,9 +759,14 @@ static void mlx4_en_restart(struct work_struct *work) | |||
761 | struct net_device *dev = priv->dev; | 759 | struct net_device *dev = priv->dev; |
762 | 760 | ||
763 | mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port); | 761 | mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port); |
764 | mlx4_en_stop_port(dev); | 762 | |
765 | if (mlx4_en_start_port(dev)) | 763 | mutex_lock(&mdev->state_lock); |
766 | mlx4_err(mdev, "Failed restarting port %d\n", priv->port); | 764 | if (priv->port_up) { |
765 | mlx4_en_stop_port(dev); | ||
766 | if (mlx4_en_start_port(dev)) | ||
767 | mlx4_err(mdev, "Failed restarting port %d\n", priv->port); | ||
768 | } | ||
769 | mutex_unlock(&mdev->state_lock); | ||
767 | } | 770 | } |
768 | 771 | ||
769 | 772 | ||
@@ -1054,7 +1057,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
1054 | * Set driver features | 1057 | * Set driver features |
1055 | */ | 1058 | */ |
1056 | dev->features |= NETIF_F_SG; | 1059 | dev->features |= NETIF_F_SG; |
1057 | dev->features |= NETIF_F_HW_CSUM; | 1060 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; |
1058 | dev->features |= NETIF_F_HIGHDMA; | 1061 | dev->features |= NETIF_F_HIGHDMA; |
1059 | dev->features |= NETIF_F_HW_VLAN_TX | | 1062 | dev->features |= NETIF_F_HW_VLAN_TX | |
1060 | NETIF_F_HW_VLAN_RX | | 1063 | NETIF_F_HW_VLAN_RX | |
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c index c5a4c0389752..a29abe845d2e 100644 --- a/drivers/net/mlx4/en_port.c +++ b/drivers/net/mlx4/en_port.c | |||
@@ -151,6 +151,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) | |||
151 | struct mlx4_cmd_mailbox *mailbox; | 151 | struct mlx4_cmd_mailbox *mailbox; |
152 | u64 in_mod = reset << 8 | port; | 152 | u64 in_mod = reset << 8 | port; |
153 | int err; | 153 | int err; |
154 | int i; | ||
154 | 155 | ||
155 | mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); | 156 | mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); |
156 | if (IS_ERR(mailbox)) | 157 | if (IS_ERR(mailbox)) |
@@ -165,38 +166,18 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) | |||
165 | 166 | ||
166 | spin_lock_bh(&priv->stats_lock); | 167 | spin_lock_bh(&priv->stats_lock); |
167 | 168 | ||
168 | stats->rx_packets = be32_to_cpu(mlx4_en_stats->RTOTFRMS) - | 169 | stats->rx_packets = 0; |
169 | be32_to_cpu(mlx4_en_stats->RDROP); | 170 | stats->rx_bytes = 0; |
170 | stats->tx_packets = be64_to_cpu(mlx4_en_stats->TTOT_prio_0) + | 171 | for (i = 0; i < priv->rx_ring_num; i++) { |
171 | be64_to_cpu(mlx4_en_stats->TTOT_prio_1) + | 172 | stats->rx_packets += priv->rx_ring[i].packets; |
172 | be64_to_cpu(mlx4_en_stats->TTOT_prio_2) + | 173 | stats->rx_bytes += priv->rx_ring[i].bytes; |
173 | be64_to_cpu(mlx4_en_stats->TTOT_prio_3) + | 174 | } |
174 | be64_to_cpu(mlx4_en_stats->TTOT_prio_4) + | 175 | stats->tx_packets = 0; |
175 | be64_to_cpu(mlx4_en_stats->TTOT_prio_5) + | 176 | stats->tx_bytes = 0; |
176 | be64_to_cpu(mlx4_en_stats->TTOT_prio_6) + | 177 | for (i = 0; i <= priv->tx_ring_num; i++) { |
177 | be64_to_cpu(mlx4_en_stats->TTOT_prio_7) + | 178 | stats->tx_packets += priv->tx_ring[i].packets; |
178 | be64_to_cpu(mlx4_en_stats->TTOT_novlan) + | 179 | stats->tx_bytes += priv->tx_ring[i].bytes; |
179 | be64_to_cpu(mlx4_en_stats->TTOT_loopbk); | 180 | } |
180 | stats->rx_bytes = be64_to_cpu(mlx4_en_stats->ROCT_prio_0) + | ||
181 | be64_to_cpu(mlx4_en_stats->ROCT_prio_1) + | ||
182 | be64_to_cpu(mlx4_en_stats->ROCT_prio_2) + | ||
183 | be64_to_cpu(mlx4_en_stats->ROCT_prio_3) + | ||
184 | be64_to_cpu(mlx4_en_stats->ROCT_prio_4) + | ||
185 | be64_to_cpu(mlx4_en_stats->ROCT_prio_5) + | ||
186 | be64_to_cpu(mlx4_en_stats->ROCT_prio_6) + | ||
187 | be64_to_cpu(mlx4_en_stats->ROCT_prio_7) + | ||
188 | be64_to_cpu(mlx4_en_stats->ROCT_novlan); | ||
189 | |||
190 | stats->tx_bytes = be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_0) + | ||
191 | be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_1) + | ||
192 | be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_2) + | ||
193 | be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_3) + | ||
194 | be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_4) + | ||
195 | be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_5) + | ||
196 | be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_6) + | ||
197 | be64_to_cpu(mlx4_en_stats->TTTLOCT_prio_7) + | ||
198 | be64_to_cpu(mlx4_en_stats->TTTLOCT_novlan) + | ||
199 | be64_to_cpu(mlx4_en_stats->TTTLOCT_loopbk); | ||
200 | 181 | ||
201 | stats->rx_errors = be64_to_cpu(mlx4_en_stats->PCS) + | 182 | stats->rx_errors = be64_to_cpu(mlx4_en_stats->PCS) + |
202 | be32_to_cpu(mlx4_en_stats->RdropLength) + | 183 | be32_to_cpu(mlx4_en_stats->RdropLength) + |
diff --git a/drivers/net/mlx4/en_resources.c b/drivers/net/mlx4/en_resources.c index a0545209e507..65ca706c04bb 100644 --- a/drivers/net/mlx4/en_resources.c +++ b/drivers/net/mlx4/en_resources.c | |||
@@ -94,3 +94,9 @@ void mlx4_en_unmap_buffer(struct mlx4_buf *buf) | |||
94 | 94 | ||
95 | vunmap(buf->direct.buf); | 95 | vunmap(buf->direct.buf); |
96 | } | 96 | } |
97 | |||
98 | void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event) | ||
99 | { | ||
100 | return; | ||
101 | } | ||
102 | |||
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 7e40741fb7d8..0cbb78ca7b29 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c | |||
@@ -436,8 +436,9 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) | |||
436 | /* Initialize page allocators */ | 436 | /* Initialize page allocators */ |
437 | err = mlx4_en_init_allocator(priv, ring); | 437 | err = mlx4_en_init_allocator(priv, ring); |
438 | if (err) { | 438 | if (err) { |
439 | mlx4_err(mdev, "Failed initializing ring allocator\n"); | 439 | mlx4_err(mdev, "Failed initializing ring allocator\n"); |
440 | goto err_allocator; | 440 | ring_ind--; |
441 | goto err_allocator; | ||
441 | } | 442 | } |
442 | 443 | ||
443 | /* Fill Rx buffers */ | 444 | /* Fill Rx buffers */ |
@@ -467,6 +468,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) | |||
467 | ring->wqres.db.dma, &ring->srq); | 468 | ring->wqres.db.dma, &ring->srq); |
468 | if (err){ | 469 | if (err){ |
469 | mlx4_err(mdev, "Failed to allocate srq\n"); | 470 | mlx4_err(mdev, "Failed to allocate srq\n"); |
471 | ring_ind--; | ||
470 | goto err_srq; | 472 | goto err_srq; |
471 | } | 473 | } |
472 | ring->srq.event = mlx4_en_srq_event; | 474 | ring->srq.event = mlx4_en_srq_event; |
@@ -926,12 +928,6 @@ void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv, | |||
926 | } | 928 | } |
927 | } | 929 | } |
928 | 930 | ||
929 | static void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event) | ||
930 | { | ||
931 | return; | ||
932 | } | ||
933 | |||
934 | |||
935 | static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, | 931 | static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, |
936 | int qpn, int srqn, int cqn, | 932 | int qpn, int srqn, int cqn, |
937 | enum mlx4_qp_state *state, | 933 | enum mlx4_qp_state *state, |
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 4afd5993e31c..ac6fc499b280 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c | |||
@@ -112,6 +112,7 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, | |||
112 | mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn); | 112 | mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn); |
113 | goto err_reserve; | 113 | goto err_reserve; |
114 | } | 114 | } |
115 | ring->qp.event = mlx4_en_sqp_event; | ||
115 | 116 | ||
116 | return 0; | 117 | return 0; |
117 | 118 | ||
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index e9af32d41ca4..ef840abbcd39 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h | |||
@@ -538,6 +538,7 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget); | |||
538 | void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, | 538 | void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, |
539 | int is_tx, int rss, int qpn, int cqn, int srqn, | 539 | int is_tx, int rss, int qpn, int cqn, int srqn, |
540 | struct mlx4_qp_context *context); | 540 | struct mlx4_qp_context *context); |
541 | void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event); | ||
541 | int mlx4_en_map_buffer(struct mlx4_buf *buf); | 542 | int mlx4_en_map_buffer(struct mlx4_buf *buf); |
542 | void mlx4_en_unmap_buffer(struct mlx4_buf *buf); | 543 | void mlx4_en_unmap_buffer(struct mlx4_buf *buf); |
543 | 544 | ||
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 9eed126a82f0..f2c4a665e93f 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -2447,6 +2447,7 @@ static int myri10ge_open(struct net_device *dev) | |||
2447 | lro_mgr->lro_arr = ss->rx_done.lro_desc; | 2447 | lro_mgr->lro_arr = ss->rx_done.lro_desc; |
2448 | lro_mgr->get_frag_header = myri10ge_get_frag_header; | 2448 | lro_mgr->get_frag_header = myri10ge_get_frag_header; |
2449 | lro_mgr->max_aggr = myri10ge_lro_max_pkts; | 2449 | lro_mgr->max_aggr = myri10ge_lro_max_pkts; |
2450 | lro_mgr->frag_align_pad = 2; | ||
2450 | if (lro_mgr->max_aggr > MAX_SKB_FRAGS) | 2451 | if (lro_mgr->max_aggr > MAX_SKB_FRAGS) |
2451 | lro_mgr->max_aggr = MAX_SKB_FRAGS; | 2452 | lro_mgr->max_aggr = MAX_SKB_FRAGS; |
2452 | 2453 | ||
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 2fbf9f9ddd37..652a36888361 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -1758,7 +1758,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1758 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), | 1758 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), |
1759 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), | 1759 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), |
1760 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"), | 1760 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"), |
1761 | PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "LA-PCM.cis"), | 1761 | PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), |
1762 | PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"), | 1762 | PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"), |
1763 | PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"), | 1763 | PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"), |
1764 | PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"), | 1764 | PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"), |
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index cf24cc34debe..e7070515d2e3 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mii.h> | 19 | #include <linux/mii.h> |
20 | #include <linux/phy.h> | 20 | #include <linux/phy.h> |
21 | #include <linux/phy_fixed.h> | 21 | #include <linux/phy_fixed.h> |
22 | #include <linux/err.h> | ||
22 | 23 | ||
23 | #define MII_REGS_NUM 29 | 24 | #define MII_REGS_NUM 29 |
24 | 25 | ||
@@ -207,8 +208,8 @@ static int __init fixed_mdio_bus_init(void) | |||
207 | int ret; | 208 | int ret; |
208 | 209 | ||
209 | pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0); | 210 | pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0); |
210 | if (!pdev) { | 211 | if (IS_ERR(pdev)) { |
211 | ret = -ENOMEM; | 212 | ret = PTR_ERR(pdev); |
212 | goto err_pdev; | 213 | goto err_pdev; |
213 | } | 214 | } |
214 | 215 | ||
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index eb6411c4694f..7a3ec9d39a9a 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
@@ -69,6 +69,11 @@ | |||
69 | #define MII_M1111_COPPER 0 | 69 | #define MII_M1111_COPPER 0 |
70 | #define MII_M1111_FIBER 1 | 70 | #define MII_M1111_FIBER 1 |
71 | 71 | ||
72 | #define MII_88E1121_PHY_LED_CTRL 16 | ||
73 | #define MII_88E1121_PHY_LED_PAGE 3 | ||
74 | #define MII_88E1121_PHY_LED_DEF 0x0030 | ||
75 | #define MII_88E1121_PHY_PAGE 22 | ||
76 | |||
72 | #define MII_M1011_PHY_STATUS 0x11 | 77 | #define MII_M1011_PHY_STATUS 0x11 |
73 | #define MII_M1011_PHY_STATUS_1000 0x8000 | 78 | #define MII_M1011_PHY_STATUS_1000 0x8000 |
74 | #define MII_M1011_PHY_STATUS_100 0x4000 | 79 | #define MII_M1011_PHY_STATUS_100 0x4000 |
@@ -154,6 +159,30 @@ static int marvell_config_aneg(struct phy_device *phydev) | |||
154 | return err; | 159 | return err; |
155 | } | 160 | } |
156 | 161 | ||
162 | static int m88e1121_config_aneg(struct phy_device *phydev) | ||
163 | { | ||
164 | int err, temp; | ||
165 | |||
166 | err = phy_write(phydev, MII_BMCR, BMCR_RESET); | ||
167 | if (err < 0) | ||
168 | return err; | ||
169 | |||
170 | err = phy_write(phydev, MII_M1011_PHY_SCR, | ||
171 | MII_M1011_PHY_SCR_AUTO_CROSS); | ||
172 | if (err < 0) | ||
173 | return err; | ||
174 | |||
175 | temp = phy_read(phydev, MII_88E1121_PHY_PAGE); | ||
176 | |||
177 | phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); | ||
178 | phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); | ||
179 | phy_write(phydev, MII_88E1121_PHY_PAGE, temp); | ||
180 | |||
181 | err = genphy_config_aneg(phydev); | ||
182 | |||
183 | return err; | ||
184 | } | ||
185 | |||
157 | static int m88e1111_config_init(struct phy_device *phydev) | 186 | static int m88e1111_config_init(struct phy_device *phydev) |
158 | { | 187 | { |
159 | int err; | 188 | int err; |
@@ -429,6 +458,18 @@ static int marvell_read_status(struct phy_device *phydev) | |||
429 | return 0; | 458 | return 0; |
430 | } | 459 | } |
431 | 460 | ||
461 | static int m88e1121_did_interrupt(struct phy_device *phydev) | ||
462 | { | ||
463 | int imask; | ||
464 | |||
465 | imask = phy_read(phydev, MII_M1011_IEVENT); | ||
466 | |||
467 | if (imask & MII_M1011_IMASK_INIT) | ||
468 | return 1; | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
432 | static struct phy_driver marvell_drivers[] = { | 473 | static struct phy_driver marvell_drivers[] = { |
433 | { | 474 | { |
434 | .phy_id = 0x01410c60, | 475 | .phy_id = 0x01410c60, |
@@ -482,6 +523,19 @@ static struct phy_driver marvell_drivers[] = { | |||
482 | .driver = {.owner = THIS_MODULE,}, | 523 | .driver = {.owner = THIS_MODULE,}, |
483 | }, | 524 | }, |
484 | { | 525 | { |
526 | .phy_id = 0x01410cb0, | ||
527 | .phy_id_mask = 0xfffffff0, | ||
528 | .name = "Marvell 88E1121R", | ||
529 | .features = PHY_GBIT_FEATURES, | ||
530 | .flags = PHY_HAS_INTERRUPT, | ||
531 | .config_aneg = &m88e1121_config_aneg, | ||
532 | .read_status = &marvell_read_status, | ||
533 | .ack_interrupt = &marvell_ack_interrupt, | ||
534 | .config_intr = &marvell_config_intr, | ||
535 | .did_interrupt = &m88e1121_did_interrupt, | ||
536 | .driver = { .owner = THIS_MODULE }, | ||
537 | }, | ||
538 | { | ||
485 | .phy_id = 0x01410cd0, | 539 | .phy_id = 0x01410cd0, |
486 | .phy_id_mask = 0xfffffff0, | 540 | .phy_id_mask = 0xfffffff0, |
487 | .name = "Marvell 88E1145", | 541 | .name = "Marvell 88E1145", |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 3ff1f425f1bb..61755cbd978e 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -434,7 +434,7 @@ void phy_start_machine(struct phy_device *phydev, | |||
434 | phydev->adjust_state = handler; | 434 | phydev->adjust_state = handler; |
435 | 435 | ||
436 | INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine); | 436 | INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine); |
437 | schedule_delayed_work(&phydev->state_queue, jiffies + HZ); | 437 | schedule_delayed_work(&phydev->state_queue, HZ); |
438 | } | 438 | } |
439 | 439 | ||
440 | /** | 440 | /** |
@@ -655,6 +655,10 @@ static void phy_change(struct work_struct *work) | |||
655 | struct phy_device *phydev = | 655 | struct phy_device *phydev = |
656 | container_of(work, struct phy_device, phy_queue); | 656 | container_of(work, struct phy_device, phy_queue); |
657 | 657 | ||
658 | if (phydev->drv->did_interrupt && | ||
659 | !phydev->drv->did_interrupt(phydev)) | ||
660 | goto ignore; | ||
661 | |||
658 | err = phy_disable_interrupts(phydev); | 662 | err = phy_disable_interrupts(phydev); |
659 | 663 | ||
660 | if (err) | 664 | if (err) |
@@ -681,6 +685,11 @@ static void phy_change(struct work_struct *work) | |||
681 | 685 | ||
682 | return; | 686 | return; |
683 | 687 | ||
688 | ignore: | ||
689 | atomic_dec(&phydev->irq_disable); | ||
690 | enable_irq(phydev->irq); | ||
691 | return; | ||
692 | |||
684 | irq_enable_err: | 693 | irq_enable_err: |
685 | disable_irq(phydev->irq); | 694 | disable_irq(phydev->irq); |
686 | atomic_inc(&phydev->irq_disable); | 695 | atomic_inc(&phydev->irq_disable); |
@@ -937,6 +946,5 @@ static void phy_state_machine(struct work_struct *work) | |||
937 | if (err < 0) | 946 | if (err < 0) |
938 | phy_error(phydev); | 947 | phy_error(phydev); |
939 | 948 | ||
940 | schedule_delayed_work(&phydev->state_queue, | 949 | schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ); |
941 | jiffies + PHY_STATE_TIME * HZ); | ||
942 | } | 950 | } |
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index a5ac2bd58b5b..4f3ada622f9b 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c | |||
@@ -2101,6 +2101,9 @@ static int gelic_wl_associate_bss(struct gelic_wl_info *wl, | |||
2101 | if (ret) { | 2101 | if (ret) { |
2102 | pr_debug("%s: WEP/WPA setup failed %d\n", __func__, | 2102 | pr_debug("%s: WEP/WPA setup failed %d\n", __func__, |
2103 | ret); | 2103 | ret); |
2104 | ret = -EPERM; | ||
2105 | gelic_wl_send_iwap_event(wl, NULL); | ||
2106 | goto out; | ||
2104 | } | 2107 | } |
2105 | 2108 | ||
2106 | /* start association */ | 2109 | /* start association */ |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index dee23b159df2..7269a426051c 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -448,9 +448,6 @@ static void efx_init_channels(struct efx_nic *efx) | |||
448 | 448 | ||
449 | WARN_ON(channel->rx_pkt != NULL); | 449 | WARN_ON(channel->rx_pkt != NULL); |
450 | efx_rx_strategy(channel); | 450 | efx_rx_strategy(channel); |
451 | |||
452 | netif_napi_add(channel->napi_dev, &channel->napi_str, | ||
453 | efx_poll, napi_weight); | ||
454 | } | 451 | } |
455 | } | 452 | } |
456 | 453 | ||
@@ -1321,6 +1318,8 @@ static int efx_init_napi(struct efx_nic *efx) | |||
1321 | 1318 | ||
1322 | efx_for_each_channel(channel, efx) { | 1319 | efx_for_each_channel(channel, efx) { |
1323 | channel->napi_dev = efx->net_dev; | 1320 | channel->napi_dev = efx->net_dev; |
1321 | netif_napi_add(channel->napi_dev, &channel->napi_str, | ||
1322 | efx_poll, napi_weight); | ||
1324 | } | 1323 | } |
1325 | return 0; | 1324 | return 0; |
1326 | } | 1325 | } |
@@ -1330,6 +1329,8 @@ static void efx_fini_napi(struct efx_nic *efx) | |||
1330 | struct efx_channel *channel; | 1329 | struct efx_channel *channel; |
1331 | 1330 | ||
1332 | efx_for_each_channel(channel, efx) { | 1331 | efx_for_each_channel(channel, efx) { |
1332 | if (channel->napi_dev) | ||
1333 | netif_napi_del(&channel->napi_str); | ||
1333 | channel->napi_dev = NULL; | 1334 | channel->napi_dev = NULL; |
1334 | } | 1335 | } |
1335 | } | 1336 | } |
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index d4629ab2c614..466a8abb0053 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c | |||
@@ -1176,9 +1176,9 @@ void falcon_sim_phy_event(struct efx_nic *efx) | |||
1176 | 1176 | ||
1177 | EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE); | 1177 | EFX_POPULATE_QWORD_1(phy_event, EV_CODE, GLOBAL_EV_DECODE); |
1178 | if (EFX_IS10G(efx)) | 1178 | if (EFX_IS10G(efx)) |
1179 | EFX_SET_OWORD_FIELD(phy_event, XG_PHY_INTR, 1); | 1179 | EFX_SET_QWORD_FIELD(phy_event, XG_PHY_INTR, 1); |
1180 | else | 1180 | else |
1181 | EFX_SET_OWORD_FIELD(phy_event, G_PHY0_INTR, 1); | 1181 | EFX_SET_QWORD_FIELD(phy_event, G_PHY0_INTR, 1); |
1182 | 1182 | ||
1183 | falcon_generate_event(&efx->channel[0], &phy_event); | 1183 | falcon_generate_event(&efx->channel[0], &phy_event); |
1184 | } | 1184 | } |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 7b1882765a0c..3ab28bb00c12 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -1188,6 +1188,19 @@ out: | |||
1188 | return ret; | 1188 | return ret; |
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | static const struct net_device_ops sh_eth_netdev_ops = { | ||
1192 | .ndo_open = sh_eth_open, | ||
1193 | .ndo_stop = sh_eth_close, | ||
1194 | .ndo_start_xmit = sh_eth_start_xmit, | ||
1195 | .ndo_get_stats = sh_eth_get_stats, | ||
1196 | .ndo_set_multicast_list = sh_eth_set_multicast_list, | ||
1197 | .ndo_tx_timeout = sh_eth_tx_timeout, | ||
1198 | .ndo_do_ioctl = sh_eth_do_ioctl, | ||
1199 | .ndo_validate_addr = eth_validate_addr, | ||
1200 | .ndo_set_mac_address = eth_mac_addr, | ||
1201 | .ndo_change_mtu = eth_change_mtu, | ||
1202 | }; | ||
1203 | |||
1191 | static int sh_eth_drv_probe(struct platform_device *pdev) | 1204 | static int sh_eth_drv_probe(struct platform_device *pdev) |
1192 | { | 1205 | { |
1193 | int ret, i, devno = 0; | 1206 | int ret, i, devno = 0; |
@@ -1240,13 +1253,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
1240 | mdp->edmac_endian = pd->edmac_endian; | 1253 | mdp->edmac_endian = pd->edmac_endian; |
1241 | 1254 | ||
1242 | /* set function */ | 1255 | /* set function */ |
1243 | ndev->open = sh_eth_open; | 1256 | ndev->netdev_ops = &sh_eth_netdev_ops; |
1244 | ndev->hard_start_xmit = sh_eth_start_xmit; | ||
1245 | ndev->stop = sh_eth_close; | ||
1246 | ndev->get_stats = sh_eth_get_stats; | ||
1247 | ndev->set_multicast_list = sh_eth_set_multicast_list; | ||
1248 | ndev->do_ioctl = sh_eth_do_ioctl; | ||
1249 | ndev->tx_timeout = sh_eth_tx_timeout; | ||
1250 | ndev->watchdog_timeo = TX_TIMEOUT; | 1257 | ndev->watchdog_timeo = TX_TIMEOUT; |
1251 | 1258 | ||
1252 | mdp->post_rx = POST_RX >> (devno << 1); | 1259 | mdp->post_rx = POST_RX >> (devno << 1); |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index b8978d4af1b7..c11cdd08ec57 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -2674,7 +2674,7 @@ static int skge_down(struct net_device *dev) | |||
2674 | if (netif_msg_ifdown(skge)) | 2674 | if (netif_msg_ifdown(skge)) |
2675 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 2675 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
2676 | 2676 | ||
2677 | netif_stop_queue(dev); | 2677 | netif_tx_disable(dev); |
2678 | 2678 | ||
2679 | if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC) | 2679 | if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC) |
2680 | del_timer_sync(&skge->link_timer); | 2680 | del_timer_sync(&skge->link_timer); |
@@ -2881,7 +2881,6 @@ static void skge_tx_clean(struct net_device *dev) | |||
2881 | } | 2881 | } |
2882 | 2882 | ||
2883 | skge->tx_ring.to_clean = e; | 2883 | skge->tx_ring.to_clean = e; |
2884 | netif_wake_queue(dev); | ||
2885 | } | 2884 | } |
2886 | 2885 | ||
2887 | static void skge_tx_timeout(struct net_device *dev) | 2886 | static void skge_tx_timeout(struct net_device *dev) |
@@ -2893,6 +2892,7 @@ static void skge_tx_timeout(struct net_device *dev) | |||
2893 | 2892 | ||
2894 | skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP); | 2893 | skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP); |
2895 | skge_tx_clean(dev); | 2894 | skge_tx_clean(dev); |
2895 | netif_wake_queue(dev); | ||
2896 | } | 2896 | } |
2897 | 2897 | ||
2898 | static int skge_change_mtu(struct net_device *dev, int new_mtu) | 2898 | static int skge_change_mtu(struct net_device *dev, int new_mtu) |
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c index e0d84772771c..a39c0b9ba8b6 100644 --- a/drivers/net/sun3_82586.c +++ b/drivers/net/sun3_82586.c | |||
@@ -331,6 +331,18 @@ out: | |||
331 | return ERR_PTR(err); | 331 | return ERR_PTR(err); |
332 | } | 332 | } |
333 | 333 | ||
334 | static const struct net_device_ops sun3_82586_netdev_ops = { | ||
335 | .ndo_open = sun3_82586_open, | ||
336 | .ndo_stop = sun3_82586_close, | ||
337 | .ndo_start_xmit = sun3_82586_send_packet, | ||
338 | .ndo_set_multicast_list = set_multicast_list, | ||
339 | .ndo_tx_timeout = sun3_82586_timeout, | ||
340 | .ndo_get_stats = sun3_82586_get_stats, | ||
341 | .ndo_validate_addr = eth_validate_addr, | ||
342 | .ndo_set_mac_address = eth_mac_addr, | ||
343 | .ndo_change_mtu = eth_change_mtu, | ||
344 | }; | ||
345 | |||
334 | static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr) | 346 | static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr) |
335 | { | 347 | { |
336 | int i, size, retval; | 348 | int i, size, retval; |
@@ -381,13 +393,8 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr) | |||
381 | 393 | ||
382 | printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq); | 394 | printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq); |
383 | 395 | ||
384 | dev->open = sun3_82586_open; | 396 | dev->netdev_ops = &sun3_82586_netdev_ops; |
385 | dev->stop = sun3_82586_close; | ||
386 | dev->get_stats = sun3_82586_get_stats; | ||
387 | dev->tx_timeout = sun3_82586_timeout; | ||
388 | dev->watchdog_timeo = HZ/20; | 397 | dev->watchdog_timeo = HZ/20; |
389 | dev->hard_start_xmit = sun3_82586_send_packet; | ||
390 | dev->set_multicast_list = set_multicast_list; | ||
391 | 398 | ||
392 | dev->if_port = 0; | 399 | dev->if_port = 0; |
393 | return 0; | 400 | return 0; |
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index d91e95b237b7..0ce2db6ce2bf 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -862,6 +862,22 @@ static int __devinit tc35815_init_dev_addr(struct net_device *dev) | |||
862 | return 0; | 862 | return 0; |
863 | } | 863 | } |
864 | 864 | ||
865 | static const struct net_device_ops tc35815_netdev_ops = { | ||
866 | .ndo_open = tc35815_open, | ||
867 | .ndo_stop = tc35815_close, | ||
868 | .ndo_start_xmit = tc35815_send_packet, | ||
869 | .ndo_get_stats = tc35815_get_stats, | ||
870 | .ndo_set_multicast_list = tc35815_set_multicast_list, | ||
871 | .ndo_tx_timeout = tc35815_tx_timeout, | ||
872 | .ndo_do_ioctl = tc35815_ioctl, | ||
873 | .ndo_validate_addr = eth_validate_addr, | ||
874 | .ndo_change_mtu = eth_change_mtu, | ||
875 | .ndo_set_mac_address = eth_mac_addr, | ||
876 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
877 | .ndo_poll_controller = tc35815_poll_controller, | ||
878 | #endif | ||
879 | }; | ||
880 | |||
865 | static int __devinit tc35815_init_one(struct pci_dev *pdev, | 881 | static int __devinit tc35815_init_one(struct pci_dev *pdev, |
866 | const struct pci_device_id *ent) | 882 | const struct pci_device_id *ent) |
867 | { | 883 | { |
@@ -904,21 +920,12 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev, | |||
904 | ioaddr = pcim_iomap_table(pdev)[1]; | 920 | ioaddr = pcim_iomap_table(pdev)[1]; |
905 | 921 | ||
906 | /* Initialize the device structure. */ | 922 | /* Initialize the device structure. */ |
907 | dev->open = tc35815_open; | 923 | dev->netdev_ops = &tc35815_netdev_ops; |
908 | dev->hard_start_xmit = tc35815_send_packet; | ||
909 | dev->stop = tc35815_close; | ||
910 | dev->get_stats = tc35815_get_stats; | ||
911 | dev->set_multicast_list = tc35815_set_multicast_list; | ||
912 | dev->do_ioctl = tc35815_ioctl; | ||
913 | dev->ethtool_ops = &tc35815_ethtool_ops; | 924 | dev->ethtool_ops = &tc35815_ethtool_ops; |
914 | dev->tx_timeout = tc35815_tx_timeout; | ||
915 | dev->watchdog_timeo = TC35815_TX_TIMEOUT; | 925 | dev->watchdog_timeo = TC35815_TX_TIMEOUT; |
916 | #ifdef TC35815_NAPI | 926 | #ifdef TC35815_NAPI |
917 | netif_napi_add(dev, &lp->napi, tc35815_poll, NAPI_WEIGHT); | 927 | netif_napi_add(dev, &lp->napi, tc35815_poll, NAPI_WEIGHT); |
918 | #endif | 928 | #endif |
919 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
920 | dev->poll_controller = tc35815_poll_controller; | ||
921 | #endif | ||
922 | 929 | ||
923 | dev->irq = pdev->irq; | 930 | dev->irq = pdev->irq; |
924 | dev->base_addr = (unsigned long)ioaddr; | 931 | dev->base_addr = (unsigned long)ioaddr; |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6a736dda3ee2..201be425643a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -2190,7 +2190,14 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp, | |||
2190 | if (!(tmp & EEPROM_ADDR_COMPLETE)) | 2190 | if (!(tmp & EEPROM_ADDR_COMPLETE)) |
2191 | return -EBUSY; | 2191 | return -EBUSY; |
2192 | 2192 | ||
2193 | *val = tr32(GRC_EEPROM_DATA); | 2193 | tmp = tr32(GRC_EEPROM_DATA); |
2194 | |||
2195 | /* | ||
2196 | * The data will always be opposite the native endian | ||
2197 | * format. Perform a blind byteswap to compensate. | ||
2198 | */ | ||
2199 | *val = swab32(tmp); | ||
2200 | |||
2194 | return 0; | 2201 | return 0; |
2195 | } | 2202 | } |
2196 | 2203 | ||
@@ -10663,7 +10670,13 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp, | |||
10663 | 10670 | ||
10664 | memcpy(&data, buf + i, 4); | 10671 | memcpy(&data, buf + i, 4); |
10665 | 10672 | ||
10666 | tw32(GRC_EEPROM_DATA, be32_to_cpu(data)); | 10673 | /* |
10674 | * The SEEPROM interface expects the data to always be opposite | ||
10675 | * the native endian format. We accomplish this by reversing | ||
10676 | * all the operations that would have been performed on the | ||
10677 | * data from a call to tg3_nvram_read_be32(). | ||
10678 | */ | ||
10679 | tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data))); | ||
10667 | 10680 | ||
10668 | val = tr32(GRC_EEPROM_ADDR); | 10681 | val = tr32(GRC_EEPROM_ADDR); |
10669 | tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE); | 10682 | tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE); |
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index bb43e7fb2a50..0f78f99f9b20 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c | |||
@@ -1561,6 +1561,18 @@ static const struct ethtool_ops tsi108_ethtool_ops = { | |||
1561 | .set_settings = tsi108_set_settings, | 1561 | .set_settings = tsi108_set_settings, |
1562 | }; | 1562 | }; |
1563 | 1563 | ||
1564 | static const struct net_device_ops tsi108_netdev_ops = { | ||
1565 | .ndo_open = tsi108_open, | ||
1566 | .ndo_stop = tsi108_close, | ||
1567 | .ndo_start_xmit = tsi108_send_packet, | ||
1568 | .ndo_set_multicast_list = tsi108_set_rx_mode, | ||
1569 | .ndo_get_stats = tsi108_get_stats, | ||
1570 | .ndo_do_ioctl = tsi108_do_ioctl, | ||
1571 | .ndo_set_mac_address = tsi108_set_mac, | ||
1572 | .ndo_validate_addr = eth_validate_addr, | ||
1573 | .ndo_change_mtu = eth_change_mtu, | ||
1574 | }; | ||
1575 | |||
1564 | static int | 1576 | static int |
1565 | tsi108_init_one(struct platform_device *pdev) | 1577 | tsi108_init_one(struct platform_device *pdev) |
1566 | { | 1578 | { |
@@ -1616,14 +1628,8 @@ tsi108_init_one(struct platform_device *pdev) | |||
1616 | data->phy_type = einfo->phy_type; | 1628 | data->phy_type = einfo->phy_type; |
1617 | data->irq_num = einfo->irq_num; | 1629 | data->irq_num = einfo->irq_num; |
1618 | data->id = pdev->id; | 1630 | data->id = pdev->id; |
1619 | dev->open = tsi108_open; | ||
1620 | dev->stop = tsi108_close; | ||
1621 | dev->hard_start_xmit = tsi108_send_packet; | ||
1622 | dev->set_mac_address = tsi108_set_mac; | ||
1623 | dev->set_multicast_list = tsi108_set_rx_mode; | ||
1624 | dev->get_stats = tsi108_get_stats; | ||
1625 | netif_napi_add(dev, &data->napi, tsi108_poll, 64); | 1631 | netif_napi_add(dev, &data->napi, tsi108_poll, 64); |
1626 | dev->do_ioctl = tsi108_do_ioctl; | 1632 | dev->netdev_ops = &tsi108_netdev_ops; |
1627 | dev->ethtool_ops = &tsi108_ethtool_ops; | 1633 | dev->ethtool_ops = &tsi108_ethtool_ops; |
1628 | 1634 | ||
1629 | /* Apparently, the Linux networking code won't use scatter-gather | 1635 | /* Apparently, the Linux networking code won't use scatter-gather |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a1b0697340ba..735bf41c654a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -93,7 +93,6 @@ struct tun_file { | |||
93 | atomic_t count; | 93 | atomic_t count; |
94 | struct tun_struct *tun; | 94 | struct tun_struct *tun; |
95 | struct net *net; | 95 | struct net *net; |
96 | wait_queue_head_t read_wait; | ||
97 | }; | 96 | }; |
98 | 97 | ||
99 | struct tun_sock; | 98 | struct tun_sock; |
@@ -156,6 +155,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file) | |||
156 | tfile->tun = tun; | 155 | tfile->tun = tun; |
157 | tun->tfile = tfile; | 156 | tun->tfile = tfile; |
158 | dev_hold(tun->dev); | 157 | dev_hold(tun->dev); |
158 | sock_hold(tun->sk); | ||
159 | atomic_inc(&tfile->count); | 159 | atomic_inc(&tfile->count); |
160 | 160 | ||
161 | out: | 161 | out: |
@@ -165,11 +165,8 @@ out: | |||
165 | 165 | ||
166 | static void __tun_detach(struct tun_struct *tun) | 166 | static void __tun_detach(struct tun_struct *tun) |
167 | { | 167 | { |
168 | struct tun_file *tfile = tun->tfile; | ||
169 | |||
170 | /* Detach from net device */ | 168 | /* Detach from net device */ |
171 | netif_tx_lock_bh(tun->dev); | 169 | netif_tx_lock_bh(tun->dev); |
172 | tfile->tun = NULL; | ||
173 | tun->tfile = NULL; | 170 | tun->tfile = NULL; |
174 | netif_tx_unlock_bh(tun->dev); | 171 | netif_tx_unlock_bh(tun->dev); |
175 | 172 | ||
@@ -333,12 +330,19 @@ static void tun_net_uninit(struct net_device *dev) | |||
333 | /* Inform the methods they need to stop using the dev. | 330 | /* Inform the methods they need to stop using the dev. |
334 | */ | 331 | */ |
335 | if (tfile) { | 332 | if (tfile) { |
336 | wake_up_all(&tfile->read_wait); | 333 | wake_up_all(&tun->socket.wait); |
337 | if (atomic_dec_and_test(&tfile->count)) | 334 | if (atomic_dec_and_test(&tfile->count)) |
338 | __tun_detach(tun); | 335 | __tun_detach(tun); |
339 | } | 336 | } |
340 | } | 337 | } |
341 | 338 | ||
339 | static void tun_free_netdev(struct net_device *dev) | ||
340 | { | ||
341 | struct tun_struct *tun = netdev_priv(dev); | ||
342 | |||
343 | sock_put(tun->sk); | ||
344 | } | ||
345 | |||
342 | /* Net device open. */ | 346 | /* Net device open. */ |
343 | static int tun_net_open(struct net_device *dev) | 347 | static int tun_net_open(struct net_device *dev) |
344 | { | 348 | { |
@@ -393,7 +397,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | |||
393 | /* Notify and wake up reader process */ | 397 | /* Notify and wake up reader process */ |
394 | if (tun->flags & TUN_FASYNC) | 398 | if (tun->flags & TUN_FASYNC) |
395 | kill_fasync(&tun->fasync, SIGIO, POLL_IN); | 399 | kill_fasync(&tun->fasync, SIGIO, POLL_IN); |
396 | wake_up_interruptible(&tun->tfile->read_wait); | 400 | wake_up_interruptible(&tun->socket.wait); |
397 | return 0; | 401 | return 0; |
398 | 402 | ||
399 | drop: | 403 | drop: |
@@ -490,7 +494,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) | |||
490 | 494 | ||
491 | DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); | 495 | DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); |
492 | 496 | ||
493 | poll_wait(file, &tfile->read_wait, wait); | 497 | poll_wait(file, &tun->socket.wait, wait); |
494 | 498 | ||
495 | if (!skb_queue_empty(&tun->readq)) | 499 | if (!skb_queue_empty(&tun->readq)) |
496 | mask |= POLLIN | POLLRDNORM; | 500 | mask |= POLLIN | POLLRDNORM; |
@@ -518,7 +522,7 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, | |||
518 | int err; | 522 | int err; |
519 | 523 | ||
520 | /* Under a page? Don't bother with paged skb. */ | 524 | /* Under a page? Don't bother with paged skb. */ |
521 | if (prepad + len < PAGE_SIZE) | 525 | if (prepad + len < PAGE_SIZE || !linear) |
522 | linear = len; | 526 | linear = len; |
523 | 527 | ||
524 | skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, | 528 | skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, |
@@ -565,7 +569,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, | |||
565 | 569 | ||
566 | if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { | 570 | if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { |
567 | align = NET_IP_ALIGN; | 571 | align = NET_IP_ALIGN; |
568 | if (unlikely(len < ETH_HLEN)) | 572 | if (unlikely(len < ETH_HLEN || |
573 | (gso.hdr_len && gso.hdr_len < ETH_HLEN))) | ||
569 | return -EINVAL; | 574 | return -EINVAL; |
570 | } | 575 | } |
571 | 576 | ||
@@ -762,7 +767,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, | |||
762 | goto out; | 767 | goto out; |
763 | } | 768 | } |
764 | 769 | ||
765 | add_wait_queue(&tfile->read_wait, &wait); | 770 | add_wait_queue(&tun->socket.wait, &wait); |
766 | while (len) { | 771 | while (len) { |
767 | current->state = TASK_INTERRUPTIBLE; | 772 | current->state = TASK_INTERRUPTIBLE; |
768 | 773 | ||
@@ -793,7 +798,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, | |||
793 | } | 798 | } |
794 | 799 | ||
795 | current->state = TASK_RUNNING; | 800 | current->state = TASK_RUNNING; |
796 | remove_wait_queue(&tfile->read_wait, &wait); | 801 | remove_wait_queue(&tun->socket.wait, &wait); |
797 | 802 | ||
798 | out: | 803 | out: |
799 | tun_put(tun); | 804 | tun_put(tun); |
@@ -810,7 +815,7 @@ static void tun_setup(struct net_device *dev) | |||
810 | tun->group = -1; | 815 | tun->group = -1; |
811 | 816 | ||
812 | dev->ethtool_ops = &tun_ethtool_ops; | 817 | dev->ethtool_ops = &tun_ethtool_ops; |
813 | dev->destructor = free_netdev; | 818 | dev->destructor = tun_free_netdev; |
814 | } | 819 | } |
815 | 820 | ||
816 | /* Trivial set of netlink ops to allow deleting tun or tap | 821 | /* Trivial set of netlink ops to allow deleting tun or tap |
@@ -847,7 +852,7 @@ static void tun_sock_write_space(struct sock *sk) | |||
847 | 852 | ||
848 | static void tun_sock_destruct(struct sock *sk) | 853 | static void tun_sock_destruct(struct sock *sk) |
849 | { | 854 | { |
850 | dev_put(container_of(sk, struct tun_sock, sk)->tun->dev); | 855 | free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev); |
851 | } | 856 | } |
852 | 857 | ||
853 | static struct proto tun_proto = { | 858 | static struct proto tun_proto = { |
@@ -861,7 +866,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
861 | struct sock *sk; | 866 | struct sock *sk; |
862 | struct tun_struct *tun; | 867 | struct tun_struct *tun; |
863 | struct net_device *dev; | 868 | struct net_device *dev; |
864 | struct tun_file *tfile = file->private_data; | ||
865 | int err; | 869 | int err; |
866 | 870 | ||
867 | dev = __dev_get_by_name(net, ifr->ifr_name); | 871 | dev = __dev_get_by_name(net, ifr->ifr_name); |
@@ -919,13 +923,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
919 | if (!sk) | 923 | if (!sk) |
920 | goto err_free_dev; | 924 | goto err_free_dev; |
921 | 925 | ||
922 | /* This ref count is for tun->sk. */ | 926 | init_waitqueue_head(&tun->socket.wait); |
923 | dev_hold(dev); | ||
924 | sock_init_data(&tun->socket, sk); | 927 | sock_init_data(&tun->socket, sk); |
925 | sk->sk_write_space = tun_sock_write_space; | 928 | sk->sk_write_space = tun_sock_write_space; |
926 | sk->sk_destruct = tun_sock_destruct; | ||
927 | sk->sk_sndbuf = INT_MAX; | 929 | sk->sk_sndbuf = INT_MAX; |
928 | sk->sk_sleep = &tfile->read_wait; | ||
929 | 930 | ||
930 | tun->sk = sk; | 931 | tun->sk = sk; |
931 | container_of(sk, struct tun_sock, sk)->tun = tun; | 932 | container_of(sk, struct tun_sock, sk)->tun = tun; |
@@ -941,11 +942,13 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
941 | err = -EINVAL; | 942 | err = -EINVAL; |
942 | err = register_netdevice(tun->dev); | 943 | err = register_netdevice(tun->dev); |
943 | if (err < 0) | 944 | if (err < 0) |
944 | goto err_free_dev; | 945 | goto err_free_sk; |
946 | |||
947 | sk->sk_destruct = tun_sock_destruct; | ||
945 | 948 | ||
946 | err = tun_attach(tun, file); | 949 | err = tun_attach(tun, file); |
947 | if (err < 0) | 950 | if (err < 0) |
948 | goto err_free_dev; | 951 | goto failed; |
949 | } | 952 | } |
950 | 953 | ||
951 | DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name); | 954 | DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name); |
@@ -1265,7 +1268,6 @@ static int tun_chr_open(struct inode *inode, struct file * file) | |||
1265 | atomic_set(&tfile->count, 0); | 1268 | atomic_set(&tfile->count, 0); |
1266 | tfile->tun = NULL; | 1269 | tfile->tun = NULL; |
1267 | tfile->net = get_net(current->nsproxy->net_ns); | 1270 | tfile->net = get_net(current->nsproxy->net_ns); |
1268 | init_waitqueue_head(&tfile->read_wait); | ||
1269 | file->private_data = tfile; | 1271 | file->private_data = tfile; |
1270 | return 0; | 1272 | return 0; |
1271 | } | 1273 | } |
@@ -1283,14 +1285,16 @@ static int tun_chr_close(struct inode *inode, struct file *file) | |||
1283 | __tun_detach(tun); | 1285 | __tun_detach(tun); |
1284 | 1286 | ||
1285 | /* If desireable, unregister the netdevice. */ | 1287 | /* If desireable, unregister the netdevice. */ |
1286 | if (!(tun->flags & TUN_PERSIST)) { | 1288 | if (!(tun->flags & TUN_PERSIST)) |
1287 | sock_put(tun->sk); | ||
1288 | unregister_netdevice(tun->dev); | 1289 | unregister_netdevice(tun->dev); |
1289 | } | ||
1290 | 1290 | ||
1291 | rtnl_unlock(); | 1291 | rtnl_unlock(); |
1292 | } | 1292 | } |
1293 | 1293 | ||
1294 | tun = tfile->tun; | ||
1295 | if (tun) | ||
1296 | sock_put(tun->sk); | ||
1297 | |||
1294 | put_net(tfile->net); | 1298 | put_net(tfile->net); |
1295 | kfree(tfile); | 1299 | kfree(tfile); |
1296 | 1300 | ||
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index d3f39e86eb95..44f8392da117 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -1394,7 +1394,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) | |||
1394 | (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) || | 1394 | (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) || |
1395 | (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) || | 1395 | (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) || |
1396 | (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { | 1396 | (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { |
1397 | upsmr |= UCC_GETH_UPSMR_RPM; | 1397 | if (ugeth->phy_interface != PHY_INTERFACE_MODE_RMII) |
1398 | upsmr |= UCC_GETH_UPSMR_RPM; | ||
1398 | switch (ugeth->max_speed) { | 1399 | switch (ugeth->max_speed) { |
1399 | case SPEED_10: | 1400 | case SPEED_10: |
1400 | upsmr |= UCC_GETH_UPSMR_R10M; | 1401 | upsmr |= UCC_GETH_UPSMR_R10M; |
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index a8228d87c8cf..2138535f2339 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c | |||
@@ -899,6 +899,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
899 | /* cleanup should already have been scheduled */ | 899 | /* cleanup should already have been scheduled */ |
900 | break; | 900 | break; |
901 | case -ENODEV: /* disconnect() upcoming */ | 901 | case -ENODEV: /* disconnect() upcoming */ |
902 | case -EPERM: | ||
902 | netif_device_detach(pegasus->net); | 903 | netif_device_detach(pegasus->net); |
903 | break; | 904 | break; |
904 | default: | 905 | default: |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index fb53ef872df3..754a4b182c1d 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -377,7 +377,7 @@ static void velocity_print_info(struct velocity_info *vptr); | |||
377 | static int velocity_open(struct net_device *dev); | 377 | static int velocity_open(struct net_device *dev); |
378 | static int velocity_change_mtu(struct net_device *dev, int mtu); | 378 | static int velocity_change_mtu(struct net_device *dev, int mtu); |
379 | static int velocity_xmit(struct sk_buff *skb, struct net_device *dev); | 379 | static int velocity_xmit(struct sk_buff *skb, struct net_device *dev); |
380 | static int velocity_intr(int irq, void *dev_instance); | 380 | static irqreturn_t velocity_intr(int irq, void *dev_instance); |
381 | static void velocity_set_multi(struct net_device *dev); | 381 | static void velocity_set_multi(struct net_device *dev); |
382 | static struct net_device_stats *velocity_get_stats(struct net_device *dev); | 382 | static struct net_device_stats *velocity_get_stats(struct net_device *dev); |
383 | static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 383 | static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
@@ -2215,7 +2215,7 @@ out: | |||
2215 | * efficiently as possible. | 2215 | * efficiently as possible. |
2216 | */ | 2216 | */ |
2217 | 2217 | ||
2218 | static int velocity_intr(int irq, void *dev_instance) | 2218 | static irqreturn_t velocity_intr(int irq, void *dev_instance) |
2219 | { | 2219 | { |
2220 | struct net_device *dev = dev_instance; | 2220 | struct net_device *dev = dev_instance; |
2221 | struct velocity_info *vptr = netdev_priv(dev); | 2221 | struct velocity_info *vptr = netdev_priv(dev); |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index f21a6171c691..c36d3a3d655f 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -6713,11 +6713,11 @@ static int airo_set_auth(struct net_device *dev, | |||
6713 | local->config.authType = AUTH_ENCRYPT; | 6713 | local->config.authType = AUTH_ENCRYPT; |
6714 | } else | 6714 | } else |
6715 | return -EINVAL; | 6715 | return -EINVAL; |
6716 | break; | ||
6717 | 6716 | ||
6718 | /* Commit the changes to flags if needed */ | 6717 | /* Commit the changes to flags if needed */ |
6719 | if (local->config.authType != currentAuthType) | 6718 | if (local->config.authType != currentAuthType) |
6720 | set_bit (FLAG_COMMIT, &local->flags); | 6719 | set_bit (FLAG_COMMIT, &local->flags); |
6720 | break; | ||
6721 | } | 6721 | } |
6722 | 6722 | ||
6723 | case IW_AUTH_WPA_ENABLED: | 6723 | case IW_AUTH_WPA_ENABLED: |
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h index 13091bd9d815..53e250a4278f 100644 --- a/drivers/net/wireless/ar9170/hw.h +++ b/drivers/net/wireless/ar9170/hw.h | |||
@@ -310,7 +310,7 @@ struct ar9170_tx_control { | |||
310 | 310 | ||
311 | struct ar9170_rx_head { | 311 | struct ar9170_rx_head { |
312 | u8 plcp[12]; | 312 | u8 plcp[12]; |
313 | }; | 313 | } __packed; |
314 | 314 | ||
315 | struct ar9170_rx_tail { | 315 | struct ar9170_rx_tail { |
316 | union { | 316 | union { |
@@ -318,16 +318,16 @@ struct ar9170_rx_tail { | |||
318 | u8 rssi_ant0, rssi_ant1, rssi_ant2, | 318 | u8 rssi_ant0, rssi_ant1, rssi_ant2, |
319 | rssi_ant0x, rssi_ant1x, rssi_ant2x, | 319 | rssi_ant0x, rssi_ant1x, rssi_ant2x, |
320 | rssi_combined; | 320 | rssi_combined; |
321 | }; | 321 | } __packed; |
322 | u8 rssi[7]; | 322 | u8 rssi[7]; |
323 | }; | 323 | } __packed; |
324 | 324 | ||
325 | u8 evm_stream0[6], evm_stream1[6]; | 325 | u8 evm_stream0[6], evm_stream1[6]; |
326 | u8 phy_err; | 326 | u8 phy_err; |
327 | u8 SAidx, DAidx; | 327 | u8 SAidx, DAidx; |
328 | u8 error; | 328 | u8 error; |
329 | u8 status; | 329 | u8 status; |
330 | }; | 330 | } __packed; |
331 | 331 | ||
332 | #define AR9170_ENC_ALG_NONE 0x0 | 332 | #define AR9170_ENC_ALG_NONE 0x0 |
333 | #define AR9170_ENC_ALG_WEP64 0x1 | 333 | #define AR9170_ENC_ALG_WEP64 0x1 |
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c index ad296840893e..fddda477095c 100644 --- a/drivers/net/wireless/ar9170/usb.c +++ b/drivers/net/wireless/ar9170/usb.c | |||
@@ -59,6 +59,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
59 | { USB_DEVICE(0x0cf3, 0x9170) }, | 59 | { USB_DEVICE(0x0cf3, 0x9170) }, |
60 | /* Atheros TG121N */ | 60 | /* Atheros TG121N */ |
61 | { USB_DEVICE(0x0cf3, 0x1001) }, | 61 | { USB_DEVICE(0x0cf3, 0x1001) }, |
62 | /* Cace Airpcap NX */ | ||
63 | { USB_DEVICE(0xcace, 0x0300) }, | ||
62 | /* D-Link DWA 160A */ | 64 | /* D-Link DWA 160A */ |
63 | { USB_DEVICE(0x07d1, 0x3c10) }, | 65 | { USB_DEVICE(0x07d1, 0x3c10) }, |
64 | /* Netgear WNDA3100 */ | 66 | /* Netgear WNDA3100 */ |
@@ -67,6 +69,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
67 | { USB_DEVICE(0x0846, 0x9001) }, | 69 | { USB_DEVICE(0x0846, 0x9001) }, |
68 | /* Zydas ZD1221 */ | 70 | /* Zydas ZD1221 */ |
69 | { USB_DEVICE(0x0ace, 0x1221) }, | 71 | { USB_DEVICE(0x0ace, 0x1221) }, |
72 | /* ZyXEL NWD271N */ | ||
73 | { USB_DEVICE(0x0586, 0x3417) }, | ||
70 | /* Z-Com UB81 BG */ | 74 | /* Z-Com UB81 BG */ |
71 | { USB_DEVICE(0x0cde, 0x0023) }, | 75 | { USB_DEVICE(0x0cde, 0x0023) }, |
72 | /* Z-Com UB82 ABG */ | 76 | /* Z-Com UB82 ABG */ |
@@ -619,6 +623,39 @@ static int ar9170_usb_open(struct ar9170 *ar) | |||
619 | return 0; | 623 | return 0; |
620 | } | 624 | } |
621 | 625 | ||
626 | static int ar9170_usb_init_device(struct ar9170_usb *aru) | ||
627 | { | ||
628 | int err; | ||
629 | |||
630 | err = ar9170_usb_alloc_rx_irq_urb(aru); | ||
631 | if (err) | ||
632 | goto err_out; | ||
633 | |||
634 | err = ar9170_usb_alloc_rx_bulk_urbs(aru); | ||
635 | if (err) | ||
636 | goto err_unrx; | ||
637 | |||
638 | err = ar9170_usb_upload_firmware(aru); | ||
639 | if (err) { | ||
640 | err = ar9170_echo_test(&aru->common, 0x60d43110); | ||
641 | if (err) { | ||
642 | /* force user invention, by disabling the device */ | ||
643 | err = usb_driver_set_configuration(aru->udev, -1); | ||
644 | dev_err(&aru->udev->dev, "device is in a bad state. " | ||
645 | "please reconnect it!\n"); | ||
646 | goto err_unrx; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | return 0; | ||
651 | |||
652 | err_unrx: | ||
653 | ar9170_usb_cancel_urbs(aru); | ||
654 | |||
655 | err_out: | ||
656 | return err; | ||
657 | } | ||
658 | |||
622 | static int ar9170_usb_probe(struct usb_interface *intf, | 659 | static int ar9170_usb_probe(struct usb_interface *intf, |
623 | const struct usb_device_id *id) | 660 | const struct usb_device_id *id) |
624 | { | 661 | { |
@@ -654,32 +691,16 @@ static int ar9170_usb_probe(struct usb_interface *intf, | |||
654 | 691 | ||
655 | err = ar9170_usb_reset(aru); | 692 | err = ar9170_usb_reset(aru); |
656 | if (err) | 693 | if (err) |
657 | goto err_unlock; | 694 | goto err_freehw; |
658 | 695 | ||
659 | err = ar9170_usb_request_firmware(aru); | 696 | err = ar9170_usb_request_firmware(aru); |
660 | if (err) | 697 | if (err) |
661 | goto err_unlock; | 698 | goto err_freehw; |
662 | 699 | ||
663 | err = ar9170_usb_alloc_rx_irq_urb(aru); | 700 | err = ar9170_usb_init_device(aru); |
664 | if (err) | 701 | if (err) |
665 | goto err_freefw; | 702 | goto err_freefw; |
666 | 703 | ||
667 | err = ar9170_usb_alloc_rx_bulk_urbs(aru); | ||
668 | if (err) | ||
669 | goto err_unrx; | ||
670 | |||
671 | err = ar9170_usb_upload_firmware(aru); | ||
672 | if (err) { | ||
673 | err = ar9170_echo_test(&aru->common, 0x60d43110); | ||
674 | if (err) { | ||
675 | /* force user invention, by disabling the device */ | ||
676 | err = usb_driver_set_configuration(aru->udev, -1); | ||
677 | dev_err(&aru->udev->dev, "device is in a bad state. " | ||
678 | "please reconnect it!\n"); | ||
679 | goto err_unrx; | ||
680 | } | ||
681 | } | ||
682 | |||
683 | err = ar9170_usb_open(ar); | 704 | err = ar9170_usb_open(ar); |
684 | if (err) | 705 | if (err) |
685 | goto err_unrx; | 706 | goto err_unrx; |
@@ -699,7 +720,7 @@ err_freefw: | |||
699 | release_firmware(aru->init_values); | 720 | release_firmware(aru->init_values); |
700 | release_firmware(aru->firmware); | 721 | release_firmware(aru->firmware); |
701 | 722 | ||
702 | err_unlock: | 723 | err_freehw: |
703 | usb_set_intfdata(intf, NULL); | 724 | usb_set_intfdata(intf, NULL); |
704 | usb_put_dev(udev); | 725 | usb_put_dev(udev); |
705 | ieee80211_free_hw(ar->hw); | 726 | ieee80211_free_hw(ar->hw); |
@@ -726,12 +747,65 @@ static void ar9170_usb_disconnect(struct usb_interface *intf) | |||
726 | ieee80211_free_hw(aru->common.hw); | 747 | ieee80211_free_hw(aru->common.hw); |
727 | } | 748 | } |
728 | 749 | ||
750 | #ifdef CONFIG_PM | ||
751 | static int ar9170_suspend(struct usb_interface *intf, | ||
752 | pm_message_t message) | ||
753 | { | ||
754 | struct ar9170_usb *aru = usb_get_intfdata(intf); | ||
755 | |||
756 | if (!aru) | ||
757 | return -ENODEV; | ||
758 | |||
759 | aru->common.state = AR9170_IDLE; | ||
760 | ar9170_usb_cancel_urbs(aru); | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static int ar9170_resume(struct usb_interface *intf) | ||
766 | { | ||
767 | struct ar9170_usb *aru = usb_get_intfdata(intf); | ||
768 | int err; | ||
769 | |||
770 | if (!aru) | ||
771 | return -ENODEV; | ||
772 | |||
773 | usb_unpoison_anchored_urbs(&aru->rx_submitted); | ||
774 | usb_unpoison_anchored_urbs(&aru->tx_submitted); | ||
775 | |||
776 | /* | ||
777 | * FIXME: firmware upload will fail on resume. | ||
778 | * but this is better than a hang! | ||
779 | */ | ||
780 | |||
781 | err = ar9170_usb_init_device(aru); | ||
782 | if (err) | ||
783 | goto err_unrx; | ||
784 | |||
785 | err = ar9170_usb_open(&aru->common); | ||
786 | if (err) | ||
787 | goto err_unrx; | ||
788 | |||
789 | return 0; | ||
790 | |||
791 | err_unrx: | ||
792 | aru->common.state = AR9170_IDLE; | ||
793 | ar9170_usb_cancel_urbs(aru); | ||
794 | |||
795 | return err; | ||
796 | } | ||
797 | #endif /* CONFIG_PM */ | ||
798 | |||
729 | static struct usb_driver ar9170_driver = { | 799 | static struct usb_driver ar9170_driver = { |
730 | .name = "ar9170usb", | 800 | .name = "ar9170usb", |
731 | .probe = ar9170_usb_probe, | 801 | .probe = ar9170_usb_probe, |
732 | .disconnect = ar9170_usb_disconnect, | 802 | .disconnect = ar9170_usb_disconnect, |
733 | .id_table = ar9170_usb_ids, | 803 | .id_table = ar9170_usb_ids, |
734 | .soft_unbind = 1, | 804 | .soft_unbind = 1, |
805 | #ifdef CONFIG_PM | ||
806 | .suspend = ar9170_suspend, | ||
807 | .resume = ar9170_resume, | ||
808 | #endif /* CONFIG_PM */ | ||
735 | }; | 809 | }; |
736 | 810 | ||
737 | static int __init ar9170_init(void) | 811 | static int __init ar9170_init(void) |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 0c02f1c2bd94..744f4f4dd3d1 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -250,6 +250,8 @@ static struct usb_device_id dev_table[] = { | |||
250 | { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) }, | 250 | { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) }, |
251 | /* Siemens Gigaset USB WLAN Adapter 11 */ | 251 | /* Siemens Gigaset USB WLAN Adapter 11 */ |
252 | { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) }, | 252 | { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) }, |
253 | /* OQO Model 01+ Internal Wi-Fi */ | ||
254 | { USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A) }, | ||
253 | /* | 255 | /* |
254 | * at76c505amx-rfmd | 256 | * at76c505amx-rfmd |
255 | */ | 257 | */ |
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c index 6dbc58580abb..168411d322a2 100644 --- a/drivers/net/wireless/ath9k/pci.c +++ b/drivers/net/wireless/ath9k/pci.c | |||
@@ -93,14 +93,14 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
93 | if (pci_enable_device(pdev)) | 93 | if (pci_enable_device(pdev)) |
94 | return -EIO; | 94 | return -EIO; |
95 | 95 | ||
96 | ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 96 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
97 | 97 | ||
98 | if (ret) { | 98 | if (ret) { |
99 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); | 99 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); |
100 | goto bad; | 100 | goto bad; |
101 | } | 101 | } |
102 | 102 | ||
103 | ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | 103 | ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
104 | 104 | ||
105 | if (ret) { | 105 | if (ret) { |
106 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | 106 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 71cb18d6757d..dd1f30156740 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -493,6 +493,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
493 | int hdrlen, padsize, retval; | 493 | int hdrlen, padsize, retval; |
494 | bool decrypt_error = false; | 494 | bool decrypt_error = false; |
495 | u8 keyix; | 495 | u8 keyix; |
496 | __le16 fc; | ||
496 | 497 | ||
497 | spin_lock_bh(&sc->rx.rxbuflock); | 498 | spin_lock_bh(&sc->rx.rxbuflock); |
498 | 499 | ||
@@ -606,6 +607,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
606 | /* see if any padding is done by the hw and remove it */ | 607 | /* see if any padding is done by the hw and remove it */ |
607 | hdr = (struct ieee80211_hdr *)skb->data; | 608 | hdr = (struct ieee80211_hdr *)skb->data; |
608 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 609 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
610 | fc = hdr->frame_control; | ||
609 | 611 | ||
610 | /* The MAC header is padded to have 32-bit boundary if the | 612 | /* The MAC header is padded to have 32-bit boundary if the |
611 | * packet payload is non-zero. The general calculation for | 613 | * packet payload is non-zero. The general calculation for |
@@ -690,7 +692,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
690 | sc->rx.rxotherant = 0; | 692 | sc->rx.rxotherant = 0; |
691 | } | 693 | } |
692 | 694 | ||
693 | if (ieee80211_is_beacon(hdr->frame_control) && | 695 | if (ieee80211_is_beacon(fc) && |
694 | (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) { | 696 | (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) { |
695 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | 697 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; |
696 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | 698 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 857d84148b1d..27eef8fb7107 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -1502,7 +1502,6 @@ static const struct net_device_ops atmel_netdev_ops = { | |||
1502 | .ndo_set_mac_address = atmel_set_mac_address, | 1502 | .ndo_set_mac_address = atmel_set_mac_address, |
1503 | .ndo_start_xmit = start_tx, | 1503 | .ndo_start_xmit = start_tx, |
1504 | .ndo_do_ioctl = atmel_ioctl, | 1504 | .ndo_do_ioctl = atmel_ioctl, |
1505 | .ndo_change_mtu = eth_change_mtu, | ||
1506 | .ndo_validate_addr = eth_validate_addr, | 1505 | .ndo_validate_addr = eth_validate_addr, |
1507 | }; | 1506 | }; |
1508 | 1507 | ||
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index e228c1de6e11..eae680b53052 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -555,11 +555,32 @@ address_error: | |||
555 | return 1; | 555 | return 1; |
556 | } | 556 | } |
557 | 557 | ||
558 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) | ||
559 | { | ||
560 | unsigned char *f = skb->data + ring->frameoffset; | ||
561 | |||
562 | return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) == 0xFF); | ||
563 | } | ||
564 | |||
565 | static void b43_poison_rx_buffer(struct b43_dmaring *ring, struct sk_buff *skb) | ||
566 | { | ||
567 | struct b43_rxhdr_fw4 *rxhdr; | ||
568 | unsigned char *frame; | ||
569 | |||
570 | /* This poisons the RX buffer to detect DMA failures. */ | ||
571 | |||
572 | rxhdr = (struct b43_rxhdr_fw4 *)(skb->data); | ||
573 | rxhdr->frame_len = 0; | ||
574 | |||
575 | B43_WARN_ON(ring->rx_buffersize < ring->frameoffset + sizeof(struct b43_plcp_hdr6) + 2); | ||
576 | frame = skb->data + ring->frameoffset; | ||
577 | memset(frame, 0xFF, sizeof(struct b43_plcp_hdr6) + 2 /* padding */); | ||
578 | } | ||
579 | |||
558 | static int setup_rx_descbuffer(struct b43_dmaring *ring, | 580 | static int setup_rx_descbuffer(struct b43_dmaring *ring, |
559 | struct b43_dmadesc_generic *desc, | 581 | struct b43_dmadesc_generic *desc, |
560 | struct b43_dmadesc_meta *meta, gfp_t gfp_flags) | 582 | struct b43_dmadesc_meta *meta, gfp_t gfp_flags) |
561 | { | 583 | { |
562 | struct b43_rxhdr_fw4 *rxhdr; | ||
563 | dma_addr_t dmaaddr; | 584 | dma_addr_t dmaaddr; |
564 | struct sk_buff *skb; | 585 | struct sk_buff *skb; |
565 | 586 | ||
@@ -568,6 +589,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
568 | skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); | 589 | skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); |
569 | if (unlikely(!skb)) | 590 | if (unlikely(!skb)) |
570 | return -ENOMEM; | 591 | return -ENOMEM; |
592 | b43_poison_rx_buffer(ring, skb); | ||
571 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); | 593 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); |
572 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { | 594 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
573 | /* ugh. try to realloc in zone_dma */ | 595 | /* ugh. try to realloc in zone_dma */ |
@@ -578,6 +600,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
578 | skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); | 600 | skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); |
579 | if (unlikely(!skb)) | 601 | if (unlikely(!skb)) |
580 | return -ENOMEM; | 602 | return -ENOMEM; |
603 | b43_poison_rx_buffer(ring, skb); | ||
581 | dmaaddr = map_descbuffer(ring, skb->data, | 604 | dmaaddr = map_descbuffer(ring, skb->data, |
582 | ring->rx_buffersize, 0); | 605 | ring->rx_buffersize, 0); |
583 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { | 606 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
@@ -592,9 +615,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
592 | ring->ops->fill_descriptor(ring, desc, dmaaddr, | 615 | ring->ops->fill_descriptor(ring, desc, dmaaddr, |
593 | ring->rx_buffersize, 0, 0, 0); | 616 | ring->rx_buffersize, 0, 0, 0); |
594 | 617 | ||
595 | rxhdr = (struct b43_rxhdr_fw4 *)(skb->data); | ||
596 | rxhdr->frame_len = 0; | ||
597 | |||
598 | return 0; | 618 | return 0; |
599 | } | 619 | } |
600 | 620 | ||
@@ -1483,12 +1503,17 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) | |||
1483 | len = le16_to_cpu(rxhdr->frame_len); | 1503 | len = le16_to_cpu(rxhdr->frame_len); |
1484 | } while (len == 0 && i++ < 5); | 1504 | } while (len == 0 && i++ < 5); |
1485 | if (unlikely(len == 0)) { | 1505 | if (unlikely(len == 0)) { |
1486 | /* recycle the descriptor buffer. */ | 1506 | dmaaddr = meta->dmaaddr; |
1487 | sync_descbuffer_for_device(ring, meta->dmaaddr, | 1507 | goto drop_recycle_buffer; |
1488 | ring->rx_buffersize); | ||
1489 | goto drop; | ||
1490 | } | 1508 | } |
1491 | } | 1509 | } |
1510 | if (unlikely(b43_rx_buffer_is_poisoned(ring, skb))) { | ||
1511 | /* Something went wrong with the DMA. | ||
1512 | * The device did not touch the buffer and did not overwrite the poison. */ | ||
1513 | b43dbg(ring->dev->wl, "DMA RX: Dropping poisoned buffer.\n"); | ||
1514 | dmaaddr = meta->dmaaddr; | ||
1515 | goto drop_recycle_buffer; | ||
1516 | } | ||
1492 | if (unlikely(len > ring->rx_buffersize)) { | 1517 | if (unlikely(len > ring->rx_buffersize)) { |
1493 | /* The data did not fit into one descriptor buffer | 1518 | /* The data did not fit into one descriptor buffer |
1494 | * and is split over multiple buffers. | 1519 | * and is split over multiple buffers. |
@@ -1501,6 +1526,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) | |||
1501 | while (1) { | 1526 | while (1) { |
1502 | desc = ops->idx2desc(ring, *slot, &meta); | 1527 | desc = ops->idx2desc(ring, *slot, &meta); |
1503 | /* recycle the descriptor buffer. */ | 1528 | /* recycle the descriptor buffer. */ |
1529 | b43_poison_rx_buffer(ring, meta->skb); | ||
1504 | sync_descbuffer_for_device(ring, meta->dmaaddr, | 1530 | sync_descbuffer_for_device(ring, meta->dmaaddr, |
1505 | ring->rx_buffersize); | 1531 | ring->rx_buffersize); |
1506 | *slot = next_slot(ring, *slot); | 1532 | *slot = next_slot(ring, *slot); |
@@ -1519,8 +1545,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) | |||
1519 | err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC); | 1545 | err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC); |
1520 | if (unlikely(err)) { | 1546 | if (unlikely(err)) { |
1521 | b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n"); | 1547 | b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n"); |
1522 | sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); | 1548 | goto drop_recycle_buffer; |
1523 | goto drop; | ||
1524 | } | 1549 | } |
1525 | 1550 | ||
1526 | unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); | 1551 | unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); |
@@ -1530,6 +1555,11 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) | |||
1530 | b43_rx(ring->dev, skb, rxhdr); | 1555 | b43_rx(ring->dev, skb, rxhdr); |
1531 | drop: | 1556 | drop: |
1532 | return; | 1557 | return; |
1558 | |||
1559 | drop_recycle_buffer: | ||
1560 | /* Poison and recycle the RX buffer. */ | ||
1561 | b43_poison_rx_buffer(ring, skb); | ||
1562 | sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); | ||
1533 | } | 1563 | } |
1534 | 1564 | ||
1535 | void b43_dma_rx(struct b43_dmaring *ring) | 1565 | void b43_dma_rx(struct b43_dmaring *ring) |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 4896e0831114..79b685e300c7 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3974,6 +3974,11 @@ static void setup_struct_phy_for_init(struct b43_wldev *dev, | |||
3974 | phy->next_txpwr_check_time = jiffies; | 3974 | phy->next_txpwr_check_time = jiffies; |
3975 | /* PHY TX errors counter. */ | 3975 | /* PHY TX errors counter. */ |
3976 | atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); | 3976 | atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); |
3977 | |||
3978 | #if B43_DEBUG | ||
3979 | phy->phy_locked = 0; | ||
3980 | phy->radio_locked = 0; | ||
3981 | #endif | ||
3977 | } | 3982 | } |
3978 | 3983 | ||
3979 | static void setup_struct_wldev_for_init(struct b43_wldev *dev) | 3984 | static void setup_struct_wldev_for_init(struct b43_wldev *dev) |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 026b61c03fb9..e176b6e0d9cf 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -131,12 +131,16 @@ void b43_radio_lock(struct b43_wldev *dev) | |||
131 | { | 131 | { |
132 | u32 macctl; | 132 | u32 macctl; |
133 | 133 | ||
134 | #if B43_DEBUG | ||
135 | B43_WARN_ON(dev->phy.radio_locked); | ||
136 | dev->phy.radio_locked = 1; | ||
137 | #endif | ||
138 | |||
134 | macctl = b43_read32(dev, B43_MMIO_MACCTL); | 139 | macctl = b43_read32(dev, B43_MMIO_MACCTL); |
135 | B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK); | ||
136 | macctl |= B43_MACCTL_RADIOLOCK; | 140 | macctl |= B43_MACCTL_RADIOLOCK; |
137 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 141 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
138 | /* Commit the write and wait for the device | 142 | /* Commit the write and wait for the firmware |
139 | * to exit any radio register access. */ | 143 | * to finish any radio register access. */ |
140 | b43_read32(dev, B43_MMIO_MACCTL); | 144 | b43_read32(dev, B43_MMIO_MACCTL); |
141 | udelay(10); | 145 | udelay(10); |
142 | } | 146 | } |
@@ -145,11 +149,15 @@ void b43_radio_unlock(struct b43_wldev *dev) | |||
145 | { | 149 | { |
146 | u32 macctl; | 150 | u32 macctl; |
147 | 151 | ||
152 | #if B43_DEBUG | ||
153 | B43_WARN_ON(!dev->phy.radio_locked); | ||
154 | dev->phy.radio_locked = 0; | ||
155 | #endif | ||
156 | |||
148 | /* Commit any write */ | 157 | /* Commit any write */ |
149 | b43_read16(dev, B43_MMIO_PHY_VER); | 158 | b43_read16(dev, B43_MMIO_PHY_VER); |
150 | /* unlock */ | 159 | /* unlock */ |
151 | macctl = b43_read32(dev, B43_MMIO_MACCTL); | 160 | macctl = b43_read32(dev, B43_MMIO_MACCTL); |
152 | B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK)); | ||
153 | macctl &= ~B43_MACCTL_RADIOLOCK; | 161 | macctl &= ~B43_MACCTL_RADIOLOCK; |
154 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 162 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
155 | } | 163 | } |
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index c9f5430d1d7d..b2d99101947b 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h | |||
@@ -245,8 +245,10 @@ struct b43_phy { | |||
245 | atomic_t txerr_cnt; | 245 | atomic_t txerr_cnt; |
246 | 246 | ||
247 | #ifdef CONFIG_B43_DEBUG | 247 | #ifdef CONFIG_B43_DEBUG |
248 | /* PHY registers locked by b43_phy_lock()? */ | 248 | /* PHY registers locked (w.r.t. firmware) */ |
249 | bool phy_locked; | 249 | bool phy_locked; |
250 | /* Radio registers locked (w.r.t. firmware) */ | ||
251 | bool radio_locked; | ||
250 | #endif /* B43_DEBUG */ | 252 | #endif /* B43_DEBUG */ |
251 | }; | 253 | }; |
252 | 254 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 2399328e8de7..527525cc0919 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -1192,7 +1192,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv) | |||
1192 | return -ENOMEM; | 1192 | return -ENOMEM; |
1193 | } | 1193 | } |
1194 | } else | 1194 | } else |
1195 | iwl_rx_queue_reset(priv, rxq); | 1195 | iwl3945_rx_queue_reset(priv, rxq); |
1196 | 1196 | ||
1197 | iwl3945_rx_replenish(priv); | 1197 | iwl3945_rx_replenish(priv); |
1198 | 1198 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index ab7aaf6872c7..55188844657b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -215,6 +215,7 @@ extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); | |||
215 | extern int iwl3945_tx_queue_init(struct iwl_priv *priv, | 215 | extern int iwl3945_tx_queue_init(struct iwl_priv *priv, |
216 | struct iwl_tx_queue *txq, int count, u32 id); | 216 | struct iwl_tx_queue *txq, int count, u32 id); |
217 | extern void iwl3945_rx_replenish(void *data); | 217 | extern void iwl3945_rx_replenish(void *data); |
218 | extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | ||
218 | extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 219 | extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
219 | extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, | 220 | extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, |
220 | const void *data); | 221 | const void *data); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3889158b359c..1ef4192207a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -976,11 +976,9 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
976 | 976 | ||
977 | rxq->queue[i] = NULL; | 977 | rxq->queue[i] = NULL; |
978 | 978 | ||
979 | dma_sync_single_range_for_cpu( | 979 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, |
980 | &priv->pci_dev->dev, rxb->real_dma_addr, | 980 | priv->hw_params.rx_buf_size + 256, |
981 | rxb->aligned_dma_addr - rxb->real_dma_addr, | 981 | PCI_DMA_FROMDEVICE); |
982 | priv->hw_params.rx_buf_size, | ||
983 | PCI_DMA_FROMDEVICE); | ||
984 | pkt = (struct iwl_rx_packet *)rxb->skb->data; | 982 | pkt = (struct iwl_rx_packet *)rxb->skb->data; |
985 | 983 | ||
986 | /* Reclaim a command buffer only if this packet is a response | 984 | /* Reclaim a command buffer only if this packet is a response |
@@ -1031,9 +1029,6 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
1031 | rxb->skb = NULL; | 1029 | rxb->skb = NULL; |
1032 | } | 1030 | } |
1033 | 1031 | ||
1034 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, | ||
1035 | priv->hw_params.rx_buf_size + 256, | ||
1036 | PCI_DMA_FROMDEVICE); | ||
1037 | spin_lock_irqsave(&rxq->lock, flags); | 1032 | spin_lock_irqsave(&rxq->lock, flags); |
1038 | list_add_tail(&rxb->list, &priv->rxq.rx_used); | 1033 | list_add_tail(&rxb->list, &priv->rxq.rx_used); |
1039 | spin_unlock_irqrestore(&rxq->lock, flags); | 1034 | spin_unlock_irqrestore(&rxq->lock, flags); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 2f1242447b3b..6e983149b83b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -223,7 +223,7 @@ | |||
223 | #define CSR_EEPROM_REG_MSK_DATA (0xFFFF0000) | 223 | #define CSR_EEPROM_REG_MSK_DATA (0xFFFF0000) |
224 | 224 | ||
225 | /* EEPROM GP */ | 225 | /* EEPROM GP */ |
226 | #define CSR_EEPROM_GP_VALID_MSK (0x00000006) | 226 | #define CSR_EEPROM_GP_VALID_MSK (0x00000007) |
227 | #define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000) | 227 | #define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000) |
228 | #define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180) | 228 | #define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180) |
229 | 229 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ec9a13846edd..cf7f0db58fcf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -360,12 +360,16 @@ struct iwl_host_cmd { | |||
360 | 360 | ||
361 | /** | 361 | /** |
362 | * struct iwl_rx_queue - Rx queue | 362 | * struct iwl_rx_queue - Rx queue |
363 | * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) | ||
364 | * @dma_addr: bus address of buffer of receive buffer descriptors (rbd) | ||
363 | * @read: Shared index to newest available Rx buffer | 365 | * @read: Shared index to newest available Rx buffer |
364 | * @write: Shared index to oldest written Rx packet | 366 | * @write: Shared index to oldest written Rx packet |
365 | * @free_count: Number of pre-allocated buffers in rx_free | 367 | * @free_count: Number of pre-allocated buffers in rx_free |
366 | * @rx_free: list of free SKBs for use | 368 | * @rx_free: list of free SKBs for use |
367 | * @rx_used: List of Rx buffers with no SKB | 369 | * @rx_used: List of Rx buffers with no SKB |
368 | * @need_update: flag to indicate we need to update read/write index | 370 | * @need_update: flag to indicate we need to update read/write index |
371 | * @rb_stts: driver's pointer to receive buffer status | ||
372 | * @rb_stts_dma: bus address of receive buffer status | ||
369 | * | 373 | * |
370 | * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers | 374 | * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers |
371 | */ | 375 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1f117a49c569..71d5b8a1a73e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -799,6 +799,22 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
799 | /* Copy MAC header from skb into command buffer */ | 799 | /* Copy MAC header from skb into command buffer */ |
800 | memcpy(tx_cmd->hdr, hdr, hdr_len); | 800 | memcpy(tx_cmd->hdr, hdr, hdr_len); |
801 | 801 | ||
802 | |||
803 | /* Total # bytes to be transmitted */ | ||
804 | len = (u16)skb->len; | ||
805 | tx_cmd->len = cpu_to_le16(len); | ||
806 | |||
807 | if (info->control.hw_key) | ||
808 | iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); | ||
809 | |||
810 | /* TODO need this for burst mode later on */ | ||
811 | iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id); | ||
812 | |||
813 | /* set is_hcca to 0; it probably will never be implemented */ | ||
814 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); | ||
815 | |||
816 | iwl_update_tx_stats(priv, le16_to_cpu(fc), len); | ||
817 | |||
802 | /* | 818 | /* |
803 | * Use the first empty entry in this queue's command buffer array | 819 | * Use the first empty entry in this queue's command buffer array |
804 | * to contain the Tx command and MAC header concatenated together | 820 | * to contain the Tx command and MAC header concatenated together |
@@ -819,21 +835,30 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
819 | else | 835 | else |
820 | len_org = 0; | 836 | len_org = 0; |
821 | 837 | ||
838 | /* Tell NIC about any 2-byte padding after MAC header */ | ||
839 | if (len_org) | ||
840 | tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; | ||
841 | |||
822 | /* Physical address of this Tx command's header (not MAC header!), | 842 | /* Physical address of this Tx command's header (not MAC header!), |
823 | * within command buffer array. */ | 843 | * within command buffer array. */ |
824 | txcmd_phys = pci_map_single(priv->pci_dev, | 844 | txcmd_phys = pci_map_single(priv->pci_dev, |
825 | out_cmd, sizeof(struct iwl_cmd), | 845 | &out_cmd->hdr, len, |
826 | PCI_DMA_BIDIRECTIONAL); | 846 | PCI_DMA_BIDIRECTIONAL); |
827 | pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); | 847 | pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); |
828 | pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd)); | 848 | pci_unmap_len_set(&out_cmd->meta, len, len); |
829 | /* Add buffer containing Tx command and MAC(!) header to TFD's | 849 | /* Add buffer containing Tx command and MAC(!) header to TFD's |
830 | * first entry */ | 850 | * first entry */ |
831 | txcmd_phys += offsetof(struct iwl_cmd, hdr); | ||
832 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, | 851 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
833 | txcmd_phys, len, 1, 0); | 852 | txcmd_phys, len, 1, 0); |
834 | 853 | ||
835 | if (info->control.hw_key) | 854 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
836 | iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); | 855 | txq->need_update = 1; |
856 | if (qc) | ||
857 | priv->stations[sta_id].tid[tid].seq_number = seq_number; | ||
858 | } else { | ||
859 | wait_write_ptr = 1; | ||
860 | txq->need_update = 0; | ||
861 | } | ||
837 | 862 | ||
838 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 863 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
839 | * if any (802.11 null frames have no payload). */ | 864 | * if any (802.11 null frames have no payload). */ |
@@ -846,41 +871,29 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
846 | 0, 0); | 871 | 0, 0); |
847 | } | 872 | } |
848 | 873 | ||
849 | /* Tell NIC about any 2-byte padding after MAC header */ | ||
850 | if (len_org) | ||
851 | tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; | ||
852 | |||
853 | /* Total # bytes to be transmitted */ | ||
854 | len = (u16)skb->len; | ||
855 | tx_cmd->len = cpu_to_le16(len); | ||
856 | /* TODO need this for burst mode later on */ | ||
857 | iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id); | ||
858 | |||
859 | /* set is_hcca to 0; it probably will never be implemented */ | ||
860 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); | ||
861 | |||
862 | iwl_update_tx_stats(priv, le16_to_cpu(fc), len); | ||
863 | |||
864 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + | 874 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + |
865 | offsetof(struct iwl_tx_cmd, scratch); | 875 | offsetof(struct iwl_tx_cmd, scratch); |
876 | |||
877 | len = sizeof(struct iwl_tx_cmd) + | ||
878 | sizeof(struct iwl_cmd_header) + hdr_len; | ||
879 | /* take back ownership of DMA buffer to enable update */ | ||
880 | pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys, | ||
881 | len, PCI_DMA_BIDIRECTIONAL); | ||
866 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 882 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
867 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | 883 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); |
868 | 884 | ||
869 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | 885 | IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n", |
870 | txq->need_update = 1; | 886 | le16_to_cpu(out_cmd->hdr.sequence)); |
871 | if (qc) | 887 | IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags)); |
872 | priv->stations[sta_id].tid[tid].seq_number = seq_number; | ||
873 | } else { | ||
874 | wait_write_ptr = 1; | ||
875 | txq->need_update = 0; | ||
876 | } | ||
877 | |||
878 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); | 888 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); |
879 | |||
880 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); | 889 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); |
881 | 890 | ||
882 | /* Set up entry for this TFD in Tx byte-count array */ | 891 | /* Set up entry for this TFD in Tx byte-count array */ |
883 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len); | 892 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, |
893 | le16_to_cpu(tx_cmd->len)); | ||
894 | |||
895 | pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, | ||
896 | len, PCI_DMA_BIDIRECTIONAL); | ||
884 | 897 | ||
885 | /* Tell device the write index *just past* this latest filled TFD */ | 898 | /* Tell device the write index *just past* this latest filled TFD */ |
886 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 899 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
@@ -968,18 +981,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
968 | INDEX_TO_SEQ(q->write_ptr)); | 981 | INDEX_TO_SEQ(q->write_ptr)); |
969 | if (out_cmd->meta.flags & CMD_SIZE_HUGE) | 982 | if (out_cmd->meta.flags & CMD_SIZE_HUGE) |
970 | out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; | 983 | out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; |
971 | len = (idx == TFD_CMD_SLOTS) ? | 984 | len = sizeof(struct iwl_cmd) - sizeof(struct iwl_cmd_meta); |
972 | IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); | 985 | len += (idx == TFD_CMD_SLOTS) ? IWL_MAX_SCAN_SIZE : 0; |
973 | |||
974 | phys_addr = pci_map_single(priv->pci_dev, out_cmd, | ||
975 | len, PCI_DMA_BIDIRECTIONAL); | ||
976 | pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); | ||
977 | pci_unmap_len_set(&out_cmd->meta, len, len); | ||
978 | phys_addr += offsetof(struct iwl_cmd, hdr); | ||
979 | 986 | ||
980 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, | ||
981 | phys_addr, fix_size, 1, | ||
982 | U32_PAD(cmd->len)); | ||
983 | 987 | ||
984 | #ifdef CONFIG_IWLWIFI_DEBUG | 988 | #ifdef CONFIG_IWLWIFI_DEBUG |
985 | switch (out_cmd->hdr.cmd) { | 989 | switch (out_cmd->hdr.cmd) { |
@@ -1007,6 +1011,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1007 | /* Set up entry in queue's byte count circular buffer */ | 1011 | /* Set up entry in queue's byte count circular buffer */ |
1008 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0); | 1012 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0); |
1009 | 1013 | ||
1014 | phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, | ||
1015 | fix_size, PCI_DMA_BIDIRECTIONAL); | ||
1016 | pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); | ||
1017 | pci_unmap_len_set(&out_cmd->meta, len, fix_size); | ||
1018 | |||
1019 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, | ||
1020 | phys_addr, fix_size, 1, | ||
1021 | U32_PAD(cmd->len)); | ||
1022 | |||
1010 | /* Increment and update queue's write index */ | 1023 | /* Increment and update queue's write index */ |
1011 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1024 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
1012 | ret = iwl_txq_update_write_ptr(priv, txq); | 1025 | ret = iwl_txq_update_write_ptr(priv, txq); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ce729281ff62..617c4235d971 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -972,7 +972,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
972 | dma_addr_t phys_addr; | 972 | dma_addr_t phys_addr; |
973 | dma_addr_t txcmd_phys; | 973 | dma_addr_t txcmd_phys; |
974 | int txq_id = skb_get_queue_mapping(skb); | 974 | int txq_id = skb_get_queue_mapping(skb); |
975 | u16 len, idx, len_org, hdr_len; | 975 | u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */ |
976 | u8 id; | 976 | u8 id; |
977 | u8 unicast; | 977 | u8 unicast; |
978 | u8 sta_id; | 978 | u8 sta_id; |
@@ -1074,6 +1074,40 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
1074 | /* Copy MAC header from skb into command buffer */ | 1074 | /* Copy MAC header from skb into command buffer */ |
1075 | memcpy(tx->hdr, hdr, hdr_len); | 1075 | memcpy(tx->hdr, hdr, hdr_len); |
1076 | 1076 | ||
1077 | |||
1078 | if (info->control.hw_key) | ||
1079 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id); | ||
1080 | |||
1081 | /* TODO need this for burst mode later on */ | ||
1082 | iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id); | ||
1083 | |||
1084 | /* set is_hcca to 0; it probably will never be implemented */ | ||
1085 | iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); | ||
1086 | |||
1087 | /* Total # bytes to be transmitted */ | ||
1088 | len = (u16)skb->len; | ||
1089 | tx->len = cpu_to_le16(len); | ||
1090 | |||
1091 | |||
1092 | tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; | ||
1093 | tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; | ||
1094 | |||
1095 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | ||
1096 | txq->need_update = 1; | ||
1097 | if (qc) | ||
1098 | priv->stations_39[sta_id].tid[tid].seq_number = seq_number; | ||
1099 | } else { | ||
1100 | wait_write_ptr = 1; | ||
1101 | txq->need_update = 0; | ||
1102 | } | ||
1103 | |||
1104 | IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n", | ||
1105 | le16_to_cpu(out_cmd->hdr.sequence)); | ||
1106 | IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx->tx_flags)); | ||
1107 | iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx)); | ||
1108 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr, | ||
1109 | ieee80211_hdrlen(fc)); | ||
1110 | |||
1077 | /* | 1111 | /* |
1078 | * Use the first empty entry in this queue's command buffer array | 1112 | * Use the first empty entry in this queue's command buffer array |
1079 | * to contain the Tx command and MAC header concatenated together | 1113 | * to contain the Tx command and MAC header concatenated together |
@@ -1096,22 +1130,18 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
1096 | 1130 | ||
1097 | /* Physical address of this Tx command's header (not MAC header!), | 1131 | /* Physical address of this Tx command's header (not MAC header!), |
1098 | * within command buffer array. */ | 1132 | * within command buffer array. */ |
1099 | txcmd_phys = pci_map_single(priv->pci_dev, | 1133 | txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr, |
1100 | out_cmd, sizeof(struct iwl_cmd), | 1134 | len, PCI_DMA_TODEVICE); |
1101 | PCI_DMA_TODEVICE); | 1135 | /* we do not map meta data ... so we can safely access address to |
1136 | * provide to unmap command*/ | ||
1102 | pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); | 1137 | pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); |
1103 | pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd)); | 1138 | pci_unmap_len_set(&out_cmd->meta, len, len); |
1104 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
1105 | * first entry */ | ||
1106 | txcmd_phys += offsetof(struct iwl_cmd, hdr); | ||
1107 | 1139 | ||
1108 | /* Add buffer containing Tx command and MAC(!) header to TFD's | 1140 | /* Add buffer containing Tx command and MAC(!) header to TFD's |
1109 | * first entry */ | 1141 | * first entry */ |
1110 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, | 1142 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
1111 | txcmd_phys, len, 1, 0); | 1143 | txcmd_phys, len, 1, 0); |
1112 | 1144 | ||
1113 | if (info->control.hw_key) | ||
1114 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id); | ||
1115 | 1145 | ||
1116 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 1146 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
1117 | * if any (802.11 null frames have no payload). */ | 1147 | * if any (802.11 null frames have no payload). */ |
@@ -1124,32 +1154,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
1124 | 0, U32_PAD(len)); | 1154 | 0, U32_PAD(len)); |
1125 | } | 1155 | } |
1126 | 1156 | ||
1127 | /* Total # bytes to be transmitted */ | ||
1128 | len = (u16)skb->len; | ||
1129 | tx->len = cpu_to_le16(len); | ||
1130 | |||
1131 | /* TODO need this for burst mode later on */ | ||
1132 | iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id); | ||
1133 | |||
1134 | /* set is_hcca to 0; it probably will never be implemented */ | ||
1135 | iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); | ||
1136 | |||
1137 | tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; | ||
1138 | tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; | ||
1139 | |||
1140 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | ||
1141 | txq->need_update = 1; | ||
1142 | if (qc) | ||
1143 | priv->stations_39[sta_id].tid[tid].seq_number = seq_number; | ||
1144 | } else { | ||
1145 | wait_write_ptr = 1; | ||
1146 | txq->need_update = 0; | ||
1147 | } | ||
1148 | |||
1149 | iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx)); | ||
1150 | |||
1151 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr, | ||
1152 | ieee80211_hdrlen(fc)); | ||
1153 | 1157 | ||
1154 | /* Tell device the write index *just past* this latest filled TFD */ | 1158 | /* Tell device the write index *just past* this latest filled TFD */ |
1155 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1159 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
@@ -1661,6 +1665,37 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv) | |||
1661 | spin_unlock_irqrestore(&rxq->lock, flags); | 1665 | spin_unlock_irqrestore(&rxq->lock, flags); |
1662 | } | 1666 | } |
1663 | 1667 | ||
1668 | void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | ||
1669 | { | ||
1670 | unsigned long flags; | ||
1671 | int i; | ||
1672 | spin_lock_irqsave(&rxq->lock, flags); | ||
1673 | INIT_LIST_HEAD(&rxq->rx_free); | ||
1674 | INIT_LIST_HEAD(&rxq->rx_used); | ||
1675 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
1676 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
1677 | /* In the reset function, these buffers may have been allocated | ||
1678 | * to an SKB, so we need to unmap and free potential storage */ | ||
1679 | if (rxq->pool[i].skb != NULL) { | ||
1680 | pci_unmap_single(priv->pci_dev, | ||
1681 | rxq->pool[i].real_dma_addr, | ||
1682 | priv->hw_params.rx_buf_size, | ||
1683 | PCI_DMA_FROMDEVICE); | ||
1684 | priv->alloc_rxb_skb--; | ||
1685 | dev_kfree_skb(rxq->pool[i].skb); | ||
1686 | rxq->pool[i].skb = NULL; | ||
1687 | } | ||
1688 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
1689 | } | ||
1690 | |||
1691 | /* Set us so that we have processed and used all buffers, but have | ||
1692 | * not restocked the Rx queue with fresh buffers */ | ||
1693 | rxq->read = rxq->write = 0; | ||
1694 | rxq->free_count = 0; | ||
1695 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
1696 | } | ||
1697 | EXPORT_SYMBOL(iwl3945_rx_queue_reset); | ||
1698 | |||
1664 | /* | 1699 | /* |
1665 | * this should be called while priv->lock is locked | 1700 | * this should be called while priv->lock is locked |
1666 | */ | 1701 | */ |
@@ -1685,6 +1720,34 @@ void iwl3945_rx_replenish(void *data) | |||
1685 | spin_unlock_irqrestore(&priv->lock, flags); | 1720 | spin_unlock_irqrestore(&priv->lock, flags); |
1686 | } | 1721 | } |
1687 | 1722 | ||
1723 | /* Assumes that the skb field of the buffers in 'pool' is kept accurate. | ||
1724 | * If an SKB has been detached, the POOL needs to have its SKB set to NULL | ||
1725 | * This free routine walks the list of POOL entries and if SKB is set to | ||
1726 | * non NULL it is unmapped and freed | ||
1727 | */ | ||
1728 | static void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | ||
1729 | { | ||
1730 | int i; | ||
1731 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | ||
1732 | if (rxq->pool[i].skb != NULL) { | ||
1733 | pci_unmap_single(priv->pci_dev, | ||
1734 | rxq->pool[i].real_dma_addr, | ||
1735 | priv->hw_params.rx_buf_size, | ||
1736 | PCI_DMA_FROMDEVICE); | ||
1737 | dev_kfree_skb(rxq->pool[i].skb); | ||
1738 | } | ||
1739 | } | ||
1740 | |||
1741 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | ||
1742 | rxq->dma_addr); | ||
1743 | pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status), | ||
1744 | rxq->rb_stts, rxq->rb_stts_dma); | ||
1745 | rxq->bd = NULL; | ||
1746 | rxq->rb_stts = NULL; | ||
1747 | } | ||
1748 | EXPORT_SYMBOL(iwl3945_rx_queue_free); | ||
1749 | |||
1750 | |||
1688 | /* Convert linear signal-to-noise ratio into dB */ | 1751 | /* Convert linear signal-to-noise ratio into dB */ |
1689 | static u8 ratio2dB[100] = { | 1752 | static u8 ratio2dB[100] = { |
1690 | /* 0 1 2 3 4 5 6 7 8 9 */ | 1753 | /* 0 1 2 3 4 5 6 7 8 9 */ |
@@ -1802,9 +1865,9 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1802 | 1865 | ||
1803 | rxq->queue[i] = NULL; | 1866 | rxq->queue[i] = NULL; |
1804 | 1867 | ||
1805 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->real_dma_addr, | 1868 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, |
1806 | priv->hw_params.rx_buf_size, | 1869 | priv->hw_params.rx_buf_size, |
1807 | PCI_DMA_FROMDEVICE); | 1870 | PCI_DMA_FROMDEVICE); |
1808 | pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1871 | pkt = (struct iwl_rx_packet *)rxb->skb->data; |
1809 | 1872 | ||
1810 | /* Reclaim a command buffer only if this packet is a response | 1873 | /* Reclaim a command buffer only if this packet is a response |
@@ -1852,9 +1915,6 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1852 | rxb->skb = NULL; | 1915 | rxb->skb = NULL; |
1853 | } | 1916 | } |
1854 | 1917 | ||
1855 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, | ||
1856 | priv->hw_params.rx_buf_size, | ||
1857 | PCI_DMA_FROMDEVICE); | ||
1858 | spin_lock_irqsave(&rxq->lock, flags); | 1918 | spin_lock_irqsave(&rxq->lock, flags); |
1859 | list_add_tail(&rxb->list, &priv->rxq.rx_used); | 1919 | list_add_tail(&rxb->list, &priv->rxq.rx_used); |
1860 | spin_unlock_irqrestore(&rxq->lock, flags); | 1920 | spin_unlock_irqrestore(&rxq->lock, flags); |
@@ -4075,7 +4135,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
4075 | if (!static_key) { | 4135 | if (!static_key) { |
4076 | sta_id = iwl3945_hw_find_station(priv, addr); | 4136 | sta_id = iwl3945_hw_find_station(priv, addr); |
4077 | if (sta_id == IWL_INVALID_STATION) { | 4137 | if (sta_id == IWL_INVALID_STATION) { |
4078 | IWL_DEBUG_MAC80211(priv, "leave - %pMnot in station map.\n", | 4138 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", |
4079 | addr); | 4139 | addr); |
4080 | return -EINVAL; | 4140 | return -EINVAL; |
4081 | } | 4141 | } |
@@ -4913,6 +4973,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
4913 | 4973 | ||
4914 | hw->wiphy->custom_regulatory = true; | 4974 | hw->wiphy->custom_regulatory = true; |
4915 | 4975 | ||
4976 | hw->wiphy->max_scan_ssids = 1; /* WILL FIX */ | ||
4977 | |||
4916 | /* Default value; 4 EDCA QOS priorities */ | 4978 | /* Default value; 4 EDCA QOS priorities */ |
4917 | hw->queues = 4; | 4979 | hw->queues = 4; |
4918 | 4980 | ||
@@ -5194,12 +5256,12 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
5194 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 5256 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
5195 | 5257 | ||
5196 | iwl_rfkill_unregister(priv); | 5258 | iwl_rfkill_unregister(priv); |
5197 | cancel_delayed_work(&priv->rfkill_poll); | 5259 | cancel_delayed_work_sync(&priv->rfkill_poll); |
5198 | 5260 | ||
5199 | iwl3945_dealloc_ucode_pci(priv); | 5261 | iwl3945_dealloc_ucode_pci(priv); |
5200 | 5262 | ||
5201 | if (priv->rxq.bd) | 5263 | if (priv->rxq.bd) |
5202 | iwl_rx_queue_free(priv, &priv->rxq); | 5264 | iwl3945_rx_queue_free(priv, &priv->rxq); |
5203 | iwl3945_hw_txq_ctx_free(priv); | 5265 | iwl3945_hw_txq_ctx_free(priv); |
5204 | 5266 | ||
5205 | iwl3945_unset_hw_params(priv); | 5267 | iwl3945_unset_hw_params(priv); |
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 63d7e19ce9bd..8e669775cb5d 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c | |||
@@ -170,6 +170,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | |||
170 | lbs_deb_rx("rx err: frame received with bad length\n"); | 170 | lbs_deb_rx("rx err: frame received with bad length\n"); |
171 | dev->stats.rx_length_errors++; | 171 | dev->stats.rx_length_errors++; |
172 | ret = 0; | 172 | ret = 0; |
173 | dev_kfree_skb(skb); | ||
173 | goto done; | 174 | goto done; |
174 | } | 175 | } |
175 | 176 | ||
@@ -181,6 +182,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | |||
181 | lbs_pr_alert("rxpd not ok\n"); | 182 | lbs_pr_alert("rxpd not ok\n"); |
182 | dev->stats.rx_errors++; | 183 | dev->stats.rx_errors++; |
183 | ret = 0; | 184 | ret = 0; |
185 | dev_kfree_skb(skb); | ||
184 | goto done; | 186 | goto done; |
185 | } | 187 | } |
186 | 188 | ||
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 57a0268d1bae..a9a970469c2a 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -893,8 +893,7 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) | |||
893 | rx_desc->next_rx_desc_phys_addr = | 893 | rx_desc->next_rx_desc_phys_addr = |
894 | cpu_to_le32(rxq->rx_desc_dma | 894 | cpu_to_le32(rxq->rx_desc_dma |
895 | + nexti * sizeof(*rx_desc)); | 895 | + nexti * sizeof(*rx_desc)); |
896 | rx_desc->rx_ctrl = | 896 | rx_desc->rx_ctrl = MWL8K_RX_CTRL_OWNED_BY_HOST; |
897 | cpu_to_le32(MWL8K_RX_CTRL_OWNED_BY_HOST); | ||
898 | } | 897 | } |
899 | 898 | ||
900 | return 0; | 899 | return 0; |
@@ -3720,12 +3719,12 @@ err_free_reg: | |||
3720 | return rc; | 3719 | return rc; |
3721 | } | 3720 | } |
3722 | 3721 | ||
3723 | static void __devexit mwl8k_remove(struct pci_dev *pdev) | 3722 | static void __devexit mwl8k_shutdown(struct pci_dev *pdev) |
3724 | { | 3723 | { |
3725 | printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__); | 3724 | printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__); |
3726 | } | 3725 | } |
3727 | 3726 | ||
3728 | static void __devexit mwl8k_shutdown(struct pci_dev *pdev) | 3727 | static void __devexit mwl8k_remove(struct pci_dev *pdev) |
3729 | { | 3728 | { |
3730 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 3729 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
3731 | struct mwl8k_priv *priv; | 3730 | struct mwl8k_priv *priv; |
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 081428d9409e..632fac86a308 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c | |||
@@ -372,15 +372,13 @@ int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx, | |||
372 | } | 372 | } |
373 | 373 | ||
374 | /* Wait upto 100ms for tx queue to empty */ | 374 | /* Wait upto 100ms for tx queue to empty */ |
375 | k = 100; | 375 | for (k = 100; k > 0; k--) { |
376 | do { | ||
377 | k--; | ||
378 | udelay(1000); | 376 | udelay(1000); |
379 | ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY, | 377 | ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY, |
380 | &xmitting); | 378 | &xmitting); |
381 | if (ret) | 379 | if (ret || !xmitting) |
382 | break; | 380 | break; |
383 | } while ((k > 0) && xmitting); | 381 | } |
384 | 382 | ||
385 | if (k == 0) | 383 | if (k == 0) |
386 | ret = -ETIMEDOUT; | 384 | ret = -ETIMEDOUT; |
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 2dda5fe418b6..ecf8b6ed5a47 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -14,9 +14,9 @@ | |||
14 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #ifdef CONFIG_MAC80211_LEDS | 17 | #ifdef CONFIG_P54_LEDS |
18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
19 | #endif /* CONFIG_MAC80211_LEDS */ | 19 | #endif /* CONFIG_P54_LEDS */ |
20 | 20 | ||
21 | enum p54_control_frame_types { | 21 | enum p54_control_frame_types { |
22 | P54_CONTROL_TYPE_SETUP = 0, | 22 | P54_CONTROL_TYPE_SETUP = 0, |
@@ -116,7 +116,7 @@ enum fw_state { | |||
116 | FW_STATE_RESETTING, | 116 | FW_STATE_RESETTING, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | #ifdef CONFIG_MAC80211_LEDS | 119 | #ifdef CONFIG_P54_LEDS |
120 | 120 | ||
121 | #define P54_LED_MAX_NAME_LEN 31 | 121 | #define P54_LED_MAX_NAME_LEN 31 |
122 | 122 | ||
@@ -129,7 +129,7 @@ struct p54_led_dev { | |||
129 | unsigned int registered; | 129 | unsigned int registered; |
130 | }; | 130 | }; |
131 | 131 | ||
132 | #endif /* CONFIG_MAC80211_LEDS */ | 132 | #endif /* CONFIG_P54_LEDS */ |
133 | 133 | ||
134 | struct p54_common { | 134 | struct p54_common { |
135 | struct ieee80211_hw *hw; | 135 | struct ieee80211_hw *hw; |
@@ -177,10 +177,10 @@ struct p54_common { | |||
177 | u8 privacy_caps; | 177 | u8 privacy_caps; |
178 | u8 rx_keycache_size; | 178 | u8 rx_keycache_size; |
179 | /* LED management */ | 179 | /* LED management */ |
180 | #ifdef CONFIG_MAC80211_LEDS | 180 | #ifdef CONFIG_P54_LEDS |
181 | struct p54_led_dev assoc_led; | 181 | struct p54_led_dev assoc_led; |
182 | struct p54_led_dev tx_led; | 182 | struct p54_led_dev tx_led; |
183 | #endif /* CONFIG_MAC80211_LEDS */ | 183 | #endif /* CONFIG_P54_LEDS */ |
184 | u16 softled_state; /* bit field of glowing LEDs */ | 184 | u16 softled_state; /* bit field of glowing LEDs */ |
185 | }; | 185 | }; |
186 | 186 | ||
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 0c1b0577d4ee..c8f0232ee5e0 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -2543,8 +2543,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
2543 | priv->basic_rate_mask = 0x15f; | 2543 | priv->basic_rate_mask = 0x15f; |
2544 | skb_queue_head_init(&priv->tx_queue); | 2544 | skb_queue_head_init(&priv->tx_queue); |
2545 | dev->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 2545 | dev->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
2546 | IEEE80211_HW_SUPPORTS_PS | | ||
2547 | IEEE80211_HW_PS_NULLFUNC_STACK | | ||
2548 | IEEE80211_HW_SIGNAL_DBM | | 2546 | IEEE80211_HW_SIGNAL_DBM | |
2549 | IEEE80211_HW_NOISE_DBM; | 2547 | IEEE80211_HW_NOISE_DBM; |
2550 | 2548 | ||
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index e3569a0a952d..b1610ea4bb3d 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -492,8 +492,8 @@ static int __devinit p54p_probe(struct pci_dev *pdev, | |||
492 | goto err_disable_dev; | 492 | goto err_disable_dev; |
493 | } | 493 | } |
494 | 494 | ||
495 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) || | 495 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) || |
496 | pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { | 496 | pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { |
497 | dev_err(&pdev->dev, "No suitable DMA available\n"); | 497 | dev_err(&pdev->dev, "No suitable DMA available\n"); |
498 | goto err_free_reg; | 498 | goto err_free_reg; |
499 | } | 499 | } |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 2b222aaa6f0a..d1fe577de3d4 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -457,9 +457,10 @@ static int p54spi_wq_tx(struct p54s_priv *priv) | |||
457 | struct ieee80211_tx_info *info; | 457 | struct ieee80211_tx_info *info; |
458 | struct p54_tx_info *minfo; | 458 | struct p54_tx_info *minfo; |
459 | struct p54s_tx_info *dinfo; | 459 | struct p54s_tx_info *dinfo; |
460 | unsigned long flags; | ||
460 | int ret = 0; | 461 | int ret = 0; |
461 | 462 | ||
462 | spin_lock_bh(&priv->tx_lock); | 463 | spin_lock_irqsave(&priv->tx_lock, flags); |
463 | 464 | ||
464 | while (!list_empty(&priv->tx_pending)) { | 465 | while (!list_empty(&priv->tx_pending)) { |
465 | entry = list_entry(priv->tx_pending.next, | 466 | entry = list_entry(priv->tx_pending.next, |
@@ -467,7 +468,7 @@ static int p54spi_wq_tx(struct p54s_priv *priv) | |||
467 | 468 | ||
468 | list_del_init(&entry->tx_list); | 469 | list_del_init(&entry->tx_list); |
469 | 470 | ||
470 | spin_unlock_bh(&priv->tx_lock); | 471 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
471 | 472 | ||
472 | dinfo = container_of((void *) entry, struct p54s_tx_info, | 473 | dinfo = container_of((void *) entry, struct p54s_tx_info, |
473 | tx_list); | 474 | tx_list); |
@@ -479,16 +480,14 @@ static int p54spi_wq_tx(struct p54s_priv *priv) | |||
479 | 480 | ||
480 | ret = p54spi_tx_frame(priv, skb); | 481 | ret = p54spi_tx_frame(priv, skb); |
481 | 482 | ||
482 | spin_lock_bh(&priv->tx_lock); | ||
483 | |||
484 | if (ret < 0) { | 483 | if (ret < 0) { |
485 | p54_free_skb(priv->hw, skb); | 484 | p54_free_skb(priv->hw, skb); |
486 | goto out; | 485 | return ret; |
487 | } | 486 | } |
488 | } | ||
489 | 487 | ||
490 | out: | 488 | spin_lock_irqsave(&priv->tx_lock, flags); |
491 | spin_unlock_bh(&priv->tx_lock); | 489 | } |
490 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
492 | return ret; | 491 | return ret; |
493 | } | 492 | } |
494 | 493 | ||
@@ -498,12 +497,13 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
498 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 497 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
499 | struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data; | 498 | struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data; |
500 | struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data; | 499 | struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data; |
500 | unsigned long flags; | ||
501 | 501 | ||
502 | BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data))); | 502 | BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data))); |
503 | 503 | ||
504 | spin_lock_bh(&priv->tx_lock); | 504 | spin_lock_irqsave(&priv->tx_lock, flags); |
505 | list_add_tail(&di->tx_list, &priv->tx_pending); | 505 | list_add_tail(&di->tx_list, &priv->tx_pending); |
506 | spin_unlock_bh(&priv->tx_lock); | 506 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
507 | 507 | ||
508 | queue_work(priv->hw->workqueue, &priv->work); | 508 | queue_work(priv->hw->workqueue, &priv->work); |
509 | } | 509 | } |
@@ -604,6 +604,7 @@ out: | |||
604 | static void p54spi_op_stop(struct ieee80211_hw *dev) | 604 | static void p54spi_op_stop(struct ieee80211_hw *dev) |
605 | { | 605 | { |
606 | struct p54s_priv *priv = dev->priv; | 606 | struct p54s_priv *priv = dev->priv; |
607 | unsigned long flags; | ||
607 | 608 | ||
608 | if (mutex_lock_interruptible(&priv->mutex)) { | 609 | if (mutex_lock_interruptible(&priv->mutex)) { |
609 | /* FIXME: how to handle this error? */ | 610 | /* FIXME: how to handle this error? */ |
@@ -615,9 +616,9 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) | |||
615 | cancel_work_sync(&priv->work); | 616 | cancel_work_sync(&priv->work); |
616 | 617 | ||
617 | p54spi_power_off(priv); | 618 | p54spi_power_off(priv); |
618 | spin_lock_bh(&priv->tx_lock); | 619 | spin_lock_irqsave(&priv->tx_lock, flags); |
619 | INIT_LIST_HEAD(&priv->tx_pending); | 620 | INIT_LIST_HEAD(&priv->tx_pending); |
620 | spin_unlock_bh(&priv->tx_lock); | 621 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
621 | 622 | ||
622 | priv->fw_state = FW_STATE_OFF; | 623 | priv->fw_state = FW_STATE_OFF; |
623 | mutex_unlock(&priv->mutex); | 624 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index da6640afc835..6cc6cbc9234f 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -71,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
71 | {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */ | 71 | {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */ |
72 | {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ | 72 | {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ |
73 | {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ | 73 | {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ |
74 | {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ | ||
74 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ | 75 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ |
75 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ | 76 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ |
76 | {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ | 77 | {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 05f94e21b423..5752aaae906b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -646,10 +646,8 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
646 | * Register HW. | 646 | * Register HW. |
647 | */ | 647 | */ |
648 | status = ieee80211_register_hw(rt2x00dev->hw); | 648 | status = ieee80211_register_hw(rt2x00dev->hw); |
649 | if (status) { | 649 | if (status) |
650 | rt2x00lib_remove_hw(rt2x00dev); | ||
651 | return status; | 650 | return status; |
652 | } | ||
653 | 651 | ||
654 | set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags); | 652 | set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags); |
655 | 653 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 43fa0f849003..9730b4f8fd26 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -369,8 +369,6 @@ int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state) | |||
369 | if (retval) | 369 | if (retval) |
370 | return retval; | 370 | return retval; |
371 | 371 | ||
372 | rt2x00pci_free_reg(rt2x00dev); | ||
373 | |||
374 | pci_save_state(pci_dev); | 372 | pci_save_state(pci_dev); |
375 | pci_disable_device(pci_dev); | 373 | pci_disable_device(pci_dev); |
376 | return pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); | 374 | return pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); |
@@ -381,7 +379,6 @@ int rt2x00pci_resume(struct pci_dev *pci_dev) | |||
381 | { | 379 | { |
382 | struct ieee80211_hw *hw = pci_get_drvdata(pci_dev); | 380 | struct ieee80211_hw *hw = pci_get_drvdata(pci_dev); |
383 | struct rt2x00_dev *rt2x00dev = hw->priv; | 381 | struct rt2x00_dev *rt2x00dev = hw->priv; |
384 | int retval; | ||
385 | 382 | ||
386 | if (pci_set_power_state(pci_dev, PCI_D0) || | 383 | if (pci_set_power_state(pci_dev, PCI_D0) || |
387 | pci_enable_device(pci_dev) || | 384 | pci_enable_device(pci_dev) || |
@@ -390,20 +387,7 @@ int rt2x00pci_resume(struct pci_dev *pci_dev) | |||
390 | return -EIO; | 387 | return -EIO; |
391 | } | 388 | } |
392 | 389 | ||
393 | retval = rt2x00pci_alloc_reg(rt2x00dev); | 390 | return rt2x00lib_resume(rt2x00dev); |
394 | if (retval) | ||
395 | return retval; | ||
396 | |||
397 | retval = rt2x00lib_resume(rt2x00dev); | ||
398 | if (retval) | ||
399 | goto exit_free_reg; | ||
400 | |||
401 | return 0; | ||
402 | |||
403 | exit_free_reg: | ||
404 | rt2x00pci_free_reg(rt2x00dev); | ||
405 | |||
406 | return retval; | ||
407 | } | 391 | } |
408 | EXPORT_SYMBOL_GPL(rt2x00pci_resume); | 392 | EXPORT_SYMBOL_GPL(rt2x00pci_resume); |
409 | #endif /* CONFIG_PM */ | 393 | #endif /* CONFIG_PM */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 7d50ca82375e..501544882c2c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -702,8 +702,6 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state) | |||
702 | if (retval) | 702 | if (retval) |
703 | return retval; | 703 | return retval; |
704 | 704 | ||
705 | rt2x00usb_free_reg(rt2x00dev); | ||
706 | |||
707 | /* | 705 | /* |
708 | * Decrease usbdev refcount. | 706 | * Decrease usbdev refcount. |
709 | */ | 707 | */ |
@@ -717,24 +715,10 @@ int rt2x00usb_resume(struct usb_interface *usb_intf) | |||
717 | { | 715 | { |
718 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); | 716 | struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); |
719 | struct rt2x00_dev *rt2x00dev = hw->priv; | 717 | struct rt2x00_dev *rt2x00dev = hw->priv; |
720 | int retval; | ||
721 | 718 | ||
722 | usb_get_dev(interface_to_usbdev(usb_intf)); | 719 | usb_get_dev(interface_to_usbdev(usb_intf)); |
723 | 720 | ||
724 | retval = rt2x00usb_alloc_reg(rt2x00dev); | 721 | return rt2x00lib_resume(rt2x00dev); |
725 | if (retval) | ||
726 | return retval; | ||
727 | |||
728 | retval = rt2x00lib_resume(rt2x00dev); | ||
729 | if (retval) | ||
730 | goto exit_free_reg; | ||
731 | |||
732 | return 0; | ||
733 | |||
734 | exit_free_reg: | ||
735 | rt2x00usb_free_reg(rt2x00dev); | ||
736 | |||
737 | return retval; | ||
738 | } | 722 | } |
739 | EXPORT_SYMBOL_GPL(rt2x00usb_resume); | 723 | EXPORT_SYMBOL_GPL(rt2x00usb_resume); |
740 | #endif /* CONFIG_PM */ | 724 | #endif /* CONFIG_PM */ |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 420fff42c0dd..853b2b279b64 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2369,6 +2369,8 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
2369 | /* Buffalo */ | 2369 | /* Buffalo */ |
2370 | { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, | 2370 | { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, |
2371 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, | 2371 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, |
2372 | { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2373 | { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2372 | /* CNet */ | 2374 | /* CNet */ |
2373 | { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, | 2375 | { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, |
2374 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, | 2376 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, |
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c index a12a7211c982..5a4ad156f63e 100644 --- a/drivers/net/xtsonic.c +++ b/drivers/net/xtsonic.c | |||
@@ -108,6 +108,18 @@ static int xtsonic_close(struct net_device *dev) | |||
108 | return err; | 108 | return err; |
109 | } | 109 | } |
110 | 110 | ||
111 | static const struct net_device_ops xtsonic_netdev_ops = { | ||
112 | .ndo_open = xtsonic_open, | ||
113 | .ndo_stop = xtsonic_close, | ||
114 | .ndo_start_xmit = sonic_send_packet, | ||
115 | .ndo_get_stats = sonic_get_stats, | ||
116 | .ndo_set_multicast_list = sonic_multicast_list, | ||
117 | .ndo_tx_timeout = sonic_tx_timeout, | ||
118 | .ndo_validate_addr = eth_validate_addr, | ||
119 | .ndo_change_mtu = eth_change_mtu, | ||
120 | .ndo_set_mac_address = eth_mac_addr, | ||
121 | }; | ||
122 | |||
111 | static int __init sonic_probe1(struct net_device *dev) | 123 | static int __init sonic_probe1(struct net_device *dev) |
112 | { | 124 | { |
113 | static unsigned version_printed = 0; | 125 | static unsigned version_printed = 0; |
@@ -205,12 +217,7 @@ static int __init sonic_probe1(struct net_device *dev) | |||
205 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | 217 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS |
206 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | 218 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
207 | 219 | ||
208 | dev->open = xtsonic_open; | 220 | dev->netdev_ops = &xtsonic_netdev_ops; |
209 | dev->stop = xtsonic_close; | ||
210 | dev->hard_start_xmit = sonic_send_packet; | ||
211 | dev->get_stats = sonic_get_stats; | ||
212 | dev->set_multicast_list = &sonic_multicast_list; | ||
213 | dev->tx_timeout = sonic_tx_timeout; | ||
214 | dev->watchdog_timeo = TX_TIMEOUT; | 221 | dev->watchdog_timeo = TX_TIMEOUT; |
215 | 222 | ||
216 | /* | 223 | /* |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 4fa3bb2ddfe4..33e5ade774ca 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -434,7 +434,8 @@ static void __init superio_parport_init(void) | |||
434 | 0 /*base_hi*/, | 434 | 0 /*base_hi*/, |
435 | PAR_IRQ, | 435 | PAR_IRQ, |
436 | PARPORT_DMA_NONE /* dma */, | 436 | PARPORT_DMA_NONE /* dma */, |
437 | NULL /*struct pci_dev* */) ) | 437 | NULL /*struct pci_dev* */), |
438 | 0 /* shared irq flags */ ) | ||
438 | 439 | ||
439 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); | 440 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); |
440 | #endif /* CONFIG_PARPORT_PC */ | 441 | #endif /* CONFIG_PARPORT_PC */ |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 25a00ce4f24d..fa3a11365ec3 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -173,12 +173,21 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header) | |||
173 | struct dmar_drhd_unit *dmaru; | 173 | struct dmar_drhd_unit *dmaru; |
174 | int ret = 0; | 174 | int ret = 0; |
175 | 175 | ||
176 | drhd = (struct acpi_dmar_hardware_unit *)header; | ||
177 | if (!drhd->address) { | ||
178 | /* Promote an attitude of violence to a BIOS engineer today */ | ||
179 | WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n" | ||
180 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
181 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
182 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
183 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
184 | return -ENODEV; | ||
185 | } | ||
176 | dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL); | 186 | dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL); |
177 | if (!dmaru) | 187 | if (!dmaru) |
178 | return -ENOMEM; | 188 | return -ENOMEM; |
179 | 189 | ||
180 | dmaru->hdr = header; | 190 | dmaru->hdr = header; |
181 | drhd = (struct acpi_dmar_hardware_unit *)header; | ||
182 | dmaru->reg_base_addr = drhd->address; | 191 | dmaru->reg_base_addr = drhd->address; |
183 | dmaru->segment = drhd->segment; | 192 | dmaru->segment = drhd->segment; |
184 | dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */ | 193 | dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */ |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index fb3a3f3fca7a..001b328adf80 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -733,8 +733,8 @@ static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end) | |||
733 | start &= (((u64)1) << addr_width) - 1; | 733 | start &= (((u64)1) << addr_width) - 1; |
734 | end &= (((u64)1) << addr_width) - 1; | 734 | end &= (((u64)1) << addr_width) - 1; |
735 | /* in case it's partial page */ | 735 | /* in case it's partial page */ |
736 | start = PAGE_ALIGN(start); | 736 | start &= PAGE_MASK; |
737 | end &= PAGE_MASK; | 737 | end = PAGE_ALIGN(end); |
738 | npages = (end - start) / VTD_PAGE_SIZE; | 738 | npages = (end - start) / VTD_PAGE_SIZE; |
739 | 739 | ||
740 | /* we don't need lock here, nobody else touches the iova range */ | 740 | /* we don't need lock here, nobody else touches the iova range */ |
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 1cd02f5a23a0..bc43f78f6f0b 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
@@ -255,6 +255,9 @@ static int __init sharpsl_pcmcia_init(void) | |||
255 | { | 255 | { |
256 | int ret; | 256 | int ret; |
257 | 257 | ||
258 | if (!platform_scoop_config) | ||
259 | return -ENODEV; | ||
260 | |||
258 | sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs; | 261 | sharpsl_pcmcia_ops.nr = platform_scoop_config->num_devs; |
259 | sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | 262 | sharpsl_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); |
260 | 263 | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index ffe34a12f446..4e9851fc1746 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -573,7 +573,7 @@ config RTC_DRV_SA1100 | |||
573 | 573 | ||
574 | config RTC_DRV_SH | 574 | config RTC_DRV_SH |
575 | tristate "SuperH On-Chip RTC" | 575 | tristate "SuperH On-Chip RTC" |
576 | depends on RTC_CLASS && SUPERH | 576 | depends on RTC_CLASS && SUPERH && HAVE_CLK |
577 | help | 577 | help |
578 | Say Y here to enable support for the on-chip RTC found in | 578 | Say Y here to enable support for the on-chip RTC found in |
579 | most SuperH processors. | 579 | most SuperH processors. |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index b6d35f50e404..23e10b6263d6 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -797,17 +797,15 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
797 | goto cleanup2; | 797 | goto cleanup2; |
798 | } | 798 | } |
799 | 799 | ||
800 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n", | 800 | pr_info("%s: %s%s, %zd bytes nvram%s\n", |
801 | dev_name(&cmos_rtc.rtc->dev), | 801 | dev_name(&cmos_rtc.rtc->dev), |
802 | is_valid_irq(rtc_irq) | 802 | !is_valid_irq(rtc_irq) ? "no alarms" : |
803 | ? (cmos_rtc.mon_alrm | 803 | cmos_rtc.mon_alrm ? "alarms up to one year" : |
804 | ? "year" | 804 | cmos_rtc.day_alrm ? "alarms up to one month" : |
805 | : (cmos_rtc.day_alrm | 805 | "alarms up to one day", |
806 | ? "month" : "day")) | 806 | cmos_rtc.century ? ", y3k" : "", |
807 | : "no", | 807 | nvram.size, |
808 | cmos_rtc.century ? ", y3k" : "", | 808 | is_hpet_enabled() ? ", hpet irqs" : ""); |
809 | nvram.size, | ||
810 | is_hpet_enabled() ? ", hpet irqs" : ""); | ||
811 | 809 | ||
812 | return 0; | 810 | return 0; |
813 | 811 | ||
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 9b1ff12bf947..d7310adb7152 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SuperH On-Chip RTC Support | 2 | * SuperH On-Chip RTC Support |
3 | * | 3 | * |
4 | * Copyright (C) 2006, 2007, 2008 Paul Mundt | 4 | * Copyright (C) 2006 - 2009 Paul Mundt |
5 | * Copyright (C) 2006 Jamie Lenehan | 5 | * Copyright (C) 2006 Jamie Lenehan |
6 | * Copyright (C) 2008 Angelo Castello | 6 | * Copyright (C) 2008 Angelo Castello |
7 | * | 7 | * |
@@ -25,10 +25,11 @@ | |||
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/log2.h> | 27 | #include <linux/log2.h> |
28 | #include <linux/clk.h> | ||
28 | #include <asm/rtc.h> | 29 | #include <asm/rtc.h> |
29 | 30 | ||
30 | #define DRV_NAME "sh-rtc" | 31 | #define DRV_NAME "sh-rtc" |
31 | #define DRV_VERSION "0.2.1" | 32 | #define DRV_VERSION "0.2.2" |
32 | 33 | ||
33 | #define RTC_REG(r) ((r) * rtc_reg_size) | 34 | #define RTC_REG(r) ((r) * rtc_reg_size) |
34 | 35 | ||
@@ -87,16 +88,17 @@ | |||
87 | #define RCR2_START 0x01 /* Start bit */ | 88 | #define RCR2_START 0x01 /* Start bit */ |
88 | 89 | ||
89 | struct sh_rtc { | 90 | struct sh_rtc { |
90 | void __iomem *regbase; | 91 | void __iomem *regbase; |
91 | unsigned long regsize; | 92 | unsigned long regsize; |
92 | struct resource *res; | 93 | struct resource *res; |
93 | int alarm_irq; | 94 | int alarm_irq; |
94 | int periodic_irq; | 95 | int periodic_irq; |
95 | int carry_irq; | 96 | int carry_irq; |
96 | struct rtc_device *rtc_dev; | 97 | struct clk *clk; |
97 | spinlock_t lock; | 98 | struct rtc_device *rtc_dev; |
98 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ | 99 | spinlock_t lock; |
99 | unsigned short periodic_freq; | 100 | unsigned long capabilities; /* See asm/rtc.h for cap bits */ |
101 | unsigned short periodic_freq; | ||
100 | }; | 102 | }; |
101 | 103 | ||
102 | static int __sh_rtc_interrupt(struct sh_rtc *rtc) | 104 | static int __sh_rtc_interrupt(struct sh_rtc *rtc) |
@@ -294,10 +296,10 @@ static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) | |||
294 | 296 | ||
295 | tmp = readb(rtc->regbase + RCR1); | 297 | tmp = readb(rtc->regbase + RCR1); |
296 | 298 | ||
297 | if (!enable) | 299 | if (enable) |
298 | tmp &= ~RCR1_AIE; | ||
299 | else | ||
300 | tmp |= RCR1_AIE; | 300 | tmp |= RCR1_AIE; |
301 | else | ||
302 | tmp &= ~RCR1_AIE; | ||
301 | 303 | ||
302 | writeb(tmp, rtc->regbase + RCR1); | 304 | writeb(tmp, rtc->regbase + RCR1); |
303 | 305 | ||
@@ -618,6 +620,7 @@ static int sh_rtc_irq_set_freq(struct device *dev, int freq) | |||
618 | { | 620 | { |
619 | if (!is_power_of_2(freq)) | 621 | if (!is_power_of_2(freq)) |
620 | return -EINVAL; | 622 | return -EINVAL; |
623 | |||
621 | return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq); | 624 | return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq); |
622 | } | 625 | } |
623 | 626 | ||
@@ -637,7 +640,8 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
637 | struct sh_rtc *rtc; | 640 | struct sh_rtc *rtc; |
638 | struct resource *res; | 641 | struct resource *res; |
639 | struct rtc_time r; | 642 | struct rtc_time r; |
640 | int ret; | 643 | char clk_name[6]; |
644 | int clk_id, ret; | ||
641 | 645 | ||
642 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); | 646 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); |
643 | if (unlikely(!rtc)) | 647 | if (unlikely(!rtc)) |
@@ -652,6 +656,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
652 | dev_err(&pdev->dev, "No IRQ resource\n"); | 656 | dev_err(&pdev->dev, "No IRQ resource\n"); |
653 | goto err_badres; | 657 | goto err_badres; |
654 | } | 658 | } |
659 | |||
655 | rtc->periodic_irq = ret; | 660 | rtc->periodic_irq = ret; |
656 | rtc->carry_irq = platform_get_irq(pdev, 1); | 661 | rtc->carry_irq = platform_get_irq(pdev, 1); |
657 | rtc->alarm_irq = platform_get_irq(pdev, 2); | 662 | rtc->alarm_irq = platform_get_irq(pdev, 2); |
@@ -663,7 +668,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
663 | goto err_badres; | 668 | goto err_badres; |
664 | } | 669 | } |
665 | 670 | ||
666 | rtc->regsize = res->end - res->start + 1; | 671 | rtc->regsize = resource_size(res); |
667 | 672 | ||
668 | rtc->res = request_mem_region(res->start, rtc->regsize, pdev->name); | 673 | rtc->res = request_mem_region(res->start, rtc->regsize, pdev->name); |
669 | if (unlikely(!rtc->res)) { | 674 | if (unlikely(!rtc->res)) { |
@@ -677,6 +682,26 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
677 | goto err_badmap; | 682 | goto err_badmap; |
678 | } | 683 | } |
679 | 684 | ||
685 | clk_id = pdev->id; | ||
686 | /* With a single device, the clock id is still "rtc0" */ | ||
687 | if (clk_id < 0) | ||
688 | clk_id = 0; | ||
689 | |||
690 | snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id); | ||
691 | |||
692 | rtc->clk = clk_get(&pdev->dev, clk_name); | ||
693 | if (IS_ERR(rtc->clk)) { | ||
694 | /* | ||
695 | * No error handling for rtc->clk intentionally, not all | ||
696 | * platforms will have a unique clock for the RTC, and | ||
697 | * the clk API can handle the struct clk pointer being | ||
698 | * NULL. | ||
699 | */ | ||
700 | rtc->clk = NULL; | ||
701 | } | ||
702 | |||
703 | clk_enable(rtc->clk); | ||
704 | |||
680 | rtc->rtc_dev = rtc_device_register("sh", &pdev->dev, | 705 | rtc->rtc_dev = rtc_device_register("sh", &pdev->dev, |
681 | &sh_rtc_ops, THIS_MODULE); | 706 | &sh_rtc_ops, THIS_MODULE); |
682 | if (IS_ERR(rtc->rtc_dev)) { | 707 | if (IS_ERR(rtc->rtc_dev)) { |
@@ -759,6 +784,8 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
759 | return 0; | 784 | return 0; |
760 | 785 | ||
761 | err_unmap: | 786 | err_unmap: |
787 | clk_disable(rtc->clk); | ||
788 | clk_put(rtc->clk); | ||
762 | iounmap(rtc->regbase); | 789 | iounmap(rtc->regbase); |
763 | err_badmap: | 790 | err_badmap: |
764 | release_resource(rtc->res); | 791 | release_resource(rtc->res); |
@@ -780,6 +807,7 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev) | |||
780 | sh_rtc_setcie(&pdev->dev, 0); | 807 | sh_rtc_setcie(&pdev->dev, 0); |
781 | 808 | ||
782 | free_irq(rtc->periodic_irq, rtc); | 809 | free_irq(rtc->periodic_irq, rtc); |
810 | |||
783 | if (rtc->carry_irq > 0) { | 811 | if (rtc->carry_irq > 0) { |
784 | free_irq(rtc->carry_irq, rtc); | 812 | free_irq(rtc->carry_irq, rtc); |
785 | free_irq(rtc->alarm_irq, rtc); | 813 | free_irq(rtc->alarm_irq, rtc); |
@@ -789,6 +817,9 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev) | |||
789 | 817 | ||
790 | iounmap(rtc->regbase); | 818 | iounmap(rtc->regbase); |
791 | 819 | ||
820 | clk_disable(rtc->clk); | ||
821 | clk_put(rtc->clk); | ||
822 | |||
792 | platform_set_drvdata(pdev, NULL); | 823 | platform_set_drvdata(pdev, NULL); |
793 | 824 | ||
794 | kfree(rtc); | 825 | kfree(rtc); |
@@ -802,11 +833,11 @@ static void sh_rtc_set_irq_wake(struct device *dev, int enabled) | |||
802 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 833 | struct sh_rtc *rtc = platform_get_drvdata(pdev); |
803 | 834 | ||
804 | set_irq_wake(rtc->periodic_irq, enabled); | 835 | set_irq_wake(rtc->periodic_irq, enabled); |
836 | |||
805 | if (rtc->carry_irq > 0) { | 837 | if (rtc->carry_irq > 0) { |
806 | set_irq_wake(rtc->carry_irq, enabled); | 838 | set_irq_wake(rtc->carry_irq, enabled); |
807 | set_irq_wake(rtc->alarm_irq, enabled); | 839 | set_irq_wake(rtc->alarm_irq, enabled); |
808 | } | 840 | } |
809 | |||
810 | } | 841 | } |
811 | 842 | ||
812 | static int sh_rtc_suspend(struct device *dev) | 843 | static int sh_rtc_suspend(struct device *dev) |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 0570794ccf1c..d1815272c435 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/buffer_head.h> | 21 | #include <linux/buffer_head.h> |
22 | #include <linux/hdreg.h> | 22 | #include <linux/hdreg.h> |
23 | #include <linux/async.h> | ||
23 | 24 | ||
24 | #include <asm/ccwdev.h> | 25 | #include <asm/ccwdev.h> |
25 | #include <asm/ebcdic.h> | 26 | #include <asm/ebcdic.h> |
@@ -480,8 +481,10 @@ static void dasd_change_state(struct dasd_device *device) | |||
480 | if (rc && rc != -EAGAIN) | 481 | if (rc && rc != -EAGAIN) |
481 | device->target = device->state; | 482 | device->target = device->state; |
482 | 483 | ||
483 | if (device->state == device->target) | 484 | if (device->state == device->target) { |
484 | wake_up(&dasd_init_waitq); | 485 | wake_up(&dasd_init_waitq); |
486 | dasd_put_device(device); | ||
487 | } | ||
485 | 488 | ||
486 | /* let user-space know that the device status changed */ | 489 | /* let user-space know that the device status changed */ |
487 | kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE); | 490 | kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE); |
@@ -513,12 +516,15 @@ void dasd_kick_device(struct dasd_device *device) | |||
513 | */ | 516 | */ |
514 | void dasd_set_target_state(struct dasd_device *device, int target) | 517 | void dasd_set_target_state(struct dasd_device *device, int target) |
515 | { | 518 | { |
519 | dasd_get_device(device); | ||
516 | /* If we are in probeonly mode stop at DASD_STATE_READY. */ | 520 | /* If we are in probeonly mode stop at DASD_STATE_READY. */ |
517 | if (dasd_probeonly && target > DASD_STATE_READY) | 521 | if (dasd_probeonly && target > DASD_STATE_READY) |
518 | target = DASD_STATE_READY; | 522 | target = DASD_STATE_READY; |
519 | if (device->target != target) { | 523 | if (device->target != target) { |
520 | if (device->state == target) | 524 | if (device->state == target) { |
521 | wake_up(&dasd_init_waitq); | 525 | wake_up(&dasd_init_waitq); |
526 | dasd_put_device(device); | ||
527 | } | ||
522 | device->target = target; | 528 | device->target = target; |
523 | } | 529 | } |
524 | if (device->state != device->target) | 530 | if (device->state != device->target) |
@@ -2148,6 +2154,22 @@ dasd_exit(void) | |||
2148 | * SECTION: common functions for ccw_driver use | 2154 | * SECTION: common functions for ccw_driver use |
2149 | */ | 2155 | */ |
2150 | 2156 | ||
2157 | static void dasd_generic_auto_online(void *data, async_cookie_t cookie) | ||
2158 | { | ||
2159 | struct ccw_device *cdev = data; | ||
2160 | int ret; | ||
2161 | |||
2162 | ret = ccw_device_set_online(cdev); | ||
2163 | if (ret) | ||
2164 | pr_warning("%s: Setting the DASD online failed with rc=%d\n", | ||
2165 | dev_name(&cdev->dev), ret); | ||
2166 | else { | ||
2167 | struct dasd_device *device = dasd_device_from_cdev(cdev); | ||
2168 | wait_event(dasd_init_waitq, _wait_for_device(device)); | ||
2169 | dasd_put_device(device); | ||
2170 | } | ||
2171 | } | ||
2172 | |||
2151 | /* | 2173 | /* |
2152 | * Initial attempt at a probe function. this can be simplified once | 2174 | * Initial attempt at a probe function. this can be simplified once |
2153 | * the other detection code is gone. | 2175 | * the other detection code is gone. |
@@ -2180,10 +2202,7 @@ int dasd_generic_probe(struct ccw_device *cdev, | |||
2180 | */ | 2202 | */ |
2181 | if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) || | 2203 | if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) || |
2182 | (dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0)) | 2204 | (dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0)) |
2183 | ret = ccw_device_set_online(cdev); | 2205 | async_schedule(dasd_generic_auto_online, cdev); |
2184 | if (ret) | ||
2185 | pr_warning("%s: Setting the DASD online failed with rc=%d\n", | ||
2186 | dev_name(&cdev->dev), ret); | ||
2187 | return 0; | 2206 | return 0; |
2188 | } | 2207 | } |
2189 | 2208 | ||
@@ -2290,13 +2309,7 @@ int dasd_generic_set_online(struct ccw_device *cdev, | |||
2290 | } else | 2309 | } else |
2291 | pr_debug("dasd_generic device %s found\n", | 2310 | pr_debug("dasd_generic device %s found\n", |
2292 | dev_name(&cdev->dev)); | 2311 | dev_name(&cdev->dev)); |
2293 | |||
2294 | /* FIXME: we have to wait for the root device but we don't want | ||
2295 | * to wait for each single device but for all at once. */ | ||
2296 | wait_event(dasd_init_waitq, _wait_for_device(device)); | ||
2297 | |||
2298 | dasd_put_device(device); | 2312 | dasd_put_device(device); |
2299 | |||
2300 | return rc; | 2313 | return rc; |
2301 | } | 2314 | } |
2302 | 2315 | ||
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 21254793c604..cb52da033f06 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -2019,15 +2019,23 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track( | |||
2019 | ccw++; | 2019 | ccw++; |
2020 | recid += count; | 2020 | recid += count; |
2021 | new_track = 0; | 2021 | new_track = 0; |
2022 | /* first idaw for a ccw may start anywhere */ | ||
2023 | if (!idaw_dst) | ||
2024 | idaw_dst = dst; | ||
2022 | } | 2025 | } |
2023 | /* If we start a new idaw, everything is fine and the | 2026 | /* If we start a new idaw, we must make sure that it |
2024 | * start of the new idaw is the start of this segment. | 2027 | * starts on an IDA_BLOCK_SIZE boundary. |
2025 | * If we continue an idaw, we must make sure that the | 2028 | * If we continue an idaw, we must make sure that the |
2026 | * current segment begins where the so far accumulated | 2029 | * current segment begins where the so far accumulated |
2027 | * idaw ends | 2030 | * idaw ends |
2028 | */ | 2031 | */ |
2029 | if (!idaw_dst) | 2032 | if (!idaw_dst) { |
2030 | idaw_dst = dst; | 2033 | if (__pa(dst) & (IDA_BLOCK_SIZE-1)) { |
2034 | dasd_sfree_request(cqr, startdev); | ||
2035 | return ERR_PTR(-ERANGE); | ||
2036 | } else | ||
2037 | idaw_dst = dst; | ||
2038 | } | ||
2031 | if ((idaw_dst + idaw_len) != dst) { | 2039 | if ((idaw_dst + idaw_len) != dst) { |
2032 | dasd_sfree_request(cqr, startdev); | 2040 | dasd_sfree_request(cqr, startdev); |
2033 | return ERR_PTR(-ERANGE); | 2041 | return ERR_PTR(-ERANGE); |
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index c07809c8016a..5469e099597e 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h | |||
@@ -285,7 +285,7 @@ extern int tape_mtop(struct tape_device *, int, int); | |||
285 | extern void tape_state_set(struct tape_device *, enum tape_state); | 285 | extern void tape_state_set(struct tape_device *, enum tape_state); |
286 | 286 | ||
287 | extern int tape_generic_online(struct tape_device *, struct tape_discipline *); | 287 | extern int tape_generic_online(struct tape_device *, struct tape_discipline *); |
288 | extern int tape_generic_offline(struct tape_device *device); | 288 | extern int tape_generic_offline(struct ccw_device *); |
289 | 289 | ||
290 | /* Externals from tape_devmap.c */ | 290 | /* Externals from tape_devmap.c */ |
291 | extern int tape_generic_probe(struct ccw_device *); | 291 | extern int tape_generic_probe(struct ccw_device *); |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 807ded5eb049..5f8e8ef43dd3 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -1294,12 +1294,6 @@ tape_34xx_online(struct ccw_device *cdev) | |||
1294 | ); | 1294 | ); |
1295 | } | 1295 | } |
1296 | 1296 | ||
1297 | static int | ||
1298 | tape_34xx_offline(struct ccw_device *cdev) | ||
1299 | { | ||
1300 | return tape_generic_offline(cdev->dev.driver_data); | ||
1301 | } | ||
1302 | |||
1303 | static struct ccw_driver tape_34xx_driver = { | 1297 | static struct ccw_driver tape_34xx_driver = { |
1304 | .name = "tape_34xx", | 1298 | .name = "tape_34xx", |
1305 | .owner = THIS_MODULE, | 1299 | .owner = THIS_MODULE, |
@@ -1307,7 +1301,7 @@ static struct ccw_driver tape_34xx_driver = { | |||
1307 | .probe = tape_generic_probe, | 1301 | .probe = tape_generic_probe, |
1308 | .remove = tape_generic_remove, | 1302 | .remove = tape_generic_remove, |
1309 | .set_online = tape_34xx_online, | 1303 | .set_online = tape_34xx_online, |
1310 | .set_offline = tape_34xx_offline, | 1304 | .set_offline = tape_generic_offline, |
1311 | }; | 1305 | }; |
1312 | 1306 | ||
1313 | static int | 1307 | static int |
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index fc1d91294143..823b05bd0dd7 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -1707,19 +1707,13 @@ tape_3590_online(struct ccw_device *cdev) | |||
1707 | &tape_discipline_3590); | 1707 | &tape_discipline_3590); |
1708 | } | 1708 | } |
1709 | 1709 | ||
1710 | static int | ||
1711 | tape_3590_offline(struct ccw_device *cdev) | ||
1712 | { | ||
1713 | return tape_generic_offline(cdev->dev.driver_data); | ||
1714 | } | ||
1715 | |||
1716 | static struct ccw_driver tape_3590_driver = { | 1710 | static struct ccw_driver tape_3590_driver = { |
1717 | .name = "tape_3590", | 1711 | .name = "tape_3590", |
1718 | .owner = THIS_MODULE, | 1712 | .owner = THIS_MODULE, |
1719 | .ids = tape_3590_ids, | 1713 | .ids = tape_3590_ids, |
1720 | .probe = tape_generic_probe, | 1714 | .probe = tape_generic_probe, |
1721 | .remove = tape_generic_remove, | 1715 | .remove = tape_generic_remove, |
1722 | .set_offline = tape_3590_offline, | 1716 | .set_offline = tape_generic_offline, |
1723 | .set_online = tape_3590_online, | 1717 | .set_online = tape_3590_online, |
1724 | }; | 1718 | }; |
1725 | 1719 | ||
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 08c09d3503cf..8a109f3b69c6 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -387,8 +387,11 @@ tape_cleanup_device(struct tape_device *device) | |||
387 | * Manual offline is only allowed while the drive is not in use. | 387 | * Manual offline is only allowed while the drive is not in use. |
388 | */ | 388 | */ |
389 | int | 389 | int |
390 | tape_generic_offline(struct tape_device *device) | 390 | tape_generic_offline(struct ccw_device *cdev) |
391 | { | 391 | { |
392 | struct tape_device *device; | ||
393 | |||
394 | device = cdev->dev.driver_data; | ||
392 | if (!device) { | 395 | if (!device) { |
393 | return -ENODEV; | 396 | return -ENODEV; |
394 | } | 397 | } |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 9e8a2914259b..accd957454e7 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -881,42 +881,6 @@ no_handler: | |||
881 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); | 881 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); |
882 | } | 882 | } |
883 | 883 | ||
884 | static void qdio_call_shutdown(struct work_struct *work) | ||
885 | { | ||
886 | struct ccw_device_private *priv; | ||
887 | struct ccw_device *cdev; | ||
888 | |||
889 | priv = container_of(work, struct ccw_device_private, kick_work); | ||
890 | cdev = priv->cdev; | ||
891 | qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); | ||
892 | put_device(&cdev->dev); | ||
893 | } | ||
894 | |||
895 | static void qdio_int_error(struct ccw_device *cdev) | ||
896 | { | ||
897 | struct qdio_irq *irq_ptr = cdev->private->qdio_data; | ||
898 | |||
899 | switch (irq_ptr->state) { | ||
900 | case QDIO_IRQ_STATE_INACTIVE: | ||
901 | case QDIO_IRQ_STATE_CLEANUP: | ||
902 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); | ||
903 | break; | ||
904 | case QDIO_IRQ_STATE_ESTABLISHED: | ||
905 | case QDIO_IRQ_STATE_ACTIVE: | ||
906 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); | ||
907 | if (get_device(&cdev->dev)) { | ||
908 | /* Can't call shutdown from interrupt context. */ | ||
909 | PREPARE_WORK(&cdev->private->kick_work, | ||
910 | qdio_call_shutdown); | ||
911 | queue_work(ccw_device_work, &cdev->private->kick_work); | ||
912 | } | ||
913 | break; | ||
914 | default: | ||
915 | WARN_ON(1); | ||
916 | } | ||
917 | wake_up(&cdev->private->wait_q); | ||
918 | } | ||
919 | |||
920 | static int qdio_establish_check_errors(struct ccw_device *cdev, int cstat, | 884 | static int qdio_establish_check_errors(struct ccw_device *cdev, int cstat, |
921 | int dstat) | 885 | int dstat) |
922 | { | 886 | { |
@@ -973,10 +937,8 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
973 | switch (PTR_ERR(irb)) { | 937 | switch (PTR_ERR(irb)) { |
974 | case -EIO: | 938 | case -EIO: |
975 | DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no); | 939 | DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no); |
976 | return; | 940 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); |
977 | case -ETIMEDOUT: | 941 | wake_up(&cdev->private->wait_q); |
978 | DBF_ERROR("%4x IO timeout", irq_ptr->schid.sch_no); | ||
979 | qdio_int_error(cdev); | ||
980 | return; | 942 | return; |
981 | default: | 943 | default: |
982 | WARN_ON(1); | 944 | WARN_ON(1); |
@@ -1001,7 +963,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
1001 | case QDIO_IRQ_STATE_ACTIVE: | 963 | case QDIO_IRQ_STATE_ACTIVE: |
1002 | if (cstat & SCHN_STAT_PCI) { | 964 | if (cstat & SCHN_STAT_PCI) { |
1003 | qdio_int_handler_pci(irq_ptr); | 965 | qdio_int_handler_pci(irq_ptr); |
1004 | /* no state change so no need to wake up wait_q */ | ||
1005 | return; | 966 | return; |
1006 | } | 967 | } |
1007 | if ((cstat & ~SCHN_STAT_PCI) || dstat) { | 968 | if ((cstat & ~SCHN_STAT_PCI) || dstat) { |
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index e6d1fc8c54f1..a85ad05e8548 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c | |||
@@ -383,18 +383,22 @@ static int jsf_ioctl_program(void __user *arg) | |||
383 | return 0; | 383 | return 0; |
384 | } | 384 | } |
385 | 385 | ||
386 | static int jsf_ioctl(struct inode *inode, struct file *f, unsigned int cmd, | 386 | static long jsf_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
387 | unsigned long arg) | ||
388 | { | 387 | { |
388 | lock_kernel(); | ||
389 | int error = -ENOTTY; | 389 | int error = -ENOTTY; |
390 | void __user *argp = (void __user *)arg; | 390 | void __user *argp = (void __user *)arg; |
391 | 391 | ||
392 | if (!capable(CAP_SYS_ADMIN)) | 392 | if (!capable(CAP_SYS_ADMIN)) { |
393 | unlock_kernel(); | ||
393 | return -EPERM; | 394 | return -EPERM; |
395 | } | ||
394 | switch (cmd) { | 396 | switch (cmd) { |
395 | case JSFLASH_IDENT: | 397 | case JSFLASH_IDENT: |
396 | if (copy_to_user(argp, &jsf0.id, JSFIDSZ)) | 398 | if (copy_to_user(argp, &jsf0.id, JSFIDSZ)) { |
399 | unlock_kernel(); | ||
397 | return -EFAULT; | 400 | return -EFAULT; |
401 | } | ||
398 | break; | 402 | break; |
399 | case JSFLASH_ERASE: | 403 | case JSFLASH_ERASE: |
400 | error = jsf_ioctl_erase(arg); | 404 | error = jsf_ioctl_erase(arg); |
@@ -404,6 +408,7 @@ static int jsf_ioctl(struct inode *inode, struct file *f, unsigned int cmd, | |||
404 | break; | 408 | break; |
405 | } | 409 | } |
406 | 410 | ||
411 | unlock_kernel(); | ||
407 | return error; | 412 | return error; |
408 | } | 413 | } |
409 | 414 | ||
@@ -439,7 +444,7 @@ static const struct file_operations jsf_fops = { | |||
439 | .llseek = jsf_lseek, | 444 | .llseek = jsf_lseek, |
440 | .read = jsf_read, | 445 | .read = jsf_read, |
441 | .write = jsf_write, | 446 | .write = jsf_write, |
442 | .ioctl = jsf_ioctl, | 447 | .unlocked_ioctl = jsf_ioctl, |
443 | .mmap = jsf_mmap, | 448 | .mmap = jsf_mmap, |
444 | .open = jsf_open, | 449 | .open = jsf_open, |
445 | .release = jsf_release, | 450 | .release = jsf_release, |
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 27993c37775d..2c56fd56ec63 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c | |||
@@ -197,9 +197,8 @@ static struct uctrl_driver { | |||
197 | static void uctrl_get_event_status(struct uctrl_driver *); | 197 | static void uctrl_get_event_status(struct uctrl_driver *); |
198 | static void uctrl_get_external_status(struct uctrl_driver *); | 198 | static void uctrl_get_external_status(struct uctrl_driver *); |
199 | 199 | ||
200 | static int | 200 | static long |
201 | uctrl_ioctl(struct inode *inode, struct file *file, | 201 | uctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
202 | unsigned int cmd, unsigned long arg) | ||
203 | { | 202 | { |
204 | switch (cmd) { | 203 | switch (cmd) { |
205 | default: | 204 | default: |
@@ -226,7 +225,7 @@ static irqreturn_t uctrl_interrupt(int irq, void *dev_id) | |||
226 | static const struct file_operations uctrl_fops = { | 225 | static const struct file_operations uctrl_fops = { |
227 | .owner = THIS_MODULE, | 226 | .owner = THIS_MODULE, |
228 | .llseek = no_llseek, | 227 | .llseek = no_llseek, |
229 | .ioctl = uctrl_ioctl, | 228 | .unlocked_ioctl = uctrl_ioctl, |
230 | .open = uctrl_open, | 229 | .open = uctrl_open, |
231 | }; | 230 | }; |
232 | 231 | ||
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index fdb14ec4fd47..8b7983aba8f7 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -2234,10 +2234,10 @@ static int twa_resume(struct pci_dev *pdev) | |||
2234 | pci_set_master(pdev); | 2234 | pci_set_master(pdev); |
2235 | pci_try_set_mwi(pdev); | 2235 | pci_try_set_mwi(pdev); |
2236 | 2236 | ||
2237 | if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) | 2237 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) |
2238 | || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) | 2238 | || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) |
2239 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) | 2239 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) |
2240 | || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { | 2240 | || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { |
2241 | TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during resume"); | 2241 | TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during resume"); |
2242 | retval = -ENODEV; | 2242 | retval = -ENODEV; |
2243 | goto out_disable_device; | 2243 | goto out_disable_device; |
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index 61af3d91ac8a..e3519fa5a3ba 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c | |||
@@ -129,7 +129,7 @@ static int __init a4000t_scsi_init(void) | |||
129 | a4000t_scsi_device = platform_device_register_simple("a4000t-scsi", | 129 | a4000t_scsi_device = platform_device_register_simple("a4000t-scsi", |
130 | -1, NULL, 0); | 130 | -1, NULL, 0); |
131 | if (IS_ERR(a4000t_scsi_device)) { | 131 | if (IS_ERR(a4000t_scsi_device)) { |
132 | platform_driver_register(&a4000t_scsi_driver); | 132 | platform_driver_unregister(&a4000t_scsi_driver); |
133 | return PTR_ERR(a4000t_scsi_device); | 133 | return PTR_ERR(a4000t_scsi_device); |
134 | } | 134 | } |
135 | 135 | ||
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 280261c451d6..2a889853a106 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -1378,7 +1378,7 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1378 | if (dev->nondasd_support && !dev->in_reset) | 1378 | if (dev->nondasd_support && !dev->in_reset) |
1379 | printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); | 1379 | printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); |
1380 | 1380 | ||
1381 | if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK) | 1381 | if (dma_get_required_mask(&dev->pdev->dev) > DMA_BIT_MASK(32)) |
1382 | dev->needs_dac = 1; | 1382 | dev->needs_dac = 1; |
1383 | dev->dac_support = 0; | 1383 | dev->dac_support = 0; |
1384 | if ((sizeof(dma_addr_t) > 4) && dev->needs_dac && | 1384 | if ((sizeof(dma_addr_t) > 4) && dev->needs_dac && |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b1bd3fc7bae8..36fd2e75da1c 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -1394,7 +1394,7 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, | |||
1394 | */ | 1394 | */ |
1395 | cmd->sense_buffer[8] = 0; /* Information */ | 1395 | cmd->sense_buffer[8] = 0; /* Information */ |
1396 | cmd->sense_buffer[9] = 0xa; /* Add. length */ | 1396 | cmd->sense_buffer[9] = 0xa; /* Add. length */ |
1397 | do_div(bghm, cmd->device->sector_size); | 1397 | bghm /= cmd->device->sector_size; |
1398 | 1398 | ||
1399 | failing_sector = scsi_get_lba(cmd); | 1399 | failing_sector = scsi_get_lba(cmd); |
1400 | failing_sector += bghm; | 1400 | failing_sector += bghm; |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 52427a8324f5..a91f5143ceac 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -855,9 +855,9 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev) | |||
855 | if (sizeof(dma_addr_t) > 4) { | 855 | if (sizeof(dma_addr_t) > 4) { |
856 | const uint64_t required_mask = | 856 | const uint64_t required_mask = |
857 | dma_get_required_mask(&pdev->dev); | 857 | dma_get_required_mask(&pdev->dev); |
858 | if ((required_mask > DMA_32BIT_MASK) && !pci_set_dma_mask(pdev, | 858 | if ((required_mask > DMA_BIT_MASK(32)) && !pci_set_dma_mask(pdev, |
859 | DMA_64BIT_MASK) && !pci_set_consistent_dma_mask(pdev, | 859 | DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(pdev, |
860 | DMA_64BIT_MASK)) { | 860 | DMA_BIT_MASK(64))) { |
861 | ioc->base_add_sg_single = &_base_add_sg_single_64; | 861 | ioc->base_add_sg_single = &_base_add_sg_single_64; |
862 | ioc->sge_size = sizeof(Mpi2SGESimple64_t); | 862 | ioc->sge_size = sizeof(Mpi2SGESimple64_t); |
863 | desc = "64"; | 863 | desc = "64"; |
@@ -865,8 +865,8 @@ _base_config_dma_addressing(struct MPT2SAS_ADAPTER *ioc, struct pci_dev *pdev) | |||
865 | } | 865 | } |
866 | } | 866 | } |
867 | 867 | ||
868 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK) | 868 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) |
869 | && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { | 869 | && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { |
870 | ioc->base_add_sg_single = &_base_add_sg_single_32; | 870 | ioc->base_add_sg_single = &_base_add_sg_single_32; |
871 | ioc->sge_size = sizeof(Mpi2SGESimple32_t); | 871 | ioc->sge_size = sizeof(Mpi2SGESimple32_t); |
872 | desc = "32"; | 872 | desc = "32"; |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index e1850904ff73..fbc83bebdd8e 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -38,9 +38,6 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) | |||
38 | { }; | 38 | { }; |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | /* scsi_scan.c */ | ||
42 | int scsi_complete_async_scans(void); | ||
43 | |||
44 | /* scsi_devinfo.c */ | 41 | /* scsi_devinfo.c */ |
45 | extern int scsi_get_device_flags(struct scsi_device *sdev, | 42 | extern int scsi_get_device_flags(struct scsi_device *sdev, |
46 | const unsigned char *vendor, | 43 | const unsigned char *vendor, |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index a14d245a66b8..6f51ca485f35 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -180,8 +180,6 @@ int scsi_complete_async_scans(void) | |||
180 | spin_unlock(&async_scan_lock); | 180 | spin_unlock(&async_scan_lock); |
181 | 181 | ||
182 | kfree(data); | 182 | kfree(data); |
183 | /* Synchronize async operations globally */ | ||
184 | async_synchronize_full(); | ||
185 | return 0; | 183 | return 0; |
186 | } | 184 | } |
187 | 185 | ||
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c index 8a636103083d..74708fcaf82f 100644 --- a/drivers/scsi/scsi_wait_scan.c +++ b/drivers/scsi/scsi_wait_scan.c | |||
@@ -11,10 +11,21 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include "scsi_priv.h" | 14 | #include <linux/device.h> |
15 | #include <scsi/scsi_scan.h> | ||
15 | 16 | ||
16 | static int __init wait_scan_init(void) | 17 | static int __init wait_scan_init(void) |
17 | { | 18 | { |
19 | /* | ||
20 | * First we need to wait for device probing to finish; | ||
21 | * the drivers we just loaded might just still be probing | ||
22 | * and might not yet have reached the scsi async scanning | ||
23 | */ | ||
24 | wait_for_device_probe(); | ||
25 | /* | ||
26 | * and then we wait for the actual asynchronous scsi scan | ||
27 | * to finish. | ||
28 | */ | ||
18 | scsi_complete_async_scans(); | 29 | scsi_complete_async_scans(); |
19 | return 0; | 30 | return 0; |
20 | } | 31 | } |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 7ddff3f55087..938bc1b6c3fa 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -771,8 +771,6 @@ static int pci_netmos_init(struct pci_dev *dev) | |||
771 | } | 771 | } |
772 | 772 | ||
773 | /* | 773 | /* |
774 | * ITE support by Niels de Vos <niels.devos@wincor-nixdorf.com> | ||
775 | * | ||
776 | * These chips are available with optionally one parallel port and up to | 774 | * These chips are available with optionally one parallel port and up to |
777 | * two serial ports. Unfortunately they all have the same product id. | 775 | * two serial ports. Unfortunately they all have the same product id. |
778 | * | 776 | * |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 0328fd4006e5..343e3a35b6a3 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -854,7 +854,7 @@ config SERIAL_IMX_CONSOLE | |||
854 | 854 | ||
855 | config SERIAL_UARTLITE | 855 | config SERIAL_UARTLITE |
856 | tristate "Xilinx uartlite serial port support" | 856 | tristate "Xilinx uartlite serial port support" |
857 | depends on PPC32 | 857 | depends on PPC32 || MICROBLAZE |
858 | select SERIAL_CORE | 858 | select SERIAL_CORE |
859 | help | 859 | help |
860 | Say Y here if you want to use the Xilinx uartlite serial controller. | 860 | Say Y here if you want to use the Xilinx uartlite serial controller. |
@@ -1340,7 +1340,7 @@ config SERIAL_NETX_CONSOLE | |||
1340 | 1340 | ||
1341 | config SERIAL_OF_PLATFORM | 1341 | config SERIAL_OF_PLATFORM |
1342 | tristate "Serial port on Open Firmware platform bus" | 1342 | tristate "Serial port on Open Firmware platform bus" |
1343 | depends on PPC_OF | 1343 | depends on PPC_OF || MICROBLAZE |
1344 | depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL | 1344 | depends on SERIAL_8250 || SERIAL_OF_PLATFORM_NWPSERIAL |
1345 | help | 1345 | help |
1346 | If you have a PowerPC based system that has serial ports | 1346 | If you have a PowerPC based system that has serial ports |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 18ba812a4f84..d86123e03391 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -166,7 +166,7 @@ static void bfin_serial_start_tx(struct uart_port *port) | |||
166 | struct tty_struct *tty = uart->port.info->port.tty; | 166 | struct tty_struct *tty = uart->port.info->port.tty; |
167 | 167 | ||
168 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 168 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
169 | if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { | 169 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { |
170 | uart->scts = 0; | 170 | uart->scts = 0; |
171 | uart_handle_cts_change(&uart->port, uart->scts); | 171 | uart_handle_cts_change(&uart->port, uart->scts); |
172 | } | 172 | } |
@@ -368,7 +368,7 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) | |||
368 | struct bfin_serial_port *uart = dev_id; | 368 | struct bfin_serial_port *uart = dev_id; |
369 | 369 | ||
370 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 370 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
371 | if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { | 371 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { |
372 | uart->scts = 0; | 372 | uart->scts = 0; |
373 | uart_handle_cts_change(&uart->port, uart->scts); | 373 | uart_handle_cts_change(&uart->port, uart->scts); |
374 | } | 374 | } |
@@ -504,7 +504,7 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) | |||
504 | struct circ_buf *xmit = &uart->port.info->xmit; | 504 | struct circ_buf *xmit = &uart->port.info->xmit; |
505 | 505 | ||
506 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 506 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
507 | if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { | 507 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { |
508 | uart->scts = 0; | 508 | uart->scts = 0; |
509 | uart_handle_cts_change(&uart->port, uart->scts); | 509 | uart_handle_cts_change(&uart->port, uart->scts); |
510 | } | 510 | } |
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c index 41ac94872b8d..e06686ae858b 100644 --- a/drivers/serial/samsung.c +++ b/drivers/serial/samsung.c | |||
@@ -127,7 +127,7 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port) | |||
127 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 127 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
128 | 128 | ||
129 | if (tx_enabled(port)) { | 129 | if (tx_enabled(port)) { |
130 | disable_irq(ourport->tx_irq); | 130 | disable_irq_nosync(ourport->tx_irq); |
131 | tx_enabled(port) = 0; | 131 | tx_enabled(port) = 0; |
132 | if (port->flags & UPF_CONS_FLOW) | 132 | if (port->flags & UPF_CONS_FLOW) |
133 | s3c24xx_serial_rx_enable(port); | 133 | s3c24xx_serial_rx_enable(port); |
@@ -154,7 +154,7 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port) | |||
154 | 154 | ||
155 | if (rx_enabled(port)) { | 155 | if (rx_enabled(port)) { |
156 | dbg("s3c24xx_serial_stop_rx: port=%p\n", port); | 156 | dbg("s3c24xx_serial_stop_rx: port=%p\n", port); |
157 | disable_irq(ourport->rx_irq); | 157 | disable_irq_nosync(ourport->rx_irq); |
158 | rx_enabled(port) = 0; | 158 | rx_enabled(port) = 0; |
159 | } | 159 | } |
160 | } | 160 | } |
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index 7fb9b5c4669a..12d13d99b6f0 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c | |||
@@ -44,6 +44,7 @@ struct intc_handle_int { | |||
44 | struct intc_desc_int { | 44 | struct intc_desc_int { |
45 | struct list_head list; | 45 | struct list_head list; |
46 | struct sys_device sysdev; | 46 | struct sys_device sysdev; |
47 | pm_message_t state; | ||
47 | unsigned long *reg; | 48 | unsigned long *reg; |
48 | #ifdef CONFIG_SMP | 49 | #ifdef CONFIG_SMP |
49 | unsigned long *smp; | 50 | unsigned long *smp; |
@@ -786,18 +787,44 @@ static int intc_suspend(struct sys_device *dev, pm_message_t state) | |||
786 | /* get intc controller associated with this sysdev */ | 787 | /* get intc controller associated with this sysdev */ |
787 | d = container_of(dev, struct intc_desc_int, sysdev); | 788 | d = container_of(dev, struct intc_desc_int, sysdev); |
788 | 789 | ||
789 | /* enable wakeup irqs belonging to this intc controller */ | 790 | switch (state.event) { |
790 | for_each_irq_desc(irq, desc) { | 791 | case PM_EVENT_ON: |
791 | if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip)) | 792 | if (d->state.event != PM_EVENT_FREEZE) |
792 | intc_enable(irq); | 793 | break; |
794 | for_each_irq_desc(irq, desc) { | ||
795 | if (desc->chip != &d->chip) | ||
796 | continue; | ||
797 | if (desc->status & IRQ_DISABLED) | ||
798 | intc_disable(irq); | ||
799 | else | ||
800 | intc_enable(irq); | ||
801 | } | ||
802 | break; | ||
803 | case PM_EVENT_FREEZE: | ||
804 | /* nothing has to be done */ | ||
805 | break; | ||
806 | case PM_EVENT_SUSPEND: | ||
807 | /* enable wakeup irqs belonging to this intc controller */ | ||
808 | for_each_irq_desc(irq, desc) { | ||
809 | if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip)) | ||
810 | intc_enable(irq); | ||
811 | } | ||
812 | break; | ||
793 | } | 813 | } |
814 | d->state = state; | ||
794 | 815 | ||
795 | return 0; | 816 | return 0; |
796 | } | 817 | } |
797 | 818 | ||
819 | static int intc_resume(struct sys_device *dev) | ||
820 | { | ||
821 | return intc_suspend(dev, PMSG_ON); | ||
822 | } | ||
823 | |||
798 | static struct sysdev_class intc_sysdev_class = { | 824 | static struct sysdev_class intc_sysdev_class = { |
799 | .name = "intc", | 825 | .name = "intc", |
800 | .suspend = intc_suspend, | 826 | .suspend = intc_suspend, |
827 | .resume = intc_resume, | ||
801 | }; | 828 | }; |
802 | 829 | ||
803 | /* register this intc as sysdev to allow suspend/resume */ | 830 | /* register this intc as sysdev to allow suspend/resume */ |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index c1688c71f052..885194a07418 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -195,7 +195,7 @@ static void cs_deassert(struct driver_data *drv_data) | |||
195 | struct chip_data *chip = drv_data->cur_chip; | 195 | struct chip_data *chip = drv_data->cur_chip; |
196 | 196 | ||
197 | if (chip->cs_control) { | 197 | if (chip->cs_control) { |
198 | chip->cs_control(PXA2XX_CS_ASSERT); | 198 | chip->cs_control(PXA2XX_CS_DEASSERT); |
199 | return; | 199 | return; |
200 | } | 200 | } |
201 | 201 | ||
@@ -213,7 +213,7 @@ static int flush(struct driver_data *drv_data) | |||
213 | while (read_SSSR(reg) & SSSR_RNE) { | 213 | while (read_SSSR(reg) & SSSR_RNE) { |
214 | read_SSDR(reg); | 214 | read_SSDR(reg); |
215 | } | 215 | } |
216 | } while ((read_SSSR(reg) & SSSR_BSY) && limit--); | 216 | } while ((read_SSSR(reg) & SSSR_BSY) && --limit); |
217 | write_SSSR(SSSR_ROR, reg); | 217 | write_SSSR(SSSR_ROR, reg); |
218 | 218 | ||
219 | return limit; | 219 | return limit; |
@@ -484,7 +484,7 @@ static int wait_ssp_rx_stall(void const __iomem *ioaddr) | |||
484 | { | 484 | { |
485 | unsigned long limit = loops_per_jiffy << 1; | 485 | unsigned long limit = loops_per_jiffy << 1; |
486 | 486 | ||
487 | while ((read_SSSR(ioaddr) & SSSR_BSY) && limit--) | 487 | while ((read_SSSR(ioaddr) & SSSR_BSY) && --limit) |
488 | cpu_relax(); | 488 | cpu_relax(); |
489 | 489 | ||
490 | return limit; | 490 | return limit; |
@@ -494,7 +494,7 @@ static int wait_dma_channel_stop(int channel) | |||
494 | { | 494 | { |
495 | unsigned long limit = loops_per_jiffy << 1; | 495 | unsigned long limit = loops_per_jiffy << 1; |
496 | 496 | ||
497 | while (!(DCSR(channel) & DCSR_STOPSTATE) && limit--) | 497 | while (!(DCSR(channel) & DCSR_STOPSTATE) && --limit) |
498 | cpu_relax(); | 498 | cpu_relax(); |
499 | 499 | ||
500 | return limit; | 500 | return limit; |
@@ -1700,6 +1700,13 @@ static int pxa2xx_spi_resume(struct platform_device *pdev) | |||
1700 | struct ssp_device *ssp = drv_data->ssp; | 1700 | struct ssp_device *ssp = drv_data->ssp; |
1701 | int status = 0; | 1701 | int status = 0; |
1702 | 1702 | ||
1703 | if (drv_data->rx_channel != -1) | ||
1704 | DRCMR(drv_data->ssp->drcmr_rx) = | ||
1705 | DRCMR_MAPVLD | drv_data->rx_channel; | ||
1706 | if (drv_data->tx_channel != -1) | ||
1707 | DRCMR(drv_data->ssp->drcmr_tx) = | ||
1708 | DRCMR_MAPVLD | drv_data->tx_channel; | ||
1709 | |||
1703 | /* Enable the SSP clock */ | 1710 | /* Enable the SSP clock */ |
1704 | clk_enable(ssp->clk); | 1711 | clk_enable(ssp->clk); |
1705 | 1712 | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 643908b74bc0..8eba98c8ed1e 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -658,7 +658,7 @@ int spi_write_then_read(struct spi_device *spi, | |||
658 | 658 | ||
659 | int status; | 659 | int status; |
660 | struct spi_message message; | 660 | struct spi_message message; |
661 | struct spi_transfer x; | 661 | struct spi_transfer x[2]; |
662 | u8 *local_buf; | 662 | u8 *local_buf; |
663 | 663 | ||
664 | /* Use preallocated DMA-safe buffer. We can't avoid copying here, | 664 | /* Use preallocated DMA-safe buffer. We can't avoid copying here, |
@@ -669,9 +669,15 @@ int spi_write_then_read(struct spi_device *spi, | |||
669 | return -EINVAL; | 669 | return -EINVAL; |
670 | 670 | ||
671 | spi_message_init(&message); | 671 | spi_message_init(&message); |
672 | memset(&x, 0, sizeof x); | 672 | memset(x, 0, sizeof x); |
673 | x.len = n_tx + n_rx; | 673 | if (n_tx) { |
674 | spi_message_add_tail(&x, &message); | 674 | x[0].len = n_tx; |
675 | spi_message_add_tail(&x[0], &message); | ||
676 | } | ||
677 | if (n_rx) { | ||
678 | x[1].len = n_rx; | ||
679 | spi_message_add_tail(&x[1], &message); | ||
680 | } | ||
675 | 681 | ||
676 | /* ... unless someone else is using the pre-allocated buffer */ | 682 | /* ... unless someone else is using the pre-allocated buffer */ |
677 | if (!mutex_trylock(&lock)) { | 683 | if (!mutex_trylock(&lock)) { |
@@ -682,15 +688,15 @@ int spi_write_then_read(struct spi_device *spi, | |||
682 | local_buf = buf; | 688 | local_buf = buf; |
683 | 689 | ||
684 | memcpy(local_buf, txbuf, n_tx); | 690 | memcpy(local_buf, txbuf, n_tx); |
685 | x.tx_buf = local_buf; | 691 | x[0].tx_buf = local_buf; |
686 | x.rx_buf = local_buf; | 692 | x[1].rx_buf = local_buf + n_tx; |
687 | 693 | ||
688 | /* do the i/o */ | 694 | /* do the i/o */ |
689 | status = spi_sync(spi, &message); | 695 | status = spi_sync(spi, &message); |
690 | if (status == 0) | 696 | if (status == 0) |
691 | memcpy(rxbuf, x.rx_buf + n_tx, n_rx); | 697 | memcpy(rxbuf, x[1].rx_buf, n_rx); |
692 | 698 | ||
693 | if (x.tx_buf == buf) | 699 | if (x[0].tx_buf == buf) |
694 | mutex_unlock(&lock); | 700 | mutex_unlock(&lock); |
695 | else | 701 | else |
696 | kfree(local_buf); | 702 | kfree(local_buf); |
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 79e90fed27d3..299d29d1dadb 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c | |||
@@ -41,6 +41,8 @@ static int binder_last_id; | |||
41 | static struct proc_dir_entry *binder_proc_dir_entry_root; | 41 | static struct proc_dir_entry *binder_proc_dir_entry_root; |
42 | static struct proc_dir_entry *binder_proc_dir_entry_proc; | 42 | static struct proc_dir_entry *binder_proc_dir_entry_proc; |
43 | static struct hlist_head binder_dead_nodes; | 43 | static struct hlist_head binder_dead_nodes; |
44 | static HLIST_HEAD(binder_deferred_list); | ||
45 | static DEFINE_MUTEX(binder_deferred_lock); | ||
44 | 46 | ||
45 | static int binder_read_proc_proc( | 47 | static int binder_read_proc_proc( |
46 | char *page, char **start, off_t off, int count, int *eof, void *data); | 48 | char *page, char **start, off_t off, int count, int *eof, void *data); |
@@ -54,11 +56,7 @@ static int binder_read_proc_proc( | |||
54 | #define SZ_4M 0x400000 | 56 | #define SZ_4M 0x400000 |
55 | #endif | 57 | #endif |
56 | 58 | ||
57 | #ifndef __i386__ | ||
58 | #define FORBIDDEN_MMAP_FLAGS (VM_WRITE | VM_EXEC) | ||
59 | #else | ||
60 | #define FORBIDDEN_MMAP_FLAGS (VM_WRITE) | 59 | #define FORBIDDEN_MMAP_FLAGS (VM_WRITE) |
61 | #endif | ||
62 | 60 | ||
63 | #define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64) | 61 | #define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64) |
64 | 62 | ||
@@ -236,6 +234,12 @@ struct binder_buffer { | |||
236 | uint8_t data[0]; | 234 | uint8_t data[0]; |
237 | }; | 235 | }; |
238 | 236 | ||
237 | enum { | ||
238 | BINDER_DEFERRED_PUT_FILES = 0x01, | ||
239 | BINDER_DEFERRED_FLUSH = 0x02, | ||
240 | BINDER_DEFERRED_RELEASE = 0x04, | ||
241 | }; | ||
242 | |||
239 | struct binder_proc { | 243 | struct binder_proc { |
240 | struct hlist_node proc_node; | 244 | struct hlist_node proc_node; |
241 | struct rb_root threads; | 245 | struct rb_root threads; |
@@ -245,8 +249,11 @@ struct binder_proc { | |||
245 | int pid; | 249 | int pid; |
246 | struct vm_area_struct *vma; | 250 | struct vm_area_struct *vma; |
247 | struct task_struct *tsk; | 251 | struct task_struct *tsk; |
252 | struct files_struct *files; | ||
253 | struct hlist_node deferred_work_node; | ||
254 | int deferred_work; | ||
248 | void *buffer; | 255 | void *buffer; |
249 | size_t user_buffer_offset; | 256 | ptrdiff_t user_buffer_offset; |
250 | 257 | ||
251 | struct list_head buffers; | 258 | struct list_head buffers; |
252 | struct rb_root free_buffers; | 259 | struct rb_root free_buffers; |
@@ -310,12 +317,14 @@ struct binder_transaction { | |||
310 | uid_t sender_euid; | 317 | uid_t sender_euid; |
311 | }; | 318 | }; |
312 | 319 | ||
320 | static void binder_defer_work(struct binder_proc *proc, int defer); | ||
321 | |||
313 | /* | 322 | /* |
314 | * copied from get_unused_fd_flags | 323 | * copied from get_unused_fd_flags |
315 | */ | 324 | */ |
316 | int task_get_unused_fd_flags(struct task_struct *tsk, int flags) | 325 | int task_get_unused_fd_flags(struct binder_proc *proc, int flags) |
317 | { | 326 | { |
318 | struct files_struct *files = get_files_struct(tsk); | 327 | struct files_struct *files = proc->files; |
319 | int fd, error; | 328 | int fd, error; |
320 | struct fdtable *fdt; | 329 | struct fdtable *fdt; |
321 | unsigned long rlim_cur; | 330 | unsigned long rlim_cur; |
@@ -337,9 +346,9 @@ repeat: | |||
337 | * will limit the total number of files that can be opened. | 346 | * will limit the total number of files that can be opened. |
338 | */ | 347 | */ |
339 | rlim_cur = 0; | 348 | rlim_cur = 0; |
340 | if (lock_task_sighand(tsk, &irqs)) { | 349 | if (lock_task_sighand(proc->tsk, &irqs)) { |
341 | rlim_cur = tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; | 350 | rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; |
342 | unlock_task_sighand(tsk, &irqs); | 351 | unlock_task_sighand(proc->tsk, &irqs); |
343 | } | 352 | } |
344 | if (fd >= rlim_cur) | 353 | if (fd >= rlim_cur) |
345 | goto out; | 354 | goto out; |
@@ -375,7 +384,6 @@ repeat: | |||
375 | 384 | ||
376 | out: | 385 | out: |
377 | spin_unlock(&files->file_lock); | 386 | spin_unlock(&files->file_lock); |
378 | put_files_struct(files); | ||
379 | return error; | 387 | return error; |
380 | } | 388 | } |
381 | 389 | ||
@@ -383,9 +391,9 @@ out: | |||
383 | * copied from fd_install | 391 | * copied from fd_install |
384 | */ | 392 | */ |
385 | static void task_fd_install( | 393 | static void task_fd_install( |
386 | struct task_struct *tsk, unsigned int fd, struct file *file) | 394 | struct binder_proc *proc, unsigned int fd, struct file *file) |
387 | { | 395 | { |
388 | struct files_struct *files = get_files_struct(tsk); | 396 | struct files_struct *files = proc->files; |
389 | struct fdtable *fdt; | 397 | struct fdtable *fdt; |
390 | 398 | ||
391 | if (files == NULL) | 399 | if (files == NULL) |
@@ -396,7 +404,6 @@ static void task_fd_install( | |||
396 | BUG_ON(fdt->fd[fd] != NULL); | 404 | BUG_ON(fdt->fd[fd] != NULL); |
397 | rcu_assign_pointer(fdt->fd[fd], file); | 405 | rcu_assign_pointer(fdt->fd[fd], file); |
398 | spin_unlock(&files->file_lock); | 406 | spin_unlock(&files->file_lock); |
399 | put_files_struct(files); | ||
400 | } | 407 | } |
401 | 408 | ||
402 | /* | 409 | /* |
@@ -413,10 +420,10 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd) | |||
413 | /* | 420 | /* |
414 | * copied from sys_close | 421 | * copied from sys_close |
415 | */ | 422 | */ |
416 | static long task_close_fd(struct task_struct *tsk, unsigned int fd) | 423 | static long task_close_fd(struct binder_proc *proc, unsigned int fd) |
417 | { | 424 | { |
418 | struct file *filp; | 425 | struct file *filp; |
419 | struct files_struct *files = get_files_struct(tsk); | 426 | struct files_struct *files = proc->files; |
420 | struct fdtable *fdt; | 427 | struct fdtable *fdt; |
421 | int retval; | 428 | int retval; |
422 | 429 | ||
@@ -443,12 +450,10 @@ static long task_close_fd(struct task_struct *tsk, unsigned int fd) | |||
443 | retval == -ERESTART_RESTARTBLOCK)) | 450 | retval == -ERESTART_RESTARTBLOCK)) |
444 | retval = -EINTR; | 451 | retval = -EINTR; |
445 | 452 | ||
446 | put_files_struct(files); | ||
447 | return retval; | 453 | return retval; |
448 | 454 | ||
449 | out_unlock: | 455 | out_unlock: |
450 | spin_unlock(&files->file_lock); | 456 | spin_unlock(&files->file_lock); |
451 | put_files_struct(files); | ||
452 | return -EBADF; | 457 | return -EBADF; |
453 | } | 458 | } |
454 | 459 | ||
@@ -618,7 +623,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, | |||
618 | proc->pid, page_addr); | 623 | proc->pid, page_addr); |
619 | goto err_map_kernel_failed; | 624 | goto err_map_kernel_failed; |
620 | } | 625 | } |
621 | user_page_addr = (size_t)page_addr + proc->user_buffer_offset; | 626 | user_page_addr = |
627 | (uintptr_t)page_addr + proc->user_buffer_offset; | ||
622 | ret = vm_insert_page(vma, user_page_addr, page[0]); | 628 | ret = vm_insert_page(vma, user_page_addr, page[0]); |
623 | if (ret) { | 629 | if (ret) { |
624 | printk(KERN_ERR "binder: %d: binder_alloc_buf failed " | 630 | printk(KERN_ERR "binder: %d: binder_alloc_buf failed " |
@@ -639,7 +645,7 @@ free_range: | |||
639 | page_addr -= PAGE_SIZE) { | 645 | page_addr -= PAGE_SIZE) { |
640 | page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; | 646 | page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; |
641 | if (vma) | 647 | if (vma) |
642 | zap_page_range(vma, (size_t)page_addr + | 648 | zap_page_range(vma, (uintptr_t)page_addr + |
643 | proc->user_buffer_offset, PAGE_SIZE, NULL); | 649 | proc->user_buffer_offset, PAGE_SIZE, NULL); |
644 | err_vm_insert_page_failed: | 650 | err_vm_insert_page_failed: |
645 | unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); | 651 | unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); |
@@ -720,18 +726,19 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, | |||
720 | "er %p size %zd\n", proc->pid, size, buffer, buffer_size); | 726 | "er %p size %zd\n", proc->pid, size, buffer, buffer_size); |
721 | 727 | ||
722 | has_page_addr = | 728 | has_page_addr = |
723 | (void *)(((size_t)buffer->data + buffer_size) & PAGE_MASK); | 729 | (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK); |
724 | if (n == NULL) { | 730 | if (n == NULL) { |
725 | if (size + sizeof(struct binder_buffer) + 4 >= buffer_size) | 731 | if (size + sizeof(struct binder_buffer) + 4 >= buffer_size) |
726 | buffer_size = size; /* no room for other buffers */ | 732 | buffer_size = size; /* no room for other buffers */ |
727 | else | 733 | else |
728 | buffer_size = size + sizeof(struct binder_buffer); | 734 | buffer_size = size + sizeof(struct binder_buffer); |
729 | } | 735 | } |
730 | end_page_addr = (void *)PAGE_ALIGN((size_t)buffer->data + buffer_size); | 736 | end_page_addr = |
737 | (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size); | ||
731 | if (end_page_addr > has_page_addr) | 738 | if (end_page_addr > has_page_addr) |
732 | end_page_addr = has_page_addr; | 739 | end_page_addr = has_page_addr; |
733 | if (binder_update_page_range(proc, 1, | 740 | if (binder_update_page_range(proc, 1, |
734 | (void *)PAGE_ALIGN((size_t)buffer->data), end_page_addr, NULL)) | 741 | (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)) |
735 | return NULL; | 742 | return NULL; |
736 | 743 | ||
737 | rb_erase(best_fit, &proc->free_buffers); | 744 | rb_erase(best_fit, &proc->free_buffers); |
@@ -762,12 +769,12 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, | |||
762 | 769 | ||
763 | static void *buffer_start_page(struct binder_buffer *buffer) | 770 | static void *buffer_start_page(struct binder_buffer *buffer) |
764 | { | 771 | { |
765 | return (void *)((size_t)buffer & PAGE_MASK); | 772 | return (void *)((uintptr_t)buffer & PAGE_MASK); |
766 | } | 773 | } |
767 | 774 | ||
768 | static void *buffer_end_page(struct binder_buffer *buffer) | 775 | static void *buffer_end_page(struct binder_buffer *buffer) |
769 | { | 776 | { |
770 | return (void *)(((size_t)(buffer + 1) - 1) & PAGE_MASK); | 777 | return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK); |
771 | } | 778 | } |
772 | 779 | ||
773 | static void binder_delete_free_buffer( | 780 | static void binder_delete_free_buffer( |
@@ -845,8 +852,8 @@ static void binder_free_buf( | |||
845 | } | 852 | } |
846 | 853 | ||
847 | binder_update_page_range(proc, 0, | 854 | binder_update_page_range(proc, 0, |
848 | (void *)PAGE_ALIGN((size_t)buffer->data), | 855 | (void *)PAGE_ALIGN((uintptr_t)buffer->data), |
849 | (void *)(((size_t)buffer->data + buffer_size) & PAGE_MASK), | 856 | (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK), |
850 | NULL); | 857 | NULL); |
851 | rb_erase(&buffer->rb_node, &proc->allocated_buffers); | 858 | rb_erase(&buffer->rb_node, &proc->allocated_buffers); |
852 | buffer->free = 1; | 859 | buffer->free = 1; |
@@ -1345,6 +1352,17 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread, | |||
1345 | if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { | 1352 | if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { |
1346 | struct binder_transaction *tmp; | 1353 | struct binder_transaction *tmp; |
1347 | tmp = thread->transaction_stack; | 1354 | tmp = thread->transaction_stack; |
1355 | if (tmp->to_thread != thread) { | ||
1356 | binder_user_error("binder: %d:%d got new " | ||
1357 | "transaction with bad transaction stack" | ||
1358 | ", transaction %d has target %d:%d\n", | ||
1359 | proc->pid, thread->pid, tmp->debug_id, | ||
1360 | tmp->to_proc ? tmp->to_proc->pid : 0, | ||
1361 | tmp->to_thread ? | ||
1362 | tmp->to_thread->pid : 0); | ||
1363 | return_error = BR_FAILED_REPLY; | ||
1364 | goto err_bad_call_stack; | ||
1365 | } | ||
1348 | while (tmp) { | 1366 | while (tmp) { |
1349 | if (tmp->from && tmp->from->proc == target_proc) | 1367 | if (tmp->from && tmp->from->proc == target_proc) |
1350 | target_thread = tmp->from; | 1368 | target_thread = tmp->from; |
@@ -1434,10 +1452,19 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread, | |||
1434 | return_error = BR_FAILED_REPLY; | 1452 | return_error = BR_FAILED_REPLY; |
1435 | goto err_copy_data_failed; | 1453 | goto err_copy_data_failed; |
1436 | } | 1454 | } |
1455 | if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { | ||
1456 | binder_user_error("binder: %d:%d got transaction with " | ||
1457 | "invalid offsets size, %zd\n", | ||
1458 | proc->pid, thread->pid, tr->offsets_size); | ||
1459 | return_error = BR_FAILED_REPLY; | ||
1460 | goto err_bad_offset; | ||
1461 | } | ||
1437 | off_end = (void *)offp + tr->offsets_size; | 1462 | off_end = (void *)offp + tr->offsets_size; |
1438 | for (; offp < off_end; offp++) { | 1463 | for (; offp < off_end; offp++) { |
1439 | struct flat_binder_object *fp; | 1464 | struct flat_binder_object *fp; |
1440 | if (*offp > t->buffer->data_size - sizeof(*fp)) { | 1465 | if (*offp > t->buffer->data_size - sizeof(*fp) || |
1466 | t->buffer->data_size < sizeof(*fp) || | ||
1467 | !IS_ALIGNED(*offp, sizeof(void *))) { | ||
1441 | binder_user_error("binder: %d:%d got transaction with " | 1468 | binder_user_error("binder: %d:%d got transaction with " |
1442 | "invalid offset, %zd\n", | 1469 | "invalid offset, %zd\n", |
1443 | proc->pid, thread->pid, *offp); | 1470 | proc->pid, thread->pid, *offp); |
@@ -1544,13 +1571,13 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread, | |||
1544 | return_error = BR_FAILED_REPLY; | 1571 | return_error = BR_FAILED_REPLY; |
1545 | goto err_fget_failed; | 1572 | goto err_fget_failed; |
1546 | } | 1573 | } |
1547 | target_fd = task_get_unused_fd_flags(target_proc->tsk, O_CLOEXEC); | 1574 | target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); |
1548 | if (target_fd < 0) { | 1575 | if (target_fd < 0) { |
1549 | fput(file); | 1576 | fput(file); |
1550 | return_error = BR_FAILED_REPLY; | 1577 | return_error = BR_FAILED_REPLY; |
1551 | goto err_get_unused_fd_failed; | 1578 | goto err_get_unused_fd_failed; |
1552 | } | 1579 | } |
1553 | task_fd_install(target_proc->tsk, target_fd, file); | 1580 | task_fd_install(target_proc, target_fd, file); |
1554 | if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) | 1581 | if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) |
1555 | printk(KERN_INFO " fd %ld -> %d\n", fp->handle, target_fd); | 1582 | printk(KERN_INFO " fd %ld -> %d\n", fp->handle, target_fd); |
1556 | /* TODO: fput? */ | 1583 | /* TODO: fput? */ |
@@ -1655,7 +1682,9 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer | |||
1655 | off_end = (void *)offp + buffer->offsets_size; | 1682 | off_end = (void *)offp + buffer->offsets_size; |
1656 | for (; offp < off_end; offp++) { | 1683 | for (; offp < off_end; offp++) { |
1657 | struct flat_binder_object *fp; | 1684 | struct flat_binder_object *fp; |
1658 | if (*offp > buffer->data_size - sizeof(*fp)) { | 1685 | if (*offp > buffer->data_size - sizeof(*fp) || |
1686 | buffer->data_size < sizeof(*fp) || | ||
1687 | !IS_ALIGNED(*offp, sizeof(void *))) { | ||
1659 | printk(KERN_ERR "binder: transaction release %d bad" | 1688 | printk(KERN_ERR "binder: transaction release %d bad" |
1660 | "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); | 1689 | "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); |
1661 | continue; | 1690 | continue; |
@@ -1691,7 +1720,7 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer | |||
1691 | if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) | 1720 | if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) |
1692 | printk(KERN_INFO " fd %ld\n", fp->handle); | 1721 | printk(KERN_INFO " fd %ld\n", fp->handle); |
1693 | if (failed_at) | 1722 | if (failed_at) |
1694 | task_close_fd(proc->tsk, fp->handle); | 1723 | task_close_fd(proc, fp->handle); |
1695 | break; | 1724 | break; |
1696 | 1725 | ||
1697 | default: | 1726 | default: |
@@ -2340,7 +2369,7 @@ retry: | |||
2340 | 2369 | ||
2341 | tr.data_size = t->buffer->data_size; | 2370 | tr.data_size = t->buffer->data_size; |
2342 | tr.offsets_size = t->buffer->offsets_size; | 2371 | tr.offsets_size = t->buffer->offsets_size; |
2343 | tr.data.ptr.buffer = (void *)((void *)t->buffer->data + proc->user_buffer_offset); | 2372 | tr.data.ptr.buffer = (void *)t->buffer->data + proc->user_buffer_offset; |
2344 | tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size, sizeof(void *)); | 2373 | tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size, sizeof(void *)); |
2345 | 2374 | ||
2346 | if (put_user(cmd, (uint32_t __user *)ptr)) | 2375 | if (put_user(cmd, (uint32_t __user *)ptr)) |
@@ -2656,6 +2685,7 @@ static void binder_vma_open(struct vm_area_struct *vma) | |||
2656 | (unsigned long)pgprot_val(vma->vm_page_prot)); | 2685 | (unsigned long)pgprot_val(vma->vm_page_prot)); |
2657 | dump_stack(); | 2686 | dump_stack(); |
2658 | } | 2687 | } |
2688 | |||
2659 | static void binder_vma_close(struct vm_area_struct *vma) | 2689 | static void binder_vma_close(struct vm_area_struct *vma) |
2660 | { | 2690 | { |
2661 | struct binder_proc *proc = vma->vm_private_data; | 2691 | struct binder_proc *proc = vma->vm_private_data; |
@@ -2666,6 +2696,7 @@ static void binder_vma_close(struct vm_area_struct *vma) | |||
2666 | (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, | 2696 | (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, |
2667 | (unsigned long)pgprot_val(vma->vm_page_prot)); | 2697 | (unsigned long)pgprot_val(vma->vm_page_prot)); |
2668 | proc->vma = NULL; | 2698 | proc->vma = NULL; |
2699 | binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); | ||
2669 | } | 2700 | } |
2670 | 2701 | ||
2671 | static struct vm_operations_struct binder_vm_ops = { | 2702 | static struct vm_operations_struct binder_vm_ops = { |
@@ -2698,6 +2729,12 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2698 | } | 2729 | } |
2699 | vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; | 2730 | vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; |
2700 | 2731 | ||
2732 | if (proc->buffer) { | ||
2733 | ret = -EBUSY; | ||
2734 | failure_string = "already mapped"; | ||
2735 | goto err_already_mapped; | ||
2736 | } | ||
2737 | |||
2701 | area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); | 2738 | area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); |
2702 | if (area == NULL) { | 2739 | if (area == NULL) { |
2703 | ret = -ENOMEM; | 2740 | ret = -ENOMEM; |
@@ -2705,7 +2742,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2705 | goto err_get_vm_area_failed; | 2742 | goto err_get_vm_area_failed; |
2706 | } | 2743 | } |
2707 | proc->buffer = area->addr; | 2744 | proc->buffer = area->addr; |
2708 | proc->user_buffer_offset = vma->vm_start - (size_t)proc->buffer; | 2745 | proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; |
2709 | 2746 | ||
2710 | #ifdef CONFIG_CPU_CACHE_VIPT | 2747 | #ifdef CONFIG_CPU_CACHE_VIPT |
2711 | if (cache_is_vipt_aliasing()) { | 2748 | if (cache_is_vipt_aliasing()) { |
@@ -2738,6 +2775,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2738 | binder_insert_free_buffer(proc, buffer); | 2775 | binder_insert_free_buffer(proc, buffer); |
2739 | proc->free_async_space = proc->buffer_size / 2; | 2776 | proc->free_async_space = proc->buffer_size / 2; |
2740 | barrier(); | 2777 | barrier(); |
2778 | proc->files = get_files_struct(current); | ||
2741 | proc->vma = vma; | 2779 | proc->vma = vma; |
2742 | 2780 | ||
2743 | /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ | 2781 | /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ |
@@ -2745,10 +2783,12 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2745 | 2783 | ||
2746 | err_alloc_small_buf_failed: | 2784 | err_alloc_small_buf_failed: |
2747 | kfree(proc->pages); | 2785 | kfree(proc->pages); |
2786 | proc->pages = NULL; | ||
2748 | err_alloc_pages_failed: | 2787 | err_alloc_pages_failed: |
2749 | vfree(proc->buffer); | 2788 | vfree(proc->buffer); |
2789 | proc->buffer = NULL; | ||
2750 | err_get_vm_area_failed: | 2790 | err_get_vm_area_failed: |
2751 | mutex_unlock(&binder_lock); | 2791 | err_already_mapped: |
2752 | err_bad_arg: | 2792 | err_bad_arg: |
2753 | printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); | 2793 | printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); |
2754 | return ret; | 2794 | return ret; |
@@ -2780,6 +2820,7 @@ static int binder_open(struct inode *nodp, struct file *filp) | |||
2780 | if (binder_proc_dir_entry_proc) { | 2820 | if (binder_proc_dir_entry_proc) { |
2781 | char strbuf[11]; | 2821 | char strbuf[11]; |
2782 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); | 2822 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); |
2823 | remove_proc_entry(strbuf, binder_proc_dir_entry_proc); | ||
2783 | create_proc_read_entry(strbuf, S_IRUGO, binder_proc_dir_entry_proc, binder_read_proc_proc, proc); | 2824 | create_proc_read_entry(strbuf, S_IRUGO, binder_proc_dir_entry_proc, binder_read_proc_proc, proc); |
2784 | } | 2825 | } |
2785 | 2826 | ||
@@ -2788,11 +2829,17 @@ static int binder_open(struct inode *nodp, struct file *filp) | |||
2788 | 2829 | ||
2789 | static int binder_flush(struct file *filp, fl_owner_t id) | 2830 | static int binder_flush(struct file *filp, fl_owner_t id) |
2790 | { | 2831 | { |
2791 | struct rb_node *n; | ||
2792 | struct binder_proc *proc = filp->private_data; | 2832 | struct binder_proc *proc = filp->private_data; |
2793 | int wake_count = 0; | ||
2794 | 2833 | ||
2795 | mutex_lock(&binder_lock); | 2834 | binder_defer_work(proc, BINDER_DEFERRED_FLUSH); |
2835 | |||
2836 | return 0; | ||
2837 | } | ||
2838 | |||
2839 | static void binder_deferred_flush(struct binder_proc *proc) | ||
2840 | { | ||
2841 | struct rb_node *n; | ||
2842 | int wake_count = 0; | ||
2796 | for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { | 2843 | for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { |
2797 | struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); | 2844 | struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); |
2798 | thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; | 2845 | thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; |
@@ -2802,28 +2849,35 @@ static int binder_flush(struct file *filp, fl_owner_t id) | |||
2802 | } | 2849 | } |
2803 | } | 2850 | } |
2804 | wake_up_interruptible_all(&proc->wait); | 2851 | wake_up_interruptible_all(&proc->wait); |
2805 | mutex_unlock(&binder_lock); | ||
2806 | 2852 | ||
2807 | if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) | 2853 | if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) |
2808 | printk(KERN_INFO "binder_flush: %d woke %d threads\n", proc->pid, wake_count); | 2854 | printk(KERN_INFO "binder_flush: %d woke %d threads\n", proc->pid, wake_count); |
2809 | |||
2810 | return 0; | ||
2811 | } | 2855 | } |
2812 | 2856 | ||
2813 | static int binder_release(struct inode *nodp, struct file *filp) | 2857 | static int binder_release(struct inode *nodp, struct file *filp) |
2814 | { | 2858 | { |
2815 | struct hlist_node *pos; | ||
2816 | struct binder_transaction *t; | ||
2817 | struct rb_node *n; | ||
2818 | struct binder_proc *proc = filp->private_data; | 2859 | struct binder_proc *proc = filp->private_data; |
2819 | int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; | ||
2820 | |||
2821 | if (binder_proc_dir_entry_proc) { | 2860 | if (binder_proc_dir_entry_proc) { |
2822 | char strbuf[11]; | 2861 | char strbuf[11]; |
2823 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); | 2862 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); |
2824 | remove_proc_entry(strbuf, binder_proc_dir_entry_proc); | 2863 | remove_proc_entry(strbuf, binder_proc_dir_entry_proc); |
2825 | } | 2864 | } |
2826 | mutex_lock(&binder_lock); | 2865 | |
2866 | binder_defer_work(proc, BINDER_DEFERRED_RELEASE); | ||
2867 | |||
2868 | return 0; | ||
2869 | } | ||
2870 | |||
2871 | static void binder_deferred_release(struct binder_proc *proc) | ||
2872 | { | ||
2873 | struct hlist_node *pos; | ||
2874 | struct binder_transaction *t; | ||
2875 | struct rb_node *n; | ||
2876 | int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; | ||
2877 | |||
2878 | BUG_ON(proc->vma); | ||
2879 | BUG_ON(proc->files); | ||
2880 | |||
2827 | hlist_del(&proc->proc_node); | 2881 | hlist_del(&proc->proc_node); |
2828 | if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { | 2882 | if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { |
2829 | if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) | 2883 | if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) |
@@ -2897,7 +2951,6 @@ static int binder_release(struct inode *nodp, struct file *filp) | |||
2897 | } | 2951 | } |
2898 | 2952 | ||
2899 | binder_stats.obj_deleted[BINDER_STAT_PROC]++; | 2953 | binder_stats.obj_deleted[BINDER_STAT_PROC]++; |
2900 | mutex_unlock(&binder_lock); | ||
2901 | 2954 | ||
2902 | page_count = 0; | 2955 | page_count = 0; |
2903 | if (proc->pages) { | 2956 | if (proc->pages) { |
@@ -2921,7 +2974,57 @@ static int binder_release(struct inode *nodp, struct file *filp) | |||
2921 | proc->pid, threads, nodes, incoming_refs, outgoing_refs, active_transactions, buffers, page_count); | 2974 | proc->pid, threads, nodes, incoming_refs, outgoing_refs, active_transactions, buffers, page_count); |
2922 | 2975 | ||
2923 | kfree(proc); | 2976 | kfree(proc); |
2924 | return 0; | 2977 | } |
2978 | |||
2979 | static void binder_deferred_func(struct work_struct *work) | ||
2980 | { | ||
2981 | struct binder_proc *proc; | ||
2982 | struct files_struct *files; | ||
2983 | |||
2984 | int defer; | ||
2985 | do { | ||
2986 | mutex_lock(&binder_lock); | ||
2987 | mutex_lock(&binder_deferred_lock); | ||
2988 | if (!hlist_empty(&binder_deferred_list)) { | ||
2989 | proc = hlist_entry(binder_deferred_list.first, | ||
2990 | struct binder_proc, deferred_work_node); | ||
2991 | hlist_del_init(&proc->deferred_work_node); | ||
2992 | defer = proc->deferred_work; | ||
2993 | proc->deferred_work = 0; | ||
2994 | } else { | ||
2995 | proc = NULL; | ||
2996 | defer = 0; | ||
2997 | } | ||
2998 | mutex_unlock(&binder_deferred_lock); | ||
2999 | |||
3000 | files = NULL; | ||
3001 | if (defer & BINDER_DEFERRED_PUT_FILES) | ||
3002 | if ((files = proc->files)) | ||
3003 | proc->files = NULL; | ||
3004 | |||
3005 | if (defer & BINDER_DEFERRED_FLUSH) | ||
3006 | binder_deferred_flush(proc); | ||
3007 | |||
3008 | if (defer & BINDER_DEFERRED_RELEASE) | ||
3009 | binder_deferred_release(proc); /* frees proc */ | ||
3010 | |||
3011 | mutex_unlock(&binder_lock); | ||
3012 | if (files) | ||
3013 | put_files_struct(files); | ||
3014 | } while (proc); | ||
3015 | } | ||
3016 | static DECLARE_WORK(binder_deferred_work, binder_deferred_func); | ||
3017 | |||
3018 | static void binder_defer_work(struct binder_proc *proc, int defer) | ||
3019 | { | ||
3020 | mutex_lock(&binder_deferred_lock); | ||
3021 | proc->deferred_work |= defer; | ||
3022 | if (hlist_unhashed(&proc->deferred_work_node)) { | ||
3023 | hlist_add_head(&proc->deferred_work_node, | ||
3024 | &binder_deferred_list); | ||
3025 | schedule_work(&binder_deferred_work); | ||
3026 | } | ||
3027 | mutex_unlock(&binder_deferred_lock); | ||
2925 | } | 3028 | } |
2926 | 3029 | ||
2927 | static char *print_binder_transaction(char *buf, char *end, const char *prefix, struct binder_transaction *t) | 3030 | static char *print_binder_transaction(char *buf, char *end, const char *prefix, struct binder_transaction *t) |
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c index 6f6e36a3bd9f..c8af9a868d62 100644 --- a/drivers/staging/at76_usb/at76_usb.c +++ b/drivers/staging/at76_usb/at76_usb.c | |||
@@ -5259,6 +5259,18 @@ static int at76_alloc_urbs(struct at76_priv *priv, | |||
5259 | return 0; | 5259 | return 0; |
5260 | } | 5260 | } |
5261 | 5261 | ||
5262 | static const struct net_device_ops at76_netdev_ops = { | ||
5263 | .ndo_open = at76_open, | ||
5264 | .ndo_stop = at76_stop, | ||
5265 | .ndo_get_stats = at76_get_stats, | ||
5266 | .ndo_start_xmit = at76_tx, | ||
5267 | .ndo_tx_timeout = at76_tx_timeout, | ||
5268 | .ndo_set_multicast_list = at76_set_multicast, | ||
5269 | .ndo_set_mac_address = at76_set_mac_address, | ||
5270 | .ndo_validate_addr = eth_validate_addr, | ||
5271 | .ndo_change_mtu = eth_change_mtu, | ||
5272 | }; | ||
5273 | |||
5262 | /* Register network device and initialize the hardware */ | 5274 | /* Register network device and initialize the hardware */ |
5263 | static int at76_init_new_device(struct at76_priv *priv, | 5275 | static int at76_init_new_device(struct at76_priv *priv, |
5264 | struct usb_interface *interface) | 5276 | struct usb_interface *interface) |
@@ -5303,21 +5315,15 @@ static int at76_init_new_device(struct at76_priv *priv, | |||
5303 | priv->scan_mode = SCAN_TYPE_ACTIVE; | 5315 | priv->scan_mode = SCAN_TYPE_ACTIVE; |
5304 | 5316 | ||
5305 | netdev->flags &= ~IFF_MULTICAST; /* not yet or never */ | 5317 | netdev->flags &= ~IFF_MULTICAST; /* not yet or never */ |
5306 | netdev->open = at76_open; | 5318 | netdev->netdev_ops = &at76_netdev_ops; |
5307 | netdev->stop = at76_stop; | ||
5308 | netdev->get_stats = at76_get_stats; | ||
5309 | netdev->ethtool_ops = &at76_ethtool_ops; | 5319 | netdev->ethtool_ops = &at76_ethtool_ops; |
5310 | 5320 | ||
5311 | /* Add pointers to enable iwspy support. */ | 5321 | /* Add pointers to enable iwspy support. */ |
5312 | priv->wireless_data.spy_data = &priv->spy_data; | 5322 | priv->wireless_data.spy_data = &priv->spy_data; |
5313 | netdev->wireless_data = &priv->wireless_data; | 5323 | netdev->wireless_data = &priv->wireless_data; |
5314 | 5324 | ||
5315 | netdev->hard_start_xmit = at76_tx; | ||
5316 | netdev->tx_timeout = at76_tx_timeout; | ||
5317 | netdev->watchdog_timeo = 2 * HZ; | 5325 | netdev->watchdog_timeo = 2 * HZ; |
5318 | netdev->wireless_handlers = &at76_handler_def; | 5326 | netdev->wireless_handlers = &at76_handler_def; |
5319 | netdev->set_multicast_list = at76_set_multicast; | ||
5320 | netdev->set_mac_address = at76_set_mac_address; | ||
5321 | dev_alloc_name(netdev, "wlan%d"); | 5327 | dev_alloc_name(netdev, "wlan%d"); |
5322 | 5328 | ||
5323 | ret = register_netdev(priv->netdev); | 5329 | ret = register_netdev(priv->netdev); |
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c index 0348072b3ab5..75ebe338c6f2 100644 --- a/drivers/staging/b3dfg/b3dfg.c +++ b/drivers/staging/b3dfg/b3dfg.c | |||
@@ -1000,7 +1000,7 @@ static int __devinit b3dfg_probe(struct pci_dev *pdev, | |||
1000 | 1000 | ||
1001 | pci_set_master(pdev); | 1001 | pci_set_master(pdev); |
1002 | 1002 | ||
1003 | r = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 1003 | r = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
1004 | if (r) { | 1004 | if (r) { |
1005 | dev_err(&pdev->dev, "no usable DMA configuration\n"); | 1005 | dev_err(&pdev->dev, "no usable DMA configuration\n"); |
1006 | goto err_free_res; | 1006 | goto err_free_res; |
diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c index 21206c4d22ff..077724a556cc 100644 --- a/drivers/staging/epl/VirtualEthernetLinux.c +++ b/drivers/staging/epl/VirtualEthernetLinux.c | |||
@@ -284,6 +284,17 @@ static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p) | |||
284 | return Ret; | 284 | return Ret; |
285 | } | 285 | } |
286 | 286 | ||
287 | static const struct net_device_ops epl_netdev_ops = { | ||
288 | .ndo_open = VEthOpen, | ||
289 | .ndo_stop = VEthClose, | ||
290 | .ndo_get_stats = VEthGetStats, | ||
291 | .ndo_start_xmit = VEthXmit, | ||
292 | .ndo_tx_timeout = VEthTimeout, | ||
293 | .ndo_change_mtu = eth_change_mtu, | ||
294 | .ndo_set_mac_address = eth_mac_addr, | ||
295 | .ndo_validate_addr = eth_validate_addr, | ||
296 | }; | ||
297 | |||
287 | tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p) | 298 | tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p) |
288 | { | 299 | { |
289 | tEplKernel Ret = kEplSuccessful; | 300 | tEplKernel Ret = kEplSuccessful; |
@@ -299,11 +310,7 @@ tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p) | |||
299 | goto Exit; | 310 | goto Exit; |
300 | } | 311 | } |
301 | 312 | ||
302 | pVEthNetDevice_g->open = VEthOpen; | 313 | pVEthNetDevice_g->netdev_ops = &epl_netdev_ops; |
303 | pVEthNetDevice_g->stop = VEthClose; | ||
304 | pVEthNetDevice_g->get_stats = VEthGetStats; | ||
305 | pVEthNetDevice_g->hard_start_xmit = VEthXmit; | ||
306 | pVEthNetDevice_g->tx_timeout = VEthTimeout; | ||
307 | pVEthNetDevice_g->watchdog_timeo = EPL_VETH_TX_TIMEOUT; | 314 | pVEthNetDevice_g->watchdog_timeo = EPL_VETH_TX_TIMEOUT; |
308 | pVEthNetDevice_g->destructor = free_netdev; | 315 | pVEthNetDevice_g->destructor = free_netdev; |
309 | 316 | ||
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index de65972ff362..951c73d5db20 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c | |||
@@ -112,6 +112,19 @@ void et131x_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); | |||
112 | void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); | 112 | void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); |
113 | void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); | 113 | void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); |
114 | 114 | ||
115 | static const struct net_device_ops et131x_netdev_ops = { | ||
116 | .ndo_open = et131x_open, | ||
117 | .ndo_stop = et131x_close, | ||
118 | .ndo_start_xmit = et131x_tx, | ||
119 | .ndo_set_multicast_list = et131x_multicast, | ||
120 | .ndo_tx_timeout = et131x_tx_timeout, | ||
121 | .ndo_change_mtu = et131x_change_mtu, | ||
122 | .ndo_set_mac_address = et131x_set_mac_addr, | ||
123 | .ndo_validate_addr = eth_validate_addr, | ||
124 | .ndo_get_stats = et131x_stats, | ||
125 | .ndo_do_ioctl = et131x_ioctl, | ||
126 | }; | ||
127 | |||
115 | /** | 128 | /** |
116 | * et131x_device_alloc | 129 | * et131x_device_alloc |
117 | * | 130 | * |
@@ -142,16 +155,8 @@ struct net_device *et131x_device_alloc(void) | |||
142 | */ | 155 | */ |
143 | //netdev->init = &et131x_init; | 156 | //netdev->init = &et131x_init; |
144 | //netdev->set_config = &et131x_config; | 157 | //netdev->set_config = &et131x_config; |
145 | netdev->get_stats = &et131x_stats; | ||
146 | netdev->open = &et131x_open; | ||
147 | netdev->stop = &et131x_close; | ||
148 | netdev->do_ioctl = &et131x_ioctl; | ||
149 | netdev->set_multicast_list = &et131x_multicast; | ||
150 | netdev->hard_start_xmit = &et131x_tx; | ||
151 | netdev->tx_timeout = &et131x_tx_timeout; | ||
152 | netdev->watchdog_timeo = ET131X_TX_TIMEOUT; | 158 | netdev->watchdog_timeo = ET131X_TX_TIMEOUT; |
153 | netdev->change_mtu = &et131x_change_mtu; | 159 | netdev->netdev_ops = &et131x_netdev_ops; |
154 | netdev->set_mac_address = &et131x_set_mac_addr; | ||
155 | 160 | ||
156 | //netdev->ethtool_ops = &et131x_ethtool_ops; | 161 | //netdev->ethtool_ops = &et131x_ethtool_ops; |
157 | 162 | ||
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index 58bfc8d81b3b..77b1e769ac92 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c | |||
@@ -191,8 +191,10 @@ int go7007_reset_encoder(struct go7007 *go) | |||
191 | /* | 191 | /* |
192 | * Attempt to instantiate an I2C client by ID, probably loading a module. | 192 | * Attempt to instantiate an I2C client by ID, probably loading a module. |
193 | */ | 193 | */ |
194 | static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr) | 194 | static int init_i2c_module(struct i2c_adapter *adapter, const char *type, |
195 | int id, int addr) | ||
195 | { | 196 | { |
197 | struct i2c_board_info info; | ||
196 | char *modname; | 198 | char *modname; |
197 | 199 | ||
198 | switch (id) { | 200 | switch (id) { |
@@ -226,7 +228,11 @@ static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr) | |||
226 | } | 228 | } |
227 | if (modname != NULL) | 229 | if (modname != NULL) |
228 | request_module(modname); | 230 | request_module(modname); |
229 | if (wis_i2c_probe_device(adapter, id, addr) == 1) | 231 | |
232 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
233 | info.addr = addr; | ||
234 | strlcpy(info.type, type, I2C_NAME_SIZE); | ||
235 | if (!i2c_new_device(adapter, &info)) | ||
230 | return 0; | 236 | return 0; |
231 | if (modname != NULL) | 237 | if (modname != NULL) |
232 | printk(KERN_INFO | 238 | printk(KERN_INFO |
@@ -266,23 +272,9 @@ int go7007_register_encoder(struct go7007 *go) | |||
266 | if (go->i2c_adapter_online) { | 272 | if (go->i2c_adapter_online) { |
267 | for (i = 0; i < go->board_info->num_i2c_devs; ++i) | 273 | for (i = 0; i < go->board_info->num_i2c_devs; ++i) |
268 | init_i2c_module(&go->i2c_adapter, | 274 | init_i2c_module(&go->i2c_adapter, |
275 | go->board_info->i2c_devs[i].type, | ||
269 | go->board_info->i2c_devs[i].id, | 276 | go->board_info->i2c_devs[i].id, |
270 | go->board_info->i2c_devs[i].addr); | 277 | go->board_info->i2c_devs[i].addr); |
271 | #ifdef TUNER_SET_TYPE_ADDR | ||
272 | if (go->tuner_type >= 0) { | ||
273 | struct tuner_setup tun_setup = { | ||
274 | .mode_mask = T_ANALOG_TV, | ||
275 | .addr = ADDR_UNSET, | ||
276 | .type = go->tuner_type | ||
277 | }; | ||
278 | i2c_clients_command(&go->i2c_adapter, | ||
279 | TUNER_SET_TYPE_ADDR, &tun_setup); | ||
280 | } | ||
281 | #else | ||
282 | if (go->tuner_type >= 0) | ||
283 | i2c_clients_command(&go->i2c_adapter, | ||
284 | TUNER_SET_TYPE, &go->tuner_type); | ||
285 | #endif | ||
286 | if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) | 278 | if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) |
287 | i2c_clients_command(&go->i2c_adapter, | 279 | i2c_clients_command(&go->i2c_adapter, |
288 | DECODER_SET_CHANNEL, &go->channel_number); | 280 | DECODER_SET_CHANNEL, &go->channel_number); |
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c index cd55b76eabc7..c82867fdd28d 100644 --- a/drivers/staging/go7007/go7007-i2c.c +++ b/drivers/staging/go7007/go7007-i2c.c | |||
@@ -31,87 +31,6 @@ | |||
31 | #include "go7007-priv.h" | 31 | #include "go7007-priv.h" |
32 | #include "wis-i2c.h" | 32 | #include "wis-i2c.h" |
33 | 33 | ||
34 | /************** Registration interface for I2C client drivers **************/ | ||
35 | |||
36 | /* Since there's no way to auto-probe the I2C devices connected to the I2C | ||
37 | * bus on the go7007, we have this silly little registration system that | ||
38 | * client drivers can use to register their I2C driver ID and their | ||
39 | * detect_client function (the one that's normally passed to i2c_probe). | ||
40 | * | ||
41 | * When a new go7007 device is connected, we can look up in a board info | ||
42 | * table by the USB or PCI vendor/product/revision ID to determine | ||
43 | * which I2C client module to load. The client driver module will register | ||
44 | * itself here, and then we can call the registered detect_client function | ||
45 | * to force-load a new client at the address listed in the board info table. | ||
46 | * | ||
47 | * Really the I2C subsystem should have a way to force-load I2C client | ||
48 | * drivers when we have a priori knowledge of what's on the bus, especially | ||
49 | * since the existing I2C auto-probe mechanism is so hokey, but we'll use | ||
50 | * our own mechanism for the time being. */ | ||
51 | |||
52 | struct wis_i2c_client_driver { | ||
53 | unsigned int id; | ||
54 | found_proc found_proc; | ||
55 | struct list_head list; | ||
56 | }; | ||
57 | |||
58 | static LIST_HEAD(i2c_client_drivers); | ||
59 | static DECLARE_MUTEX(i2c_client_driver_list_lock); | ||
60 | |||
61 | /* Client drivers register here by their I2C driver ID */ | ||
62 | int wis_i2c_add_driver(unsigned int id, found_proc found_proc) | ||
63 | { | ||
64 | struct wis_i2c_client_driver *driver; | ||
65 | |||
66 | driver = kmalloc(sizeof(struct wis_i2c_client_driver), GFP_KERNEL); | ||
67 | if (driver == NULL) | ||
68 | return -ENOMEM; | ||
69 | driver->id = id; | ||
70 | driver->found_proc = found_proc; | ||
71 | |||
72 | down(&i2c_client_driver_list_lock); | ||
73 | list_add_tail(&driver->list, &i2c_client_drivers); | ||
74 | up(&i2c_client_driver_list_lock); | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | EXPORT_SYMBOL(wis_i2c_add_driver); | ||
79 | |||
80 | void wis_i2c_del_driver(found_proc found_proc) | ||
81 | { | ||
82 | struct wis_i2c_client_driver *driver, *next; | ||
83 | |||
84 | down(&i2c_client_driver_list_lock); | ||
85 | list_for_each_entry_safe(driver, next, &i2c_client_drivers, list) | ||
86 | if (driver->found_proc == found_proc) { | ||
87 | list_del(&driver->list); | ||
88 | kfree(driver); | ||
89 | } | ||
90 | up(&i2c_client_driver_list_lock); | ||
91 | } | ||
92 | EXPORT_SYMBOL(wis_i2c_del_driver); | ||
93 | |||
94 | /* The main go7007 driver calls this to instantiate a client by driver | ||
95 | * ID and bus address, which are both stored in the board info table */ | ||
96 | int wis_i2c_probe_device(struct i2c_adapter *adapter, | ||
97 | unsigned int id, int addr) | ||
98 | { | ||
99 | struct wis_i2c_client_driver *driver; | ||
100 | int found = 0; | ||
101 | |||
102 | if (addr < 0 || addr > 0x7f) | ||
103 | return -1; | ||
104 | down(&i2c_client_driver_list_lock); | ||
105 | list_for_each_entry(driver, &i2c_client_drivers, list) | ||
106 | if (driver->id == id) { | ||
107 | if (driver->found_proc(adapter, addr, 0) == 0) | ||
108 | found = 1; | ||
109 | break; | ||
110 | } | ||
111 | up(&i2c_client_driver_list_lock); | ||
112 | return found; | ||
113 | } | ||
114 | |||
115 | /********************* Driver for on-board I2C adapter *********************/ | 34 | /********************* Driver for on-board I2C adapter *********************/ |
116 | 35 | ||
117 | /* #define GO7007_I2C_DEBUG */ | 36 | /* #define GO7007_I2C_DEBUG */ |
@@ -287,9 +206,7 @@ static struct i2c_algorithm go7007_algo = { | |||
287 | 206 | ||
288 | static struct i2c_adapter go7007_adap_templ = { | 207 | static struct i2c_adapter go7007_adap_templ = { |
289 | .owner = THIS_MODULE, | 208 | .owner = THIS_MODULE, |
290 | .class = I2C_CLASS_TV_ANALOG, | ||
291 | .name = "WIS GO7007SB", | 209 | .name = "WIS GO7007SB", |
292 | .id = I2C_ALGO_GO7007, | ||
293 | .algo = &go7007_algo, | 210 | .algo = &go7007_algo, |
294 | }; | 211 | }; |
295 | 212 | ||
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h index 372f1f1c09b2..178d18119faa 100644 --- a/drivers/staging/go7007/go7007-priv.h +++ b/drivers/staging/go7007/go7007-priv.h | |||
@@ -87,6 +87,7 @@ struct go7007_board_info { | |||
87 | int audio_main_div; | 87 | int audio_main_div; |
88 | int num_i2c_devs; | 88 | int num_i2c_devs; |
89 | struct { | 89 | struct { |
90 | const char *type; | ||
90 | int id; | 91 | int id; |
91 | int addr; | 92 | int addr; |
92 | } i2c_devs[4]; | 93 | } i2c_devs[4]; |
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c index 83eec920c7d3..aa4a9e0b9954 100644 --- a/drivers/staging/go7007/go7007-usb.c +++ b/drivers/staging/go7007/go7007-usb.c | |||
@@ -91,6 +91,7 @@ static struct go7007_usb_board board_matrix_ii = { | |||
91 | .num_i2c_devs = 1, | 91 | .num_i2c_devs = 1, |
92 | .i2c_devs = { | 92 | .i2c_devs = { |
93 | { | 93 | { |
94 | .type = "wis_saa7115", | ||
94 | .id = I2C_DRIVERID_WIS_SAA7115, | 95 | .id = I2C_DRIVERID_WIS_SAA7115, |
95 | .addr = 0x20, | 96 | .addr = 0x20, |
96 | }, | 97 | }, |
@@ -127,6 +128,7 @@ static struct go7007_usb_board board_matrix_reload = { | |||
127 | .num_i2c_devs = 1, | 128 | .num_i2c_devs = 1, |
128 | .i2c_devs = { | 129 | .i2c_devs = { |
129 | { | 130 | { |
131 | .type = "wis_saa7113", | ||
130 | .id = I2C_DRIVERID_WIS_SAA7113, | 132 | .id = I2C_DRIVERID_WIS_SAA7113, |
131 | .addr = 0x25, | 133 | .addr = 0x25, |
132 | }, | 134 | }, |
@@ -164,6 +166,7 @@ static struct go7007_usb_board board_star_trek = { | |||
164 | .num_i2c_devs = 1, | 166 | .num_i2c_devs = 1, |
165 | .i2c_devs = { | 167 | .i2c_devs = { |
166 | { | 168 | { |
169 | .type = "wis_saa7115", | ||
167 | .id = I2C_DRIVERID_WIS_SAA7115, | 170 | .id = I2C_DRIVERID_WIS_SAA7115, |
168 | .addr = 0x20, | 171 | .addr = 0x20, |
169 | }, | 172 | }, |
@@ -209,14 +212,17 @@ static struct go7007_usb_board board_px_tv402u = { | |||
209 | .num_i2c_devs = 3, | 212 | .num_i2c_devs = 3, |
210 | .i2c_devs = { | 213 | .i2c_devs = { |
211 | { | 214 | { |
215 | .type = "wis_saa7115", | ||
212 | .id = I2C_DRIVERID_WIS_SAA7115, | 216 | .id = I2C_DRIVERID_WIS_SAA7115, |
213 | .addr = 0x20, | 217 | .addr = 0x20, |
214 | }, | 218 | }, |
215 | { | 219 | { |
220 | .type = "wis_uda1342", | ||
216 | .id = I2C_DRIVERID_WIS_UDA1342, | 221 | .id = I2C_DRIVERID_WIS_UDA1342, |
217 | .addr = 0x1a, | 222 | .addr = 0x1a, |
218 | }, | 223 | }, |
219 | { | 224 | { |
225 | .type = "wis_sony_tuner", | ||
220 | .id = I2C_DRIVERID_WIS_SONY_TUNER, | 226 | .id = I2C_DRIVERID_WIS_SONY_TUNER, |
221 | .addr = 0x60, | 227 | .addr = 0x60, |
222 | }, | 228 | }, |
@@ -264,6 +270,7 @@ static struct go7007_usb_board board_xmen = { | |||
264 | .num_i2c_devs = 1, | 270 | .num_i2c_devs = 1, |
265 | .i2c_devs = { | 271 | .i2c_devs = { |
266 | { | 272 | { |
273 | .type = "wis_ov7640", | ||
267 | .id = I2C_DRIVERID_WIS_OV7640, | 274 | .id = I2C_DRIVERID_WIS_OV7640, |
268 | .addr = 0x21, | 275 | .addr = 0x21, |
269 | }, | 276 | }, |
@@ -296,6 +303,7 @@ static struct go7007_usb_board board_matrix_revolution = { | |||
296 | .num_i2c_devs = 1, | 303 | .num_i2c_devs = 1, |
297 | .i2c_devs = { | 304 | .i2c_devs = { |
298 | { | 305 | { |
306 | .type = "wis_tw9903", | ||
299 | .id = I2C_DRIVERID_WIS_TW9903, | 307 | .id = I2C_DRIVERID_WIS_TW9903, |
300 | .addr = 0x44, | 308 | .addr = 0x44, |
301 | }, | 309 | }, |
@@ -385,6 +393,7 @@ static struct go7007_usb_board board_adlink_mpg24 = { | |||
385 | .num_i2c_devs = 1, | 393 | .num_i2c_devs = 1, |
386 | .i2c_devs = { | 394 | .i2c_devs = { |
387 | { | 395 | { |
396 | .type = "wis_twTW2804", | ||
388 | .id = I2C_DRIVERID_WIS_TW2804, | 397 | .id = I2C_DRIVERID_WIS_TW2804, |
389 | .addr = 0x00, /* yes, really */ | 398 | .addr = 0x00, /* yes, really */ |
390 | }, | 399 | }, |
@@ -415,8 +424,9 @@ static struct go7007_usb_board board_sensoray_2250 = { | |||
415 | .num_i2c_devs = 1, | 424 | .num_i2c_devs = 1, |
416 | .i2c_devs = { | 425 | .i2c_devs = { |
417 | { | 426 | { |
427 | .type = "s2250_board", | ||
418 | .id = I2C_DRIVERID_S2250, | 428 | .id = I2C_DRIVERID_S2250, |
419 | .addr = 0x34, | 429 | .addr = 0x43, |
420 | }, | 430 | }, |
421 | }, | 431 | }, |
422 | .num_inputs = 2, | 432 | .num_inputs = 2, |
@@ -943,9 +953,7 @@ static struct i2c_algorithm go7007_usb_algo = { | |||
943 | 953 | ||
944 | static struct i2c_adapter go7007_usb_adap_templ = { | 954 | static struct i2c_adapter go7007_usb_adap_templ = { |
945 | .owner = THIS_MODULE, | 955 | .owner = THIS_MODULE, |
946 | .class = I2C_CLASS_TV_ANALOG, | ||
947 | .name = "WIS GO7007SB EZ-USB", | 956 | .name = "WIS GO7007SB EZ-USB", |
948 | .id = I2C_ALGO_GO7007_USB, | ||
949 | .algo = &go7007_usb_algo, | 957 | .algo = &go7007_usb_algo, |
950 | }; | 958 | }; |
951 | 959 | ||
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c index d333ea2cd774..1706fbf06847 100644 --- a/drivers/staging/go7007/s2250-board.c +++ b/drivers/staging/go7007/s2250-board.c | |||
@@ -28,7 +28,6 @@ extern int s2250loader_init(void); | |||
28 | extern void s2250loader_cleanup(void); | 28 | extern void s2250loader_cleanup(void); |
29 | 29 | ||
30 | #define TLV320_ADDRESS 0x34 | 30 | #define TLV320_ADDRESS 0x34 |
31 | #define S2250_VIDDEC 0x86 | ||
32 | #define VPX322_ADDR_ANALOGCONTROL1 0x02 | 31 | #define VPX322_ADDR_ANALOGCONTROL1 0x02 |
33 | #define VPX322_ADDR_BRIGHTNESS0 0x0127 | 32 | #define VPX322_ADDR_BRIGHTNESS0 0x0127 |
34 | #define VPX322_ADDR_BRIGHTNESS1 0x0131 | 33 | #define VPX322_ADDR_BRIGHTNESS1 0x0131 |
@@ -123,6 +122,7 @@ struct s2250 { | |||
123 | int hue; | 122 | int hue; |
124 | int reg12b_val; | 123 | int reg12b_val; |
125 | int audio_input; | 124 | int audio_input; |
125 | struct i2c_client *audio; | ||
126 | }; | 126 | }; |
127 | 127 | ||
128 | /* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/ | 128 | /* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/ |
@@ -452,16 +452,15 @@ static int s2250_command(struct i2c_client *client, | |||
452 | { | 452 | { |
453 | struct v4l2_audio *audio = arg; | 453 | struct v4l2_audio *audio = arg; |
454 | 454 | ||
455 | client->addr = TLV320_ADDRESS; | ||
456 | switch (audio->index) { | 455 | switch (audio->index) { |
457 | case 0: | 456 | case 0: |
458 | write_reg(client, 0x08, 0x02); /* Line In */ | 457 | write_reg(dec->audio, 0x08, 0x02); /* Line In */ |
459 | break; | 458 | break; |
460 | case 1: | 459 | case 1: |
461 | write_reg(client, 0x08, 0x04); /* Mic */ | 460 | write_reg(dec->audio, 0x08, 0x04); /* Mic */ |
462 | break; | 461 | break; |
463 | case 2: | 462 | case 2: |
464 | write_reg(client, 0x08, 0x05); /* Mic Boost */ | 463 | write_reg(dec->audio, 0x08, 0x05); /* Mic Boost */ |
465 | break; | 464 | break; |
466 | default: | 465 | default: |
467 | return -EINVAL; | 466 | return -EINVAL; |
@@ -477,31 +476,23 @@ static int s2250_command(struct i2c_client *client, | |||
477 | return 0; | 476 | return 0; |
478 | } | 477 | } |
479 | 478 | ||
480 | static struct i2c_driver s2250_driver; | 479 | static int s2250_probe(struct i2c_client *client, |
481 | 480 | const struct i2c_device_id *id) | |
482 | static struct i2c_client s2250_client_templ = { | ||
483 | .name = "Sensoray 2250", | ||
484 | .driver = &s2250_driver, | ||
485 | }; | ||
486 | |||
487 | static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind) | ||
488 | { | 481 | { |
489 | struct i2c_client *client; | 482 | struct i2c_client *audio; |
483 | struct i2c_adapter *adapter = client->adapter; | ||
490 | struct s2250 *dec; | 484 | struct s2250 *dec; |
491 | u8 *data; | 485 | u8 *data; |
492 | struct go7007 *go = i2c_get_adapdata(adapter); | 486 | struct go7007 *go = i2c_get_adapdata(adapter); |
493 | struct go7007_usb *usb = go->hpi_context; | 487 | struct go7007_usb *usb = go->hpi_context; |
494 | 488 | ||
495 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | 489 | audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1); |
496 | if (client == NULL) | 490 | if (audio == NULL) |
497 | return -ENOMEM; | 491 | return -ENOMEM; |
498 | memcpy(client, &s2250_client_templ, | ||
499 | sizeof(s2250_client_templ)); | ||
500 | client->adapter = adapter; | ||
501 | 492 | ||
502 | dec = kmalloc(sizeof(struct s2250), GFP_KERNEL); | 493 | dec = kmalloc(sizeof(struct s2250), GFP_KERNEL); |
503 | if (dec == NULL) { | 494 | if (dec == NULL) { |
504 | kfree(client); | 495 | i2c_unregister_device(audio); |
505 | return -ENOMEM; | 496 | return -ENOMEM; |
506 | } | 497 | } |
507 | 498 | ||
@@ -510,7 +501,7 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind) | |||
510 | dec->contrast = 50; | 501 | dec->contrast = 50; |
511 | dec->saturation = 50; | 502 | dec->saturation = 50; |
512 | dec->hue = 0; | 503 | dec->hue = 0; |
513 | client->addr = TLV320_ADDRESS; | 504 | dec->audio = audio; |
514 | i2c_set_clientdata(client, dec); | 505 | i2c_set_clientdata(client, dec); |
515 | 506 | ||
516 | printk(KERN_DEBUG | 507 | printk(KERN_DEBUG |
@@ -518,28 +509,25 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind) | |||
518 | adapter->name); | 509 | adapter->name); |
519 | 510 | ||
520 | /* initialize the audio */ | 511 | /* initialize the audio */ |
521 | client->addr = TLV320_ADDRESS; | 512 | if (write_regs(audio, aud_regs) < 0) { |
522 | if (write_regs(client, aud_regs) < 0) { | ||
523 | printk(KERN_ERR | 513 | printk(KERN_ERR |
524 | "s2250: error initializing audio\n"); | 514 | "s2250: error initializing audio\n"); |
525 | kfree(client); | 515 | i2c_unregister_device(audio); |
526 | kfree(dec); | 516 | kfree(dec); |
527 | return 0; | 517 | return 0; |
528 | } | 518 | } |
529 | client->addr = S2250_VIDDEC; | ||
530 | i2c_set_clientdata(client, dec); | ||
531 | 519 | ||
532 | if (write_regs(client, vid_regs) < 0) { | 520 | if (write_regs(client, vid_regs) < 0) { |
533 | printk(KERN_ERR | 521 | printk(KERN_ERR |
534 | "s2250: error initializing decoder\n"); | 522 | "s2250: error initializing decoder\n"); |
535 | kfree(client); | 523 | i2c_unregister_device(audio); |
536 | kfree(dec); | 524 | kfree(dec); |
537 | return 0; | 525 | return 0; |
538 | } | 526 | } |
539 | if (write_regs_fp(client, vid_regs_fp) < 0) { | 527 | if (write_regs_fp(client, vid_regs_fp) < 0) { |
540 | printk(KERN_ERR | 528 | printk(KERN_ERR |
541 | "s2250: error initializing decoder\n"); | 529 | "s2250: error initializing decoder\n"); |
542 | kfree(client); | 530 | i2c_unregister_device(audio); |
543 | kfree(dec); | 531 | kfree(dec); |
544 | return 0; | 532 | return 0; |
545 | } | 533 | } |
@@ -575,32 +563,33 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind) | |||
575 | up(&usb->i2c_lock); | 563 | up(&usb->i2c_lock); |
576 | } | 564 | } |
577 | 565 | ||
578 | i2c_attach_client(client); | ||
579 | printk("s2250: initialized successfully\n"); | 566 | printk("s2250: initialized successfully\n"); |
580 | return 0; | 567 | return 0; |
581 | } | 568 | } |
582 | 569 | ||
583 | static int s2250_detach(struct i2c_client *client) | 570 | static int s2250_remove(struct i2c_client *client) |
584 | { | 571 | { |
585 | struct s2250 *dec = i2c_get_clientdata(client); | 572 | struct s2250 *dec = i2c_get_clientdata(client); |
586 | int r; | ||
587 | |||
588 | r = i2c_detach_client(client); | ||
589 | if (r < 0) | ||
590 | return r; | ||
591 | 573 | ||
592 | kfree(client); | 574 | i2c_set_clientdata(client, NULL); |
575 | i2c_unregister_device(dec->audio); | ||
593 | kfree(dec); | 576 | kfree(dec); |
594 | return 0; | 577 | return 0; |
595 | } | 578 | } |
596 | 579 | ||
580 | static struct i2c_device_id s2250_id[] = { | ||
581 | { "s2250_board", 0 }, | ||
582 | { } | ||
583 | }; | ||
584 | |||
597 | static struct i2c_driver s2250_driver = { | 585 | static struct i2c_driver s2250_driver = { |
598 | .driver = { | 586 | .driver = { |
599 | .name = "Sensoray 2250 board driver", | 587 | .name = "Sensoray 2250 board driver", |
600 | }, | 588 | }, |
601 | .id = I2C_DRIVERID_S2250, | 589 | .probe = s2250_probe, |
602 | .detach_client = s2250_detach, | 590 | .remove = s2250_remove, |
603 | .command = s2250_command, | 591 | .command = s2250_command, |
592 | .id_table = s2250_id, | ||
604 | }; | 593 | }; |
605 | 594 | ||
606 | static int __init s2250_init(void) | 595 | static int __init s2250_init(void) |
@@ -613,13 +602,13 @@ static int __init s2250_init(void) | |||
613 | 602 | ||
614 | r = i2c_add_driver(&s2250_driver); | 603 | r = i2c_add_driver(&s2250_driver); |
615 | if (r < 0) | 604 | if (r < 0) |
616 | return r; | 605 | s2250loader_cleanup(); |
617 | return wis_i2c_add_driver(s2250_driver.id, s2250_detect); | 606 | |
607 | return r; | ||
618 | } | 608 | } |
619 | 609 | ||
620 | static void __exit s2250_cleanup(void) | 610 | static void __exit s2250_cleanup(void) |
621 | { | 611 | { |
622 | wis_i2c_del_driver(s2250_detect); | ||
623 | i2c_del_driver(&s2250_driver); | 612 | i2c_del_driver(&s2250_driver); |
624 | 613 | ||
625 | s2250loader_cleanup(); | 614 | s2250loader_cleanup(); |
diff --git a/drivers/staging/go7007/wis-i2c.h b/drivers/staging/go7007/wis-i2c.h index 431f41dd3966..3c2b9be455df 100644 --- a/drivers/staging/go7007/wis-i2c.h +++ b/drivers/staging/go7007/wis-i2c.h | |||
@@ -24,21 +24,12 @@ | |||
24 | #define I2C_DRIVERID_WIS_OV7640 0xf0f5 | 24 | #define I2C_DRIVERID_WIS_OV7640 0xf0f5 |
25 | #define I2C_DRIVERID_WIS_TW2804 0xf0f6 | 25 | #define I2C_DRIVERID_WIS_TW2804 0xf0f6 |
26 | #define I2C_DRIVERID_S2250 0xf0f7 | 26 | #define I2C_DRIVERID_S2250 0xf0f7 |
27 | #define I2C_ALGO_GO7007 0xf00000 | ||
28 | #define I2C_ALGO_GO7007_USB 0xf10000 | ||
29 | 27 | ||
30 | /* Flag to indicate that the client needs to be accessed with SCCB semantics */ | 28 | /* Flag to indicate that the client needs to be accessed with SCCB semantics */ |
31 | /* We re-use the I2C_M_TEN value so the flag passes through the masks in the | 29 | /* We re-use the I2C_M_TEN value so the flag passes through the masks in the |
32 | * core I2C code. Major kludge, but the I2C layer ain't exactly flexible. */ | 30 | * core I2C code. Major kludge, but the I2C layer ain't exactly flexible. */ |
33 | #define I2C_CLIENT_SCCB 0x10 | 31 | #define I2C_CLIENT_SCCB 0x10 |
34 | 32 | ||
35 | typedef int (*found_proc) (struct i2c_adapter *, int, int); | ||
36 | int wis_i2c_add_driver(unsigned int id, found_proc found_proc); | ||
37 | void wis_i2c_del_driver(found_proc found_proc); | ||
38 | |||
39 | int wis_i2c_probe_device(struct i2c_adapter *adapter, | ||
40 | unsigned int id, int addr); | ||
41 | |||
42 | /* Definitions for new video decoder commands */ | 33 | /* Definitions for new video decoder commands */ |
43 | 34 | ||
44 | struct video_decoder_resolution { | 35 | struct video_decoder_resolution { |
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c index 2f9efca04606..04d6d3a498a3 100644 --- a/drivers/staging/go7007/wis-ov7640.c +++ b/drivers/staging/go7007/wis-ov7640.c | |||
@@ -50,76 +50,54 @@ static int write_regs(struct i2c_client *client, u8 *regs) | |||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | static struct i2c_driver wis_ov7640_driver; | 53 | static int wis_ov7640_probe(struct i2c_client *client, |
54 | 54 | const struct i2c_device_id *id) | |
55 | static struct i2c_client wis_ov7640_client_templ = { | ||
56 | .name = "OV7640 (WIS)", | ||
57 | .driver = &wis_ov7640_driver, | ||
58 | }; | ||
59 | |||
60 | static int wis_ov7640_detect(struct i2c_adapter *adapter, int addr, int kind) | ||
61 | { | 55 | { |
62 | struct i2c_client *client; | 56 | struct i2c_adapter *adapter = client->adapter; |
63 | 57 | ||
64 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 58 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
65 | return 0; | 59 | return -ENODEV; |
66 | 60 | ||
67 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
68 | if (client == NULL) | ||
69 | return -ENOMEM; | ||
70 | memcpy(client, &wis_ov7640_client_templ, | ||
71 | sizeof(wis_ov7640_client_templ)); | ||
72 | client->adapter = adapter; | ||
73 | client->addr = addr; | ||
74 | client->flags = I2C_CLIENT_SCCB; | 61 | client->flags = I2C_CLIENT_SCCB; |
75 | 62 | ||
76 | printk(KERN_DEBUG | 63 | printk(KERN_DEBUG |
77 | "wis-ov7640: initializing OV7640 at address %d on %s\n", | 64 | "wis-ov7640: initializing OV7640 at address %d on %s\n", |
78 | addr, adapter->name); | 65 | client->addr, adapter->name); |
79 | 66 | ||
80 | if (write_regs(client, initial_registers) < 0) { | 67 | if (write_regs(client, initial_registers) < 0) { |
81 | printk(KERN_ERR "wis-ov7640: error initializing OV7640\n"); | 68 | printk(KERN_ERR "wis-ov7640: error initializing OV7640\n"); |
82 | kfree(client); | 69 | return -ENODEV; |
83 | return 0; | ||
84 | } | 70 | } |
85 | 71 | ||
86 | i2c_attach_client(client); | ||
87 | return 0; | 72 | return 0; |
88 | } | 73 | } |
89 | 74 | ||
90 | static int wis_ov7640_detach(struct i2c_client *client) | 75 | static int wis_ov7640_remove(struct i2c_client *client) |
91 | { | 76 | { |
92 | int r; | ||
93 | |||
94 | r = i2c_detach_client(client); | ||
95 | if (r < 0) | ||
96 | return r; | ||
97 | |||
98 | kfree(client); | ||
99 | return 0; | 77 | return 0; |
100 | } | 78 | } |
101 | 79 | ||
80 | static struct i2c_device_id wis_ov7640_id[] = { | ||
81 | { "wis_ov7640", 0 }, | ||
82 | { } | ||
83 | }; | ||
84 | |||
102 | static struct i2c_driver wis_ov7640_driver = { | 85 | static struct i2c_driver wis_ov7640_driver = { |
103 | .driver = { | 86 | .driver = { |
104 | .name = "WIS OV7640 I2C driver", | 87 | .name = "WIS OV7640 I2C driver", |
105 | }, | 88 | }, |
106 | .id = I2C_DRIVERID_WIS_OV7640, | 89 | .probe = wis_ov7640_probe, |
107 | .detach_client = wis_ov7640_detach, | 90 | .remove = wis_ov7640_remove, |
91 | .id_table = wis_ov7640_id, | ||
108 | }; | 92 | }; |
109 | 93 | ||
110 | static int __init wis_ov7640_init(void) | 94 | static int __init wis_ov7640_init(void) |
111 | { | 95 | { |
112 | int r; | 96 | return i2c_add_driver(&wis_ov7640_driver); |
113 | |||
114 | r = i2c_add_driver(&wis_ov7640_driver); | ||
115 | if (r < 0) | ||
116 | return r; | ||
117 | return wis_i2c_add_driver(wis_ov7640_driver.id, wis_ov7640_detect); | ||
118 | } | 97 | } |
119 | 98 | ||
120 | static void __exit wis_ov7640_cleanup(void) | 99 | static void __exit wis_ov7640_cleanup(void) |
121 | { | 100 | { |
122 | wis_i2c_del_driver(wis_ov7640_detect); | ||
123 | i2c_del_driver(&wis_ov7640_driver); | 101 | i2c_del_driver(&wis_ov7640_driver); |
124 | } | 102 | } |
125 | 103 | ||
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c index 11689723945e..9ab893bd204e 100644 --- a/drivers/staging/go7007/wis-saa7113.c +++ b/drivers/staging/go7007/wis-saa7113.c | |||
@@ -261,34 +261,19 @@ static int wis_saa7113_command(struct i2c_client *client, | |||
261 | return 0; | 261 | return 0; |
262 | } | 262 | } |
263 | 263 | ||
264 | static struct i2c_driver wis_saa7113_driver; | 264 | static int wis_saa7113_probe(struct i2c_client *client, |
265 | 265 | const struct i2c_device_id *id) | |
266 | static struct i2c_client wis_saa7113_client_templ = { | ||
267 | .name = "SAA7113 (WIS)", | ||
268 | .driver = &wis_saa7113_driver, | ||
269 | }; | ||
270 | |||
271 | static int wis_saa7113_detect(struct i2c_adapter *adapter, int addr, int kind) | ||
272 | { | 266 | { |
273 | struct i2c_client *client; | 267 | struct i2c_adapter *adapter = client->adapter; |
274 | struct wis_saa7113 *dec; | 268 | struct wis_saa7113 *dec; |
275 | 269 | ||
276 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 270 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
277 | return 0; | 271 | return -ENODEV; |
278 | |||
279 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
280 | if (client == NULL) | ||
281 | return -ENOMEM; | ||
282 | memcpy(client, &wis_saa7113_client_templ, | ||
283 | sizeof(wis_saa7113_client_templ)); | ||
284 | client->adapter = adapter; | ||
285 | client->addr = addr; | ||
286 | 272 | ||
287 | dec = kmalloc(sizeof(struct wis_saa7113), GFP_KERNEL); | 273 | dec = kmalloc(sizeof(struct wis_saa7113), GFP_KERNEL); |
288 | if (dec == NULL) { | 274 | if (dec == NULL) |
289 | kfree(client); | ||
290 | return -ENOMEM; | 275 | return -ENOMEM; |
291 | } | 276 | |
292 | dec->norm = V4L2_STD_NTSC; | 277 | dec->norm = V4L2_STD_NTSC; |
293 | dec->brightness = 128; | 278 | dec->brightness = 128; |
294 | dec->contrast = 71; | 279 | dec->contrast = 71; |
@@ -298,56 +283,49 @@ static int wis_saa7113_detect(struct i2c_adapter *adapter, int addr, int kind) | |||
298 | 283 | ||
299 | printk(KERN_DEBUG | 284 | printk(KERN_DEBUG |
300 | "wis-saa7113: initializing SAA7113 at address %d on %s\n", | 285 | "wis-saa7113: initializing SAA7113 at address %d on %s\n", |
301 | addr, adapter->name); | 286 | client->addr, adapter->name); |
302 | 287 | ||
303 | if (write_regs(client, initial_registers) < 0) { | 288 | if (write_regs(client, initial_registers) < 0) { |
304 | printk(KERN_ERR | 289 | printk(KERN_ERR |
305 | "wis-saa7113: error initializing SAA7113\n"); | 290 | "wis-saa7113: error initializing SAA7113\n"); |
306 | kfree(client); | ||
307 | kfree(dec); | 291 | kfree(dec); |
308 | return 0; | 292 | return -ENODEV; |
309 | } | 293 | } |
310 | 294 | ||
311 | i2c_attach_client(client); | ||
312 | return 0; | 295 | return 0; |
313 | } | 296 | } |
314 | 297 | ||
315 | static int wis_saa7113_detach(struct i2c_client *client) | 298 | static int wis_saa7113_remove(struct i2c_client *client) |
316 | { | 299 | { |
317 | struct wis_saa7113 *dec = i2c_get_clientdata(client); | 300 | struct wis_saa7113 *dec = i2c_get_clientdata(client); |
318 | int r; | ||
319 | |||
320 | r = i2c_detach_client(client); | ||
321 | if (r < 0) | ||
322 | return r; | ||
323 | 301 | ||
324 | kfree(client); | 302 | i2c_set_clientdata(client, NULL); |
325 | kfree(dec); | 303 | kfree(dec); |
326 | return 0; | 304 | return 0; |
327 | } | 305 | } |
328 | 306 | ||
307 | static struct i2c_device_id wis_saa7113_id[] = { | ||
308 | { "wis_saa7113", 0 }, | ||
309 | { } | ||
310 | }; | ||
311 | |||
329 | static struct i2c_driver wis_saa7113_driver = { | 312 | static struct i2c_driver wis_saa7113_driver = { |
330 | .driver = { | 313 | .driver = { |
331 | .name = "WIS SAA7113 I2C driver", | 314 | .name = "WIS SAA7113 I2C driver", |
332 | }, | 315 | }, |
333 | .id = I2C_DRIVERID_WIS_SAA7113, | 316 | .probe = wis_saa7113_probe, |
334 | .detach_client = wis_saa7113_detach, | 317 | .remove = wis_saa7113_remove, |
335 | .command = wis_saa7113_command, | 318 | .command = wis_saa7113_command, |
319 | .id_table = wis_saa7113_id, | ||
336 | }; | 320 | }; |
337 | 321 | ||
338 | static int __init wis_saa7113_init(void) | 322 | static int __init wis_saa7113_init(void) |
339 | { | 323 | { |
340 | int r; | 324 | return i2c_add_driver(&wis_saa7113_driver); |
341 | |||
342 | r = i2c_add_driver(&wis_saa7113_driver); | ||
343 | if (r < 0) | ||
344 | return r; | ||
345 | return wis_i2c_add_driver(wis_saa7113_driver.id, wis_saa7113_detect); | ||
346 | } | 325 | } |
347 | 326 | ||
348 | static void __exit wis_saa7113_cleanup(void) | 327 | static void __exit wis_saa7113_cleanup(void) |
349 | { | 328 | { |
350 | wis_i2c_del_driver(wis_saa7113_detect); | ||
351 | i2c_del_driver(&wis_saa7113_driver); | 329 | i2c_del_driver(&wis_saa7113_driver); |
352 | } | 330 | } |
353 | 331 | ||
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c index 59417a7174d7..8687ad2de761 100644 --- a/drivers/staging/go7007/wis-saa7115.c +++ b/drivers/staging/go7007/wis-saa7115.c | |||
@@ -394,34 +394,19 @@ static int wis_saa7115_command(struct i2c_client *client, | |||
394 | return 0; | 394 | return 0; |
395 | } | 395 | } |
396 | 396 | ||
397 | static struct i2c_driver wis_saa7115_driver; | 397 | static int wis_saa7115_probe(struct i2c_client *client, |
398 | 398 | const struct i2c_device_id *id) | |
399 | static struct i2c_client wis_saa7115_client_templ = { | ||
400 | .name = "SAA7115 (WIS)", | ||
401 | .driver = &wis_saa7115_driver, | ||
402 | }; | ||
403 | |||
404 | static int wis_saa7115_detect(struct i2c_adapter *adapter, int addr, int kind) | ||
405 | { | 399 | { |
406 | struct i2c_client *client; | 400 | struct i2c_adapter *adapter = client->adapter; |
407 | struct wis_saa7115 *dec; | 401 | struct wis_saa7115 *dec; |
408 | 402 | ||
409 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 403 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
410 | return 0; | 404 | return -ENODEV; |
411 | |||
412 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
413 | if (client == NULL) | ||
414 | return -ENOMEM; | ||
415 | memcpy(client, &wis_saa7115_client_templ, | ||
416 | sizeof(wis_saa7115_client_templ)); | ||
417 | client->adapter = adapter; | ||
418 | client->addr = addr; | ||
419 | 405 | ||
420 | dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL); | 406 | dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL); |
421 | if (dec == NULL) { | 407 | if (dec == NULL) |
422 | kfree(client); | ||
423 | return -ENOMEM; | 408 | return -ENOMEM; |
424 | } | 409 | |
425 | dec->norm = V4L2_STD_NTSC; | 410 | dec->norm = V4L2_STD_NTSC; |
426 | dec->brightness = 128; | 411 | dec->brightness = 128; |
427 | dec->contrast = 64; | 412 | dec->contrast = 64; |
@@ -431,56 +416,49 @@ static int wis_saa7115_detect(struct i2c_adapter *adapter, int addr, int kind) | |||
431 | 416 | ||
432 | printk(KERN_DEBUG | 417 | printk(KERN_DEBUG |
433 | "wis-saa7115: initializing SAA7115 at address %d on %s\n", | 418 | "wis-saa7115: initializing SAA7115 at address %d on %s\n", |
434 | addr, adapter->name); | 419 | client->addr, adapter->name); |
435 | 420 | ||
436 | if (write_regs(client, initial_registers) < 0) { | 421 | if (write_regs(client, initial_registers) < 0) { |
437 | printk(KERN_ERR | 422 | printk(KERN_ERR |
438 | "wis-saa7115: error initializing SAA7115\n"); | 423 | "wis-saa7115: error initializing SAA7115\n"); |
439 | kfree(client); | ||
440 | kfree(dec); | 424 | kfree(dec); |
441 | return 0; | 425 | return -ENODEV; |
442 | } | 426 | } |
443 | 427 | ||
444 | i2c_attach_client(client); | ||
445 | return 0; | 428 | return 0; |
446 | } | 429 | } |
447 | 430 | ||
448 | static int wis_saa7115_detach(struct i2c_client *client) | 431 | static int wis_saa7115_remove(struct i2c_client *client) |
449 | { | 432 | { |
450 | struct wis_saa7115 *dec = i2c_get_clientdata(client); | 433 | struct wis_saa7115 *dec = i2c_get_clientdata(client); |
451 | int r; | ||
452 | |||
453 | r = i2c_detach_client(client); | ||
454 | if (r < 0) | ||
455 | return r; | ||
456 | 434 | ||
457 | kfree(client); | 435 | i2c_set_clientdata(client, NULL); |
458 | kfree(dec); | 436 | kfree(dec); |
459 | return 0; | 437 | return 0; |
460 | } | 438 | } |
461 | 439 | ||
440 | static struct i2c_device_id wis_saa7115_id[] = { | ||
441 | { "wis_saa7115", 0 }, | ||
442 | { } | ||
443 | }; | ||
444 | |||
462 | static struct i2c_driver wis_saa7115_driver = { | 445 | static struct i2c_driver wis_saa7115_driver = { |
463 | .driver = { | 446 | .driver = { |
464 | .name = "WIS SAA7115 I2C driver", | 447 | .name = "WIS SAA7115 I2C driver", |
465 | }, | 448 | }, |
466 | .id = I2C_DRIVERID_WIS_SAA7115, | 449 | .probe = wis_saa7115_probe, |
467 | .detach_client = wis_saa7115_detach, | 450 | .remove = wis_saa7115_remove, |
468 | .command = wis_saa7115_command, | 451 | .command = wis_saa7115_command, |
452 | .id_table = wis_saa7115_id, | ||
469 | }; | 453 | }; |
470 | 454 | ||
471 | static int __init wis_saa7115_init(void) | 455 | static int __init wis_saa7115_init(void) |
472 | { | 456 | { |
473 | int r; | 457 | return i2c_add_driver(&wis_saa7115_driver); |
474 | |||
475 | r = i2c_add_driver(&wis_saa7115_driver); | ||
476 | if (r < 0) | ||
477 | return r; | ||
478 | return wis_i2c_add_driver(wis_saa7115_driver.id, wis_saa7115_detect); | ||
479 | } | 458 | } |
480 | 459 | ||
481 | static void __exit wis_saa7115_cleanup(void) | 460 | static void __exit wis_saa7115_cleanup(void) |
482 | { | 461 | { |
483 | wis_i2c_del_driver(wis_saa7115_detect); | ||
484 | i2c_del_driver(&wis_saa7115_driver); | 462 | i2c_del_driver(&wis_saa7115_driver); |
485 | } | 463 | } |
486 | 464 | ||
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c index 58fddb122372..c965c601ac90 100644 --- a/drivers/staging/go7007/wis-sony-tuner.c +++ b/drivers/staging/go7007/wis-sony-tuner.c | |||
@@ -386,6 +386,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
386 | struct wis_sony_tuner *t = i2c_get_clientdata(client); | 386 | struct wis_sony_tuner *t = i2c_get_clientdata(client); |
387 | 387 | ||
388 | switch (cmd) { | 388 | switch (cmd) { |
389 | #if 0 | ||
389 | #ifdef TUNER_SET_TYPE_ADDR | 390 | #ifdef TUNER_SET_TYPE_ADDR |
390 | case TUNER_SET_TYPE_ADDR: | 391 | case TUNER_SET_TYPE_ADDR: |
391 | { | 392 | { |
@@ -463,6 +464,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
463 | t->type, sony_tuners[t->type - 200].name); | 464 | t->type, sony_tuners[t->type - 200].name); |
464 | break; | 465 | break; |
465 | } | 466 | } |
467 | #endif | ||
466 | case VIDIOC_G_FREQUENCY: | 468 | case VIDIOC_G_FREQUENCY: |
467 | { | 469 | { |
468 | struct v4l2_frequency *f = arg; | 470 | struct v4l2_frequency *f = arg; |
@@ -651,35 +653,19 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
651 | return 0; | 653 | return 0; |
652 | } | 654 | } |
653 | 655 | ||
654 | static struct i2c_driver wis_sony_tuner_driver; | 656 | static int wis_sony_tuner_probe(struct i2c_client *client, |
655 | 657 | const struct i2c_device_id *id) | |
656 | static struct i2c_client wis_sony_tuner_client_templ = { | ||
657 | .name = "Sony TV Tuner (WIS)", | ||
658 | .driver = &wis_sony_tuner_driver, | ||
659 | }; | ||
660 | |||
661 | static int wis_sony_tuner_detect(struct i2c_adapter *adapter, | ||
662 | int addr, int kind) | ||
663 | { | 658 | { |
664 | struct i2c_client *client; | 659 | struct i2c_adapter *adapter = client->adapter; |
665 | struct wis_sony_tuner *t; | 660 | struct wis_sony_tuner *t; |
666 | 661 | ||
667 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) | 662 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) |
668 | return 0; | 663 | return -ENODEV; |
669 | |||
670 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
671 | if (client == NULL) | ||
672 | return -ENOMEM; | ||
673 | memcpy(client, &wis_sony_tuner_client_templ, | ||
674 | sizeof(wis_sony_tuner_client_templ)); | ||
675 | client->adapter = adapter; | ||
676 | client->addr = addr; | ||
677 | 664 | ||
678 | t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL); | 665 | t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL); |
679 | if (t == NULL) { | 666 | if (t == NULL) |
680 | kfree(client); | ||
681 | return -ENOMEM; | 667 | return -ENOMEM; |
682 | } | 668 | |
683 | t->type = -1; | 669 | t->type = -1; |
684 | t->freq = 0; | 670 | t->freq = 0; |
685 | t->mpxmode = 0; | 671 | t->mpxmode = 0; |
@@ -688,50 +674,42 @@ static int wis_sony_tuner_detect(struct i2c_adapter *adapter, | |||
688 | 674 | ||
689 | printk(KERN_DEBUG | 675 | printk(KERN_DEBUG |
690 | "wis-sony-tuner: initializing tuner at address %d on %s\n", | 676 | "wis-sony-tuner: initializing tuner at address %d on %s\n", |
691 | addr, adapter->name); | 677 | client->addr, adapter->name); |
692 | |||
693 | i2c_attach_client(client); | ||
694 | 678 | ||
695 | return 0; | 679 | return 0; |
696 | } | 680 | } |
697 | 681 | ||
698 | static int wis_sony_tuner_detach(struct i2c_client *client) | 682 | static int wis_sony_tuner_remove(struct i2c_client *client) |
699 | { | 683 | { |
700 | struct wis_sony_tuner *t = i2c_get_clientdata(client); | 684 | struct wis_sony_tuner *t = i2c_get_clientdata(client); |
701 | int r; | ||
702 | |||
703 | r = i2c_detach_client(client); | ||
704 | if (r < 0) | ||
705 | return r; | ||
706 | 685 | ||
686 | i2c_set_clientdata(client, NULL); | ||
707 | kfree(t); | 687 | kfree(t); |
708 | kfree(client); | ||
709 | return 0; | 688 | return 0; |
710 | } | 689 | } |
711 | 690 | ||
691 | static struct i2c_device_id wis_sony_tuner_id[] = { | ||
692 | { "wis_sony_tuner", 0 }, | ||
693 | { } | ||
694 | }; | ||
695 | |||
712 | static struct i2c_driver wis_sony_tuner_driver = { | 696 | static struct i2c_driver wis_sony_tuner_driver = { |
713 | .driver = { | 697 | .driver = { |
714 | .name = "WIS Sony TV Tuner I2C driver", | 698 | .name = "WIS Sony TV Tuner I2C driver", |
715 | }, | 699 | }, |
716 | .id = I2C_DRIVERID_WIS_SONY_TUNER, | 700 | .probe = wis_sony_tuner_probe, |
717 | .detach_client = wis_sony_tuner_detach, | 701 | .remove = wis_sony_tuner_remove, |
718 | .command = tuner_command, | 702 | .command = tuner_command, |
703 | .id_table = wis_sony_tuner_id, | ||
719 | }; | 704 | }; |
720 | 705 | ||
721 | static int __init wis_sony_tuner_init(void) | 706 | static int __init wis_sony_tuner_init(void) |
722 | { | 707 | { |
723 | int r; | 708 | return i2c_add_driver(&wis_sony_tuner_driver); |
724 | |||
725 | r = i2c_add_driver(&wis_sony_tuner_driver); | ||
726 | if (r < 0) | ||
727 | return r; | ||
728 | return wis_i2c_add_driver(wis_sony_tuner_driver.id, | ||
729 | wis_sony_tuner_detect); | ||
730 | } | 709 | } |
731 | 710 | ||
732 | static void __exit wis_sony_tuner_cleanup(void) | 711 | static void __exit wis_sony_tuner_cleanup(void) |
733 | { | 712 | { |
734 | wis_i2c_del_driver(wis_sony_tuner_detect); | ||
735 | i2c_del_driver(&wis_sony_tuner_driver); | 713 | i2c_del_driver(&wis_sony_tuner_driver); |
736 | } | 714 | } |
737 | 715 | ||
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c index 57b8f2b1caa3..e15794a2a0ae 100644 --- a/drivers/staging/go7007/wis-tw2804.c +++ b/drivers/staging/go7007/wis-tw2804.c | |||
@@ -291,34 +291,19 @@ static int wis_tw2804_command(struct i2c_client *client, | |||
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | static struct i2c_driver wis_tw2804_driver; | 294 | static int wis_tw2804_probe(struct i2c_client *client, |
295 | 295 | const struct i2c_device_id *id) | |
296 | static struct i2c_client wis_tw2804_client_templ = { | ||
297 | .name = "TW2804 (WIS)", | ||
298 | .driver = &wis_tw2804_driver, | ||
299 | }; | ||
300 | |||
301 | static int wis_tw2804_detect(struct i2c_adapter *adapter, int addr, int kind) | ||
302 | { | 296 | { |
303 | struct i2c_client *client; | 297 | struct i2c_adapter *adapter = client->adapter; |
304 | struct wis_tw2804 *dec; | 298 | struct wis_tw2804 *dec; |
305 | 299 | ||
306 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 300 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
307 | return 0; | 301 | return -ENODEV; |
308 | |||
309 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
310 | if (client == NULL) | ||
311 | return -ENOMEM; | ||
312 | memcpy(client, &wis_tw2804_client_templ, | ||
313 | sizeof(wis_tw2804_client_templ)); | ||
314 | client->adapter = adapter; | ||
315 | client->addr = addr; | ||
316 | 302 | ||
317 | dec = kmalloc(sizeof(struct wis_tw2804), GFP_KERNEL); | 303 | dec = kmalloc(sizeof(struct wis_tw2804), GFP_KERNEL); |
318 | if (dec == NULL) { | 304 | if (dec == NULL) |
319 | kfree(client); | ||
320 | return -ENOMEM; | 305 | return -ENOMEM; |
321 | } | 306 | |
322 | dec->channel = -1; | 307 | dec->channel = -1; |
323 | dec->norm = V4L2_STD_NTSC; | 308 | dec->norm = V4L2_STD_NTSC; |
324 | dec->brightness = 128; | 309 | dec->brightness = 128; |
@@ -328,48 +313,42 @@ static int wis_tw2804_detect(struct i2c_adapter *adapter, int addr, int kind) | |||
328 | i2c_set_clientdata(client, dec); | 313 | i2c_set_clientdata(client, dec); |
329 | 314 | ||
330 | printk(KERN_DEBUG "wis-tw2804: creating TW2804 at address %d on %s\n", | 315 | printk(KERN_DEBUG "wis-tw2804: creating TW2804 at address %d on %s\n", |
331 | addr, adapter->name); | 316 | client->addr, adapter->name); |
332 | 317 | ||
333 | i2c_attach_client(client); | ||
334 | return 0; | 318 | return 0; |
335 | } | 319 | } |
336 | 320 | ||
337 | static int wis_tw2804_detach(struct i2c_client *client) | 321 | static int wis_tw2804_remove(struct i2c_client *client) |
338 | { | 322 | { |
339 | struct wis_tw2804 *dec = i2c_get_clientdata(client); | 323 | struct wis_tw2804 *dec = i2c_get_clientdata(client); |
340 | int r; | ||
341 | |||
342 | r = i2c_detach_client(client); | ||
343 | if (r < 0) | ||
344 | return r; | ||
345 | 324 | ||
346 | kfree(client); | 325 | i2c_set_clientdata(client, NULL); |
347 | kfree(dec); | 326 | kfree(dec); |
348 | return 0; | 327 | return 0; |
349 | } | 328 | } |
350 | 329 | ||
330 | static struct i2c_device_id wis_tw2804_id[] = { | ||
331 | { "wis_tw2804", 0 }, | ||
332 | { } | ||
333 | }; | ||
334 | |||
351 | static struct i2c_driver wis_tw2804_driver = { | 335 | static struct i2c_driver wis_tw2804_driver = { |
352 | .driver = { | 336 | .driver = { |
353 | .name = "WIS TW2804 I2C driver", | 337 | .name = "WIS TW2804 I2C driver", |
354 | }, | 338 | }, |
355 | .id = I2C_DRIVERID_WIS_TW2804, | 339 | .probe = wis_tw2804_probe, |
356 | .detach_client = wis_tw2804_detach, | 340 | .remove = wis_tw2804_remove, |
357 | .command = wis_tw2804_command, | 341 | .command = wis_tw2804_command, |
342 | .id_table = wis_tw2804_id, | ||
358 | }; | 343 | }; |
359 | 344 | ||
360 | static int __init wis_tw2804_init(void) | 345 | static int __init wis_tw2804_init(void) |
361 | { | 346 | { |
362 | int r; | 347 | return i2c_add_driver(&wis_tw2804_driver); |
363 | |||
364 | r = i2c_add_driver(&wis_tw2804_driver); | ||
365 | if (r < 0) | ||
366 | return r; | ||
367 | return wis_i2c_add_driver(wis_tw2804_driver.id, wis_tw2804_detect); | ||
368 | } | 348 | } |
369 | 349 | ||
370 | static void __exit wis_tw2804_cleanup(void) | 350 | static void __exit wis_tw2804_cleanup(void) |
371 | { | 351 | { |
372 | wis_i2c_del_driver(wis_tw2804_detect); | ||
373 | i2c_del_driver(&wis_tw2804_driver); | 352 | i2c_del_driver(&wis_tw2804_driver); |
374 | } | 353 | } |
375 | 354 | ||
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c index 40627b282cb4..6c3427bb6f4c 100644 --- a/drivers/staging/go7007/wis-tw9903.c +++ b/drivers/staging/go7007/wis-tw9903.c | |||
@@ -267,34 +267,19 @@ static int wis_tw9903_command(struct i2c_client *client, | |||
267 | return 0; | 267 | return 0; |
268 | } | 268 | } |
269 | 269 | ||
270 | static struct i2c_driver wis_tw9903_driver; | 270 | static int wis_tw9903_probe(struct i2c_client *client, |
271 | 271 | const struct i2c_device_id *id) | |
272 | static struct i2c_client wis_tw9903_client_templ = { | ||
273 | .name = "TW9903 (WIS)", | ||
274 | .driver = &wis_tw9903_driver, | ||
275 | }; | ||
276 | |||
277 | static int wis_tw9903_detect(struct i2c_adapter *adapter, int addr, int kind) | ||
278 | { | 272 | { |
279 | struct i2c_client *client; | 273 | struct i2c_adapter *adapter = client->adapter; |
280 | struct wis_tw9903 *dec; | 274 | struct wis_tw9903 *dec; |
281 | 275 | ||
282 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 276 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
283 | return 0; | 277 | return -ENODEV; |
284 | |||
285 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
286 | if (client == NULL) | ||
287 | return -ENOMEM; | ||
288 | memcpy(client, &wis_tw9903_client_templ, | ||
289 | sizeof(wis_tw9903_client_templ)); | ||
290 | client->adapter = adapter; | ||
291 | client->addr = addr; | ||
292 | 278 | ||
293 | dec = kmalloc(sizeof(struct wis_tw9903), GFP_KERNEL); | 279 | dec = kmalloc(sizeof(struct wis_tw9903), GFP_KERNEL); |
294 | if (dec == NULL) { | 280 | if (dec == NULL) |
295 | kfree(client); | ||
296 | return -ENOMEM; | 281 | return -ENOMEM; |
297 | } | 282 | |
298 | dec->norm = V4L2_STD_NTSC; | 283 | dec->norm = V4L2_STD_NTSC; |
299 | dec->brightness = 0; | 284 | dec->brightness = 0; |
300 | dec->contrast = 0x60; | 285 | dec->contrast = 0x60; |
@@ -303,55 +288,48 @@ static int wis_tw9903_detect(struct i2c_adapter *adapter, int addr, int kind) | |||
303 | 288 | ||
304 | printk(KERN_DEBUG | 289 | printk(KERN_DEBUG |
305 | "wis-tw9903: initializing TW9903 at address %d on %s\n", | 290 | "wis-tw9903: initializing TW9903 at address %d on %s\n", |
306 | addr, adapter->name); | 291 | client->addr, adapter->name); |
307 | 292 | ||
308 | if (write_regs(client, initial_registers) < 0) { | 293 | if (write_regs(client, initial_registers) < 0) { |
309 | printk(KERN_ERR "wis-tw9903: error initializing TW9903\n"); | 294 | printk(KERN_ERR "wis-tw9903: error initializing TW9903\n"); |
310 | kfree(client); | ||
311 | kfree(dec); | 295 | kfree(dec); |
312 | return 0; | 296 | return -ENODEV; |
313 | } | 297 | } |
314 | 298 | ||
315 | i2c_attach_client(client); | ||
316 | return 0; | 299 | return 0; |
317 | } | 300 | } |
318 | 301 | ||
319 | static int wis_tw9903_detach(struct i2c_client *client) | 302 | static int wis_tw9903_remove(struct i2c_client *client) |
320 | { | 303 | { |
321 | struct wis_tw9903 *dec = i2c_get_clientdata(client); | 304 | struct wis_tw9903 *dec = i2c_get_clientdata(client); |
322 | int r; | ||
323 | |||
324 | r = i2c_detach_client(client); | ||
325 | if (r < 0) | ||
326 | return r; | ||
327 | 305 | ||
328 | kfree(client); | 306 | i2c_set_clientdata(client, NULL); |
329 | kfree(dec); | 307 | kfree(dec); |
330 | return 0; | 308 | return 0; |
331 | } | 309 | } |
332 | 310 | ||
311 | static struct i2c_device_id wis_tw9903_id[] = { | ||
312 | { "wis_tw9903", 0 }, | ||
313 | { } | ||
314 | }; | ||
315 | |||
333 | static struct i2c_driver wis_tw9903_driver = { | 316 | static struct i2c_driver wis_tw9903_driver = { |
334 | .driver = { | 317 | .driver = { |
335 | .name = "WIS TW9903 I2C driver", | 318 | .name = "WIS TW9903 I2C driver", |
336 | }, | 319 | }, |
337 | .id = I2C_DRIVERID_WIS_TW9903, | 320 | .probe = wis_tw9903_probe, |
338 | .detach_client = wis_tw9903_detach, | 321 | .remove = wis_tw9903_remove, |
339 | .command = wis_tw9903_command, | 322 | .command = wis_tw9903_command, |
323 | .id_table = wis_tw9903_id, | ||
340 | }; | 324 | }; |
341 | 325 | ||
342 | static int __init wis_tw9903_init(void) | 326 | static int __init wis_tw9903_init(void) |
343 | { | 327 | { |
344 | int r; | 328 | return i2c_add_driver(&wis_tw9903_driver); |
345 | |||
346 | r = i2c_add_driver(&wis_tw9903_driver); | ||
347 | if (r < 0) | ||
348 | return r; | ||
349 | return wis_i2c_add_driver(wis_tw9903_driver.id, wis_tw9903_detect); | ||
350 | } | 329 | } |
351 | 330 | ||
352 | static void __exit wis_tw9903_cleanup(void) | 331 | static void __exit wis_tw9903_cleanup(void) |
353 | { | 332 | { |
354 | wis_i2c_del_driver(wis_tw9903_detect); | ||
355 | i2c_del_driver(&wis_tw9903_driver); | 333 | i2c_del_driver(&wis_tw9903_driver); |
356 | } | 334 | } |
357 | 335 | ||
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c index 555645c0cc1a..739c7ae8913f 100644 --- a/drivers/staging/go7007/wis-uda1342.c +++ b/drivers/staging/go7007/wis-uda1342.c | |||
@@ -59,73 +59,51 @@ static int wis_uda1342_command(struct i2c_client *client, | |||
59 | return 0; | 59 | return 0; |
60 | } | 60 | } |
61 | 61 | ||
62 | static struct i2c_driver wis_uda1342_driver; | 62 | static int wis_uda1342_probe(struct i2c_client *client, |
63 | 63 | const struct i2c_device_id *id) | |
64 | static struct i2c_client wis_uda1342_client_templ = { | ||
65 | .name = "UDA1342 (WIS)", | ||
66 | .driver = &wis_uda1342_driver, | ||
67 | }; | ||
68 | |||
69 | static int wis_uda1342_detect(struct i2c_adapter *adapter, int addr, int kind) | ||
70 | { | 64 | { |
71 | struct i2c_client *client; | 65 | struct i2c_adapter *adapter = client->adapter; |
72 | 66 | ||
73 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) | 67 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) |
74 | return 0; | 68 | return -ENODEV; |
75 | |||
76 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
77 | if (client == NULL) | ||
78 | return -ENOMEM; | ||
79 | memcpy(client, &wis_uda1342_client_templ, | ||
80 | sizeof(wis_uda1342_client_templ)); | ||
81 | client->adapter = adapter; | ||
82 | client->addr = addr; | ||
83 | 69 | ||
84 | printk(KERN_DEBUG | 70 | printk(KERN_DEBUG |
85 | "wis-uda1342: initializing UDA1342 at address %d on %s\n", | 71 | "wis-uda1342: initializing UDA1342 at address %d on %s\n", |
86 | addr, adapter->name); | 72 | client->addr, adapter->name); |
87 | 73 | ||
88 | write_reg(client, 0x00, 0x8000); /* reset registers */ | 74 | write_reg(client, 0x00, 0x8000); /* reset registers */ |
89 | write_reg(client, 0x00, 0x1241); /* select input 1 */ | 75 | write_reg(client, 0x00, 0x1241); /* select input 1 */ |
90 | 76 | ||
91 | i2c_attach_client(client); | ||
92 | return 0; | 77 | return 0; |
93 | } | 78 | } |
94 | 79 | ||
95 | static int wis_uda1342_detach(struct i2c_client *client) | 80 | static int wis_uda1342_remove(struct i2c_client *client) |
96 | { | 81 | { |
97 | int r; | ||
98 | |||
99 | r = i2c_detach_client(client); | ||
100 | if (r < 0) | ||
101 | return r; | ||
102 | |||
103 | kfree(client); | ||
104 | return 0; | 82 | return 0; |
105 | } | 83 | } |
106 | 84 | ||
85 | static struct i2c_device_id wis_uda1342_id[] = { | ||
86 | { "wis_uda1342", 0 }, | ||
87 | { } | ||
88 | }; | ||
89 | |||
107 | static struct i2c_driver wis_uda1342_driver = { | 90 | static struct i2c_driver wis_uda1342_driver = { |
108 | .driver = { | 91 | .driver = { |
109 | .name = "WIS UDA1342 I2C driver", | 92 | .name = "WIS UDA1342 I2C driver", |
110 | }, | 93 | }, |
111 | .id = I2C_DRIVERID_WIS_UDA1342, | 94 | .probe = wis_uda1342_probe, |
112 | .detach_client = wis_uda1342_detach, | 95 | .remove = wis_uda1342_remove, |
113 | .command = wis_uda1342_command, | 96 | .command = wis_uda1342_command, |
97 | .id_table = wis_uda1342_id, | ||
114 | }; | 98 | }; |
115 | 99 | ||
116 | static int __init wis_uda1342_init(void) | 100 | static int __init wis_uda1342_init(void) |
117 | { | 101 | { |
118 | int r; | 102 | return i2c_add_driver(&wis_uda1342_driver); |
119 | |||
120 | r = i2c_add_driver(&wis_uda1342_driver); | ||
121 | if (r < 0) | ||
122 | return r; | ||
123 | return wis_i2c_add_driver(wis_uda1342_driver.id, wis_uda1342_detect); | ||
124 | } | 103 | } |
125 | 104 | ||
126 | static void __exit wis_uda1342_cleanup(void) | 105 | static void __exit wis_uda1342_cleanup(void) |
127 | { | 106 | { |
128 | wis_i2c_del_driver(wis_uda1342_detect); | ||
129 | i2c_del_driver(&wis_uda1342_driver); | 107 | i2c_del_driver(&wis_uda1342_driver); |
130 | } | 108 | } |
131 | 109 | ||
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c index 3aa946899ced..e2ac8d60f8c2 100644 --- a/drivers/staging/line6/audio.c +++ b/drivers/staging/line6/audio.c | |||
@@ -27,11 +27,12 @@ int line6_init_audio(struct usb_line6 *line6) | |||
27 | { | 27 | { |
28 | static int dev; | 28 | static int dev; |
29 | struct snd_card *card; | 29 | struct snd_card *card; |
30 | int err; | ||
30 | 31 | ||
31 | card = snd_card_new(line6_index[dev], line6_id[dev], THIS_MODULE, 0); | 32 | err = snd_card_create(line6_index[dev], line6_id[dev], THIS_MODULE, 0, |
32 | 33 | &card); | |
33 | if (card == NULL) | 34 | if (err < 0) |
34 | return -ENOMEM; | 35 | return err; |
35 | 36 | ||
36 | line6->card = card; | 37 | line6->card = card; |
37 | 38 | ||
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c index 565a839589f5..540cbbb826f9 100644 --- a/drivers/staging/otus/usbdrv.c +++ b/drivers/staging/otus/usbdrv.c | |||
@@ -822,6 +822,21 @@ int zfLnxVapXmitFrame(struct sk_buff *skb, struct net_device *dev) | |||
822 | return 0; | 822 | return 0; |
823 | } | 823 | } |
824 | 824 | ||
825 | static const struct net_device_ops vap_netdev_ops = { | ||
826 | .ndo_open = zfLnxVapOpen, | ||
827 | .ndo_stop = zfLnxVapClose, | ||
828 | .ndo_start_xmit = zfLnxVapXmitFrame, | ||
829 | .ndo_get_stats = usbdrv_get_stats, | ||
830 | .ndo_change_mtu = usbdrv_change_mtu, | ||
831 | .ndo_validate_addr = eth_validate_addr, | ||
832 | .ndo_set_mac_address = eth_mac_addr, | ||
833 | #ifdef ZM_HOSTAPD_SUPPORT | ||
834 | .ndo_do_ioctl = usbdrv_ioctl, | ||
835 | #else | ||
836 | .ndo_do_ioctl = NULL, | ||
837 | #endif | ||
838 | }; | ||
839 | |||
825 | int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId) | 840 | int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId) |
826 | { | 841 | { |
827 | /* Allocate net device structure */ | 842 | /* Allocate net device structure */ |
@@ -846,16 +861,7 @@ int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId) | |||
846 | vap[vapId].dev->ml_priv = parentDev->ml_priv; | 861 | vap[vapId].dev->ml_priv = parentDev->ml_priv; |
847 | 862 | ||
848 | //dev->hard_start_xmit = &zd1212_wds_xmit_frame; | 863 | //dev->hard_start_xmit = &zd1212_wds_xmit_frame; |
849 | vap[vapId].dev->hard_start_xmit = &zfLnxVapXmitFrame; | 864 | vap[vapId].dev->netdev_ops = &vap_netdev_ops; |
850 | vap[vapId].dev->open = &zfLnxVapOpen; | ||
851 | vap[vapId].dev->stop = &zfLnxVapClose; | ||
852 | vap[vapId].dev->get_stats = &usbdrv_get_stats; | ||
853 | vap[vapId].dev->change_mtu = &usbdrv_change_mtu; | ||
854 | #ifdef ZM_HOSTAPD_SUPPORT | ||
855 | vap[vapId].dev->do_ioctl = usbdrv_ioctl; | ||
856 | #else | ||
857 | vap[vapId].dev->do_ioctl = NULL; | ||
858 | #endif | ||
859 | vap[vapId].dev->destructor = free_netdev; | 865 | vap[vapId].dev->destructor = free_netdev; |
860 | 866 | ||
861 | vap[vapId].dev->tx_queue_len = 0; | 867 | vap[vapId].dev->tx_queue_len = 0; |
@@ -1068,6 +1074,18 @@ void zfLnxUnlinkAllUrbs(struct usbdrv_private *macp) | |||
1068 | usb_unlink_urb(macp->RegInUrb); | 1074 | usb_unlink_urb(macp->RegInUrb); |
1069 | } | 1075 | } |
1070 | 1076 | ||
1077 | static const struct net_device_ops otus_netdev_ops = { | ||
1078 | .ndo_open = usbdrv_open, | ||
1079 | .ndo_stop = usbdrv_close, | ||
1080 | .ndo_start_xmit = usbdrv_xmit_frame, | ||
1081 | .ndo_change_mtu = usbdrv_change_mtu, | ||
1082 | .ndo_get_stats = usbdrv_get_stats, | ||
1083 | .ndo_set_multicast_list = usbdrv_set_multi, | ||
1084 | .ndo_set_mac_address = usbdrv_set_mac, | ||
1085 | .ndo_do_ioctl = usbdrv_ioctl, | ||
1086 | .ndo_validate_addr = eth_validate_addr, | ||
1087 | }; | ||
1088 | |||
1071 | u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp) | 1089 | u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp) |
1072 | { | 1090 | { |
1073 | //unsigned char addr[6]; | 1091 | //unsigned char addr[6]; |
@@ -1092,14 +1110,7 @@ u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp) | |||
1092 | dev->wireless_handlers = (struct iw_handler_def *)&p80211wext_handler_def; | 1110 | dev->wireless_handlers = (struct iw_handler_def *)&p80211wext_handler_def; |
1093 | #endif | 1111 | #endif |
1094 | 1112 | ||
1095 | dev->open = usbdrv_open; | 1113 | dev->netdev_ops = &otus_netdev_ops; |
1096 | dev->hard_start_xmit = usbdrv_xmit_frame; | ||
1097 | dev->stop = usbdrv_close; | ||
1098 | dev->change_mtu = &usbdrv_change_mtu; | ||
1099 | dev->get_stats = usbdrv_get_stats; | ||
1100 | dev->set_multicast_list = usbdrv_set_multi; | ||
1101 | dev->set_mac_address = usbdrv_set_mac; | ||
1102 | dev->do_ioctl = usbdrv_ioctl; | ||
1103 | 1114 | ||
1104 | dev->flags |= IFF_MULTICAST; | 1115 | dev->flags |= IFF_MULTICAST; |
1105 | 1116 | ||
diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c index 78f1d2224fa1..2a6d937ba5e8 100644 --- a/drivers/staging/otus/zdusb.c +++ b/drivers/staging/otus/zdusb.c | |||
@@ -48,7 +48,8 @@ static const char driver_name[] = "Otus"; | |||
48 | static struct usb_device_id zd1221_ids [] = { | 48 | static struct usb_device_id zd1221_ids [] = { |
49 | { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) }, | 49 | { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) }, |
50 | { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) }, | 50 | { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) }, |
51 | { USB_DEVICE(0x0846, 0x9010) }, | 51 | { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) }, |
52 | { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WN111v2) }, | ||
52 | { } /* Terminating entry */ | 53 | { } /* Terminating entry */ |
53 | }; | 54 | }; |
54 | 55 | ||
diff --git a/drivers/staging/otus/zdusb.h b/drivers/staging/otus/zdusb.h index 656dc212ade5..9f8ab2e96169 100644 --- a/drivers/staging/otus/zdusb.h +++ b/drivers/staging/otus/zdusb.h | |||
@@ -40,4 +40,8 @@ | |||
40 | #define VENDOR_DLINK 0x07D1 //Dlink | 40 | #define VENDOR_DLINK 0x07D1 //Dlink |
41 | #define PRODUCT_DWA160A 0x3C10 | 41 | #define PRODUCT_DWA160A 0x3C10 |
42 | 42 | ||
43 | #define VENDOR_NETGEAR 0x0846 /* NetGear */ | ||
44 | #define PRODUCT_WNDA3100 0x9010 | ||
45 | #define PRODUCT_WN111v2 0x9001 | ||
46 | |||
43 | #endif | 47 | #endif |
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 3e67da9ea381..a6eaa42fb669 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c | |||
@@ -81,6 +81,45 @@ static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned | |||
81 | return g; | 81 | return g; |
82 | } | 82 | } |
83 | 83 | ||
84 | static inline void pohmelfs_insert_config_entry(struct pohmelfs_sb *psb, struct pohmelfs_config *dst) | ||
85 | { | ||
86 | struct pohmelfs_config *tmp; | ||
87 | |||
88 | INIT_LIST_HEAD(&dst->config_entry); | ||
89 | |||
90 | list_for_each_entry(tmp, &psb->state_list, config_entry) { | ||
91 | if (dst->state.ctl.prio > tmp->state.ctl.prio) | ||
92 | list_add_tail(&dst->config_entry, &tmp->config_entry); | ||
93 | } | ||
94 | if (list_empty(&dst->config_entry)) | ||
95 | list_add_tail(&dst->config_entry, &psb->state_list); | ||
96 | } | ||
97 | |||
98 | static int pohmelfs_move_config_entry(struct pohmelfs_sb *psb, | ||
99 | struct pohmelfs_config *dst, struct pohmelfs_config *new) | ||
100 | { | ||
101 | if ((dst->state.ctl.prio == new->state.ctl.prio) && | ||
102 | (dst->state.ctl.perm == new->state.ctl.perm)) | ||
103 | return 0; | ||
104 | |||
105 | dprintk("%s: dst: prio: %d, perm: %x, new: prio: %d, perm: %d.\n", | ||
106 | __func__, dst->state.ctl.prio, dst->state.ctl.perm, | ||
107 | new->state.ctl.prio, new->state.ctl.perm); | ||
108 | dst->state.ctl.prio = new->state.ctl.prio; | ||
109 | dst->state.ctl.perm = new->state.ctl.perm; | ||
110 | |||
111 | list_del_init(&dst->config_entry); | ||
112 | pohmelfs_insert_config_entry(psb, dst); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * pohmelfs_copy_config() is used to copy new state configs from the | ||
118 | * config group (controlled by the netlink messages) into the superblock. | ||
119 | * This happens either at startup time where no transactions can access | ||
120 | * the list of the configs (and thus list of the network states), or at | ||
121 | * run-time, where it is protected by the psb->state_lock. | ||
122 | */ | ||
84 | int pohmelfs_copy_config(struct pohmelfs_sb *psb) | 123 | int pohmelfs_copy_config(struct pohmelfs_sb *psb) |
85 | { | 124 | { |
86 | struct pohmelfs_config_group *g; | 125 | struct pohmelfs_config_group *g; |
@@ -103,7 +142,9 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) | |||
103 | err = 0; | 142 | err = 0; |
104 | list_for_each_entry(dst, &psb->state_list, config_entry) { | 143 | list_for_each_entry(dst, &psb->state_list, config_entry) { |
105 | if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) { | 144 | if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) { |
106 | err = -EEXIST; | 145 | err = pohmelfs_move_config_entry(psb, dst, c); |
146 | if (!err) | ||
147 | err = -EEXIST; | ||
107 | break; | 148 | break; |
108 | } | 149 | } |
109 | } | 150 | } |
@@ -119,7 +160,7 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) | |||
119 | 160 | ||
120 | memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl)); | 161 | memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl)); |
121 | 162 | ||
122 | list_add_tail(&dst->config_entry, &psb->state_list); | 163 | pohmelfs_insert_config_entry(psb, dst); |
123 | 164 | ||
124 | err = pohmelfs_state_init_one(psb, dst); | 165 | err = pohmelfs_state_init_one(psb, dst); |
125 | if (err) { | 166 | if (err) { |
@@ -248,6 +289,13 @@ out_unlock: | |||
248 | return err; | 289 | return err; |
249 | } | 290 | } |
250 | 291 | ||
292 | static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new) | ||
293 | { | ||
294 | old->perm = new->perm; | ||
295 | old->prio = new->prio; | ||
296 | return 0; | ||
297 | } | ||
298 | |||
251 | static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | 299 | static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) |
252 | { | 300 | { |
253 | struct pohmelfs_config_group *g; | 301 | struct pohmelfs_config_group *g; |
@@ -278,6 +326,9 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | |||
278 | g->num_entry--; | 326 | g->num_entry--; |
279 | kfree(c); | 327 | kfree(c); |
280 | goto out_unlock; | 328 | goto out_unlock; |
329 | } else if (action == POHMELFS_FLAGS_MODIFY) { | ||
330 | err = pohmelfs_modify_config(sc, ctl); | ||
331 | goto out_unlock; | ||
281 | } else { | 332 | } else { |
282 | err = -EEXIST; | 333 | err = -EEXIST; |
283 | goto out_unlock; | 334 | goto out_unlock; |
@@ -296,6 +347,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | |||
296 | } | 347 | } |
297 | memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl)); | 348 | memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl)); |
298 | g->num_entry++; | 349 | g->num_entry++; |
350 | |||
299 | list_add_tail(&c->config_entry, &g->config_list); | 351 | list_add_tail(&c->config_entry, &g->config_list); |
300 | 352 | ||
301 | out_unlock: | 353 | out_unlock: |
@@ -401,10 +453,9 @@ static void pohmelfs_cn_callback(void *data) | |||
401 | 453 | ||
402 | switch (msg->flags) { | 454 | switch (msg->flags) { |
403 | case POHMELFS_FLAGS_ADD: | 455 | case POHMELFS_FLAGS_ADD: |
404 | err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD); | ||
405 | break; | ||
406 | case POHMELFS_FLAGS_DEL: | 456 | case POHMELFS_FLAGS_DEL: |
407 | err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL); | 457 | case POHMELFS_FLAGS_MODIFY: |
458 | err = pohmelfs_cn_ctl(msg, msg->flags); | ||
408 | break; | 459 | break; |
409 | case POHMELFS_FLAGS_SHOW: | 460 | case POHMELFS_FLAGS_SHOW: |
410 | err = pohmelfs_cn_disp(msg); | 461 | err = pohmelfs_cn_disp(msg); |
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index 7a41183a32e1..b5799842fb84 100644 --- a/drivers/staging/pohmelfs/dir.c +++ b/drivers/staging/pohmelfs/dir.c | |||
@@ -328,7 +328,7 @@ static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi) | |||
328 | { | 328 | { |
329 | struct inode *inode = &pi->vfs_inode; | 329 | struct inode *inode = &pi->vfs_inode; |
330 | struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb); | 330 | struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb); |
331 | long ret = msecs_to_jiffies(25000); | 331 | long ret = psb->wait_on_page_timeout; |
332 | int err; | 332 | int err; |
333 | 333 | ||
334 | dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n", | 334 | dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n", |
@@ -389,11 +389,11 @@ static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
389 | dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n", | 389 | dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n", |
390 | __func__, pi->ino, (u64)file->f_pos, | 390 | __func__, pi->ino, (u64)file->f_pos, |
391 | (unsigned long)file->private_data); | 391 | (unsigned long)file->private_data); |
392 | 392 | #if 0 | |
393 | err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK); | 393 | err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK); |
394 | if (err) | 394 | if (err) |
395 | return err; | 395 | return err; |
396 | 396 | #endif | |
397 | err = pohmelfs_sync_remote_dir(pi); | 397 | err = pohmelfs_sync_remote_dir(pi); |
398 | if (err) | 398 | if (err) |
399 | return err; | 399 | return err; |
@@ -513,10 +513,6 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
513 | 513 | ||
514 | need_lock = pohmelfs_need_lock(parent, lock_type); | 514 | need_lock = pohmelfs_need_lock(parent, lock_type); |
515 | 515 | ||
516 | err = pohmelfs_data_lock(parent, 0, ~0, lock_type); | ||
517 | if (err) | ||
518 | goto out; | ||
519 | |||
520 | str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0); | 516 | str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0); |
521 | 517 | ||
522 | mutex_lock(&parent->offset_lock); | 518 | mutex_lock(&parent->offset_lock); |
@@ -525,8 +521,8 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
525 | ino = n->ino; | 521 | ino = n->ino; |
526 | mutex_unlock(&parent->offset_lock); | 522 | mutex_unlock(&parent->offset_lock); |
527 | 523 | ||
528 | dprintk("%s: 1 ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx.\n", | 524 | dprintk("%s: start ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx, need_lock: %d.\n", |
529 | __func__, ino, inode, str.name, str.hash, parent->state); | 525 | __func__, ino, inode, str.name, str.hash, parent->state, need_lock); |
530 | 526 | ||
531 | if (ino) { | 527 | if (ino) { |
532 | inode = ilookup(dir->i_sb, ino); | 528 | inode = ilookup(dir->i_sb, ino); |
@@ -534,7 +530,7 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
534 | goto out; | 530 | goto out; |
535 | } | 531 | } |
536 | 532 | ||
537 | dprintk("%s: dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n", | 533 | dprintk("%s: no inode dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n", |
538 | __func__, dir, parent->ino, | 534 | __func__, dir, parent->ino, |
539 | str.name, str.len, parent->state, ino); | 535 | str.name, str.len, parent->state, ino); |
540 | 536 | ||
@@ -543,6 +539,10 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
543 | goto out; | 539 | goto out; |
544 | } | 540 | } |
545 | 541 | ||
542 | err = pohmelfs_data_lock(parent, 0, ~0, lock_type); | ||
543 | if (err) | ||
544 | goto out; | ||
545 | |||
546 | err = pohmelfs_lookup_single(parent, &str, ino); | 546 | err = pohmelfs_lookup_single(parent, &str, ino); |
547 | if (err) | 547 | if (err) |
548 | goto out; | 548 | goto out; |
@@ -557,10 +557,10 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
557 | 557 | ||
558 | if (ino) { | 558 | if (ino) { |
559 | inode = ilookup(dir->i_sb, ino); | 559 | inode = ilookup(dir->i_sb, ino); |
560 | printk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n", | 560 | dprintk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n", |
561 | __func__, ino, inode, str.name, str.hash); | 561 | __func__, ino, inode, str.name, str.hash); |
562 | if (!inode) { | 562 | if (!inode) { |
563 | printk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n", | 563 | dprintk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n", |
564 | __func__, ino, str.name, str.hash); | 564 | __func__, ino, str.name, str.hash); |
565 | //return NULL; | 565 | //return NULL; |
566 | return ERR_PTR(-EACCES); | 566 | return ERR_PTR(-EACCES); |
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 5bf16504cd6f..b2eaf9047266 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c | |||
@@ -1169,16 +1169,17 @@ err_out_put: | |||
1169 | static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 1169 | static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |
1170 | { | 1170 | { |
1171 | struct inode *inode = dentry->d_inode; | 1171 | struct inode *inode = dentry->d_inode; |
1172 | #if 0 | ||
1172 | struct pohmelfs_inode *pi = POHMELFS_I(inode); | 1173 | struct pohmelfs_inode *pi = POHMELFS_I(inode); |
1173 | int err; | 1174 | int err; |
1174 | 1175 | ||
1175 | err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK); | 1176 | err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK); |
1176 | if (err) | 1177 | if (err) |
1177 | return err; | 1178 | return err; |
1178 | |||
1179 | dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n", | 1179 | dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n", |
1180 | __func__, pi->ino, inode->i_mode, inode->i_uid, | 1180 | __func__, pi->ino, inode->i_mode, inode->i_uid, |
1181 | inode->i_gid, inode->i_size); | 1181 | inode->i_gid, inode->i_size); |
1182 | #endif | ||
1182 | 1183 | ||
1183 | generic_fillattr(inode, stat); | 1184 | generic_fillattr(inode, stat); |
1184 | return 0; | 1185 | return 0; |
@@ -1342,14 +1343,6 @@ static void pohmelfs_put_super(struct super_block *sb) | |||
1342 | 1343 | ||
1343 | kfree(psb); | 1344 | kfree(psb); |
1344 | sb->s_fs_info = NULL; | 1345 | sb->s_fs_info = NULL; |
1345 | |||
1346 | pohmelfs_ftrans_exit(); | ||
1347 | } | ||
1348 | |||
1349 | static int pohmelfs_remount(struct super_block *sb, int *flags, char *data) | ||
1350 | { | ||
1351 | *flags |= MS_RDONLY; | ||
1352 | return 0; | ||
1353 | } | 1346 | } |
1354 | 1347 | ||
1355 | static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 1348 | static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
@@ -1394,42 +1387,33 @@ static int pohmelfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
1394 | return 0; | 1387 | return 0; |
1395 | } | 1388 | } |
1396 | 1389 | ||
1397 | static const struct super_operations pohmelfs_sb_ops = { | ||
1398 | .alloc_inode = pohmelfs_alloc_inode, | ||
1399 | .destroy_inode = pohmelfs_destroy_inode, | ||
1400 | .drop_inode = pohmelfs_drop_inode, | ||
1401 | .write_inode = pohmelfs_write_inode, | ||
1402 | .put_super = pohmelfs_put_super, | ||
1403 | .remount_fs = pohmelfs_remount, | ||
1404 | .statfs = pohmelfs_statfs, | ||
1405 | .show_options = pohmelfs_show_options, | ||
1406 | }; | ||
1407 | |||
1408 | enum { | 1390 | enum { |
1409 | pohmelfs_opt_idx, | 1391 | pohmelfs_opt_idx, |
1392 | pohmelfs_opt_crypto_thread_num, | ||
1393 | pohmelfs_opt_trans_max_pages, | ||
1394 | pohmelfs_opt_crypto_fail_unsupported, | ||
1395 | |||
1396 | /* Remountable options */ | ||
1410 | pohmelfs_opt_trans_scan_timeout, | 1397 | pohmelfs_opt_trans_scan_timeout, |
1411 | pohmelfs_opt_drop_scan_timeout, | 1398 | pohmelfs_opt_drop_scan_timeout, |
1412 | pohmelfs_opt_wait_on_page_timeout, | 1399 | pohmelfs_opt_wait_on_page_timeout, |
1413 | pohmelfs_opt_trans_retries, | 1400 | pohmelfs_opt_trans_retries, |
1414 | pohmelfs_opt_crypto_thread_num, | ||
1415 | pohmelfs_opt_trans_max_pages, | ||
1416 | pohmelfs_opt_crypto_fail_unsupported, | ||
1417 | pohmelfs_opt_mcache_timeout, | 1401 | pohmelfs_opt_mcache_timeout, |
1418 | }; | 1402 | }; |
1419 | 1403 | ||
1420 | static struct match_token pohmelfs_tokens[] = { | 1404 | static struct match_token pohmelfs_tokens[] = { |
1421 | {pohmelfs_opt_idx, "idx=%u"}, | 1405 | {pohmelfs_opt_idx, "idx=%u"}, |
1406 | {pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"}, | ||
1407 | {pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"}, | ||
1408 | {pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"}, | ||
1422 | {pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"}, | 1409 | {pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"}, |
1423 | {pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"}, | 1410 | {pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"}, |
1424 | {pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"}, | 1411 | {pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"}, |
1425 | {pohmelfs_opt_trans_retries, "trans_retries=%u"}, | 1412 | {pohmelfs_opt_trans_retries, "trans_retries=%u"}, |
1426 | {pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"}, | ||
1427 | {pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"}, | ||
1428 | {pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"}, | ||
1429 | {pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"}, | 1413 | {pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"}, |
1430 | }; | 1414 | }; |
1431 | 1415 | ||
1432 | static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb) | 1416 | static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb, int remount) |
1433 | { | 1417 | { |
1434 | char *p; | 1418 | char *p; |
1435 | substring_t args[MAX_OPT_ARGS]; | 1419 | substring_t args[MAX_OPT_ARGS]; |
@@ -1449,6 +1433,9 @@ static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb) | |||
1449 | if (err) | 1433 | if (err) |
1450 | return err; | 1434 | return err; |
1451 | 1435 | ||
1436 | if (remount && token <= pohmelfs_opt_crypto_fail_unsupported) | ||
1437 | continue; | ||
1438 | |||
1452 | switch (token) { | 1439 | switch (token) { |
1453 | case pohmelfs_opt_idx: | 1440 | case pohmelfs_opt_idx: |
1454 | psb->idx = option; | 1441 | psb->idx = option; |
@@ -1485,6 +1472,25 @@ static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb) | |||
1485 | return 0; | 1472 | return 0; |
1486 | } | 1473 | } |
1487 | 1474 | ||
1475 | static int pohmelfs_remount(struct super_block *sb, int *flags, char *data) | ||
1476 | { | ||
1477 | int err; | ||
1478 | struct pohmelfs_sb *psb = POHMELFS_SB(sb); | ||
1479 | unsigned long old_sb_flags = sb->s_flags; | ||
1480 | |||
1481 | err = pohmelfs_parse_options(data, psb, 1); | ||
1482 | if (err) | ||
1483 | goto err_out_restore; | ||
1484 | |||
1485 | if (!(*flags & MS_RDONLY)) | ||
1486 | sb->s_flags &= ~MS_RDONLY; | ||
1487 | return 0; | ||
1488 | |||
1489 | err_out_restore: | ||
1490 | sb->s_flags = old_sb_flags; | ||
1491 | return err; | ||
1492 | } | ||
1493 | |||
1488 | static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count) | 1494 | static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count) |
1489 | { | 1495 | { |
1490 | struct inode *inode = &pi->vfs_inode; | 1496 | struct inode *inode = &pi->vfs_inode; |
@@ -1753,6 +1759,57 @@ err_out_exit: | |||
1753 | return err; | 1759 | return err; |
1754 | } | 1760 | } |
1755 | 1761 | ||
1762 | static int pohmelfs_show_stats(struct seq_file *m, struct vfsmount *mnt) | ||
1763 | { | ||
1764 | struct netfs_state *st; | ||
1765 | struct pohmelfs_ctl *ctl; | ||
1766 | struct pohmelfs_sb *psb = POHMELFS_SB(mnt->mnt_sb); | ||
1767 | struct pohmelfs_config *c; | ||
1768 | |||
1769 | mutex_lock(&psb->state_lock); | ||
1770 | |||
1771 | seq_printf(m, "\nidx addr(:port) socket_type protocol active priority permissions\n"); | ||
1772 | |||
1773 | list_for_each_entry(c, &psb->state_list, config_entry) { | ||
1774 | st = &c->state; | ||
1775 | ctl = &st->ctl; | ||
1776 | |||
1777 | seq_printf(m, "%u ", ctl->idx); | ||
1778 | if (ctl->addr.sa_family == AF_INET) { | ||
1779 | struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr; | ||
1780 | //seq_printf(m, "%pi4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port)); | ||
1781 | seq_printf(m, "%u.%u.%u.%u:%u", NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); | ||
1782 | } else if (ctl->addr.sa_family == AF_INET6) { | ||
1783 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr; | ||
1784 | seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port)); | ||
1785 | } else { | ||
1786 | unsigned int i; | ||
1787 | for (i=0; i<ctl->addrlen; ++i) | ||
1788 | seq_printf(m, "%02x.", ctl->addr.addr[i]); | ||
1789 | } | ||
1790 | |||
1791 | seq_printf(m, " %u %u %d %u %x\n", | ||
1792 | ctl->type, ctl->proto, | ||
1793 | st->socket != NULL, | ||
1794 | ctl->prio, ctl->perm); | ||
1795 | } | ||
1796 | mutex_unlock(&psb->state_lock); | ||
1797 | |||
1798 | return 0; | ||
1799 | } | ||
1800 | |||
1801 | static const struct super_operations pohmelfs_sb_ops = { | ||
1802 | .alloc_inode = pohmelfs_alloc_inode, | ||
1803 | .destroy_inode = pohmelfs_destroy_inode, | ||
1804 | .drop_inode = pohmelfs_drop_inode, | ||
1805 | .write_inode = pohmelfs_write_inode, | ||
1806 | .put_super = pohmelfs_put_super, | ||
1807 | .remount_fs = pohmelfs_remount, | ||
1808 | .statfs = pohmelfs_statfs, | ||
1809 | .show_options = pohmelfs_show_options, | ||
1810 | .show_stats = pohmelfs_show_stats, | ||
1811 | }; | ||
1812 | |||
1756 | /* | 1813 | /* |
1757 | * Allocate private superblock and create root dir. | 1814 | * Allocate private superblock and create root dir. |
1758 | */ | 1815 | */ |
@@ -1764,8 +1821,6 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1764 | struct pohmelfs_inode *npi; | 1821 | struct pohmelfs_inode *npi; |
1765 | struct qstr str; | 1822 | struct qstr str; |
1766 | 1823 | ||
1767 | pohmelfs_ftrans_init(); | ||
1768 | |||
1769 | psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL); | 1824 | psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL); |
1770 | if (!psb) | 1825 | if (!psb) |
1771 | goto err_out_exit; | 1826 | goto err_out_exit; |
@@ -1816,7 +1871,7 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1816 | mutex_init(&psb->state_lock); | 1871 | mutex_init(&psb->state_lock); |
1817 | INIT_LIST_HEAD(&psb->state_list); | 1872 | INIT_LIST_HEAD(&psb->state_list); |
1818 | 1873 | ||
1819 | err = pohmelfs_parse_options((char *) data, psb); | 1874 | err = pohmelfs_parse_options((char *) data, psb, 0); |
1820 | if (err) | 1875 | if (err) |
1821 | goto err_out_free_sb; | 1876 | goto err_out_free_sb; |
1822 | 1877 | ||
@@ -1845,6 +1900,8 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1845 | err = PTR_ERR(npi); | 1900 | err = PTR_ERR(npi); |
1846 | goto err_out_crypto_exit; | 1901 | goto err_out_crypto_exit; |
1847 | } | 1902 | } |
1903 | set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state); | ||
1904 | clear_bit(NETFS_INODE_OWNED, &npi->state); | ||
1848 | 1905 | ||
1849 | root = &npi->vfs_inode; | 1906 | root = &npi->vfs_inode; |
1850 | 1907 | ||
@@ -1887,11 +1944,29 @@ static int pohmelfs_get_sb(struct file_system_type *fs_type, | |||
1887 | mnt); | 1944 | mnt); |
1888 | } | 1945 | } |
1889 | 1946 | ||
1947 | /* | ||
1948 | * We need this to sync all inodes earlier, since when writeback | ||
1949 | * is invoked from the umount/mntput path dcache is already shrunk, | ||
1950 | * see generic_shutdown_super(), and no inodes can access the path. | ||
1951 | */ | ||
1952 | static void pohmelfs_kill_super(struct super_block *sb) | ||
1953 | { | ||
1954 | struct writeback_control wbc = { | ||
1955 | .sync_mode = WB_SYNC_ALL, | ||
1956 | .range_start = 0, | ||
1957 | .range_end = LLONG_MAX, | ||
1958 | .nr_to_write = LONG_MAX, | ||
1959 | }; | ||
1960 | generic_sync_sb_inodes(sb, &wbc); | ||
1961 | |||
1962 | kill_anon_super(sb); | ||
1963 | } | ||
1964 | |||
1890 | static struct file_system_type pohmel_fs_type = { | 1965 | static struct file_system_type pohmel_fs_type = { |
1891 | .owner = THIS_MODULE, | 1966 | .owner = THIS_MODULE, |
1892 | .name = "pohmel", | 1967 | .name = "pohmel", |
1893 | .get_sb = pohmelfs_get_sb, | 1968 | .get_sb = pohmelfs_get_sb, |
1894 | .kill_sb = kill_anon_super, | 1969 | .kill_sb = pohmelfs_kill_super, |
1895 | }; | 1970 | }; |
1896 | 1971 | ||
1897 | /* | 1972 | /* |
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c index ad4a18559bdd..22fef18cae90 100644 --- a/drivers/staging/pohmelfs/lock.c +++ b/drivers/staging/pohmelfs/lock.c | |||
@@ -41,7 +41,8 @@ static int pohmelfs_send_lock_trans(struct pohmelfs_inode *pi, | |||
41 | path_len = err; | 41 | path_len = err; |
42 | 42 | ||
43 | err = -ENOMEM; | 43 | err = -ENOMEM; |
44 | t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize, 0, 0); | 44 | t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize, |
45 | NETFS_TRANS_SINGLE_DST, 0); | ||
45 | if (!t) | 46 | if (!t) |
46 | goto err_out_exit; | 47 | goto err_out_exit; |
47 | 48 | ||
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c index c9b8540c1efe..11ecac026ca7 100644 --- a/drivers/staging/pohmelfs/net.c +++ b/drivers/staging/pohmelfs/net.c | |||
@@ -26,55 +26,6 @@ | |||
26 | 26 | ||
27 | #include "netfs.h" | 27 | #include "netfs.h" |
28 | 28 | ||
29 | static int pohmelfs_ftrans_size = 10240; | ||
30 | static u32 *pohmelfs_ftrans; | ||
31 | |||
32 | int pohmelfs_ftrans_init(void) | ||
33 | { | ||
34 | pohmelfs_ftrans = vmalloc(pohmelfs_ftrans_size * 4); | ||
35 | if (!pohmelfs_ftrans) | ||
36 | return -ENOMEM; | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | void pohmelfs_ftrans_exit(void) | ||
42 | { | ||
43 | vfree(pohmelfs_ftrans); | ||
44 | } | ||
45 | |||
46 | void pohmelfs_ftrans_clean(u64 id) | ||
47 | { | ||
48 | if (pohmelfs_ftrans) { | ||
49 | u32 i = id & 0xffffffff; | ||
50 | int idx = i % pohmelfs_ftrans_size; | ||
51 | |||
52 | pohmelfs_ftrans[idx] = 0; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | void pohmelfs_ftrans_update(u64 id) | ||
57 | { | ||
58 | if (pohmelfs_ftrans) { | ||
59 | u32 i = id & 0xffffffff; | ||
60 | int idx = i % pohmelfs_ftrans_size; | ||
61 | |||
62 | pohmelfs_ftrans[idx] = i; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | int pohmelfs_ftrans_check(u64 id) | ||
67 | { | ||
68 | if (pohmelfs_ftrans) { | ||
69 | u32 i = id & 0xffffffff; | ||
70 | int idx = i % pohmelfs_ftrans_size; | ||
71 | |||
72 | return (pohmelfs_ftrans[idx] == i); | ||
73 | } | ||
74 | |||
75 | return -1; | ||
76 | } | ||
77 | |||
78 | /* | 29 | /* |
79 | * Async machinery lives here. | 30 | * Async machinery lives here. |
80 | * All commands being sent to server do _not_ require sync reply, | 31 | * All commands being sent to server do _not_ require sync reply, |
@@ -450,8 +401,24 @@ static int pohmelfs_readdir_response(struct netfs_state *st) | |||
450 | if (err != -EEXIST) | 401 | if (err != -EEXIST) |
451 | goto err_out_put; | 402 | goto err_out_put; |
452 | } else { | 403 | } else { |
404 | struct dentry *dentry, *alias, *pd; | ||
405 | |||
453 | set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state); | 406 | set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state); |
454 | clear_bit(NETFS_INODE_OWNED, &npi->state); | 407 | clear_bit(NETFS_INODE_OWNED, &npi->state); |
408 | |||
409 | pd = d_find_alias(&parent->vfs_inode); | ||
410 | if (pd) { | ||
411 | str.hash = full_name_hash(str.name, str.len); | ||
412 | dentry = d_alloc(pd, &str); | ||
413 | if (dentry) { | ||
414 | alias = d_materialise_unique(dentry, &npi->vfs_inode); | ||
415 | if (alias) | ||
416 | dput(dentry); | ||
417 | } | ||
418 | |||
419 | dput(dentry); | ||
420 | dput(pd); | ||
421 | } | ||
455 | } | 422 | } |
456 | } | 423 | } |
457 | out: | 424 | out: |
@@ -638,15 +605,12 @@ static int pohmelfs_transaction_response(struct netfs_state *st) | |||
638 | if (dst) { | 605 | if (dst) { |
639 | netfs_trans_remove_nolock(dst, st); | 606 | netfs_trans_remove_nolock(dst, st); |
640 | t = dst->trans; | 607 | t = dst->trans; |
641 | |||
642 | pohmelfs_ftrans_update(cmd->start); | ||
643 | } | 608 | } |
644 | mutex_unlock(&st->trans_lock); | 609 | mutex_unlock(&st->trans_lock); |
645 | 610 | ||
646 | if (!t) { | 611 | if (!t) { |
647 | int check = pohmelfs_ftrans_check(cmd->start); | 612 | printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u.\n", |
648 | printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u, double: %d.\n", | 613 | __func__, cmd->start, cmd->id, cmd->size, cmd->ext); |
649 | __func__, cmd->start, cmd->id, cmd->size, cmd->ext, check); | ||
650 | err = -EINVAL; | 614 | err = -EINVAL; |
651 | goto out; | 615 | goto out; |
652 | } | 616 | } |
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h index 2ff21ae5bb12..c78cfcb042fb 100644 --- a/drivers/staging/pohmelfs/netfs.h +++ b/drivers/staging/pohmelfs/netfs.h | |||
@@ -87,6 +87,7 @@ enum { | |||
87 | POHMELFS_FLAGS_DEL, /* Network state control message for DEL */ | 87 | POHMELFS_FLAGS_DEL, /* Network state control message for DEL */ |
88 | POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ | 88 | POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ |
89 | POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ | 89 | POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ |
90 | POHMELFS_FLAGS_MODIFY, /* Network state modification message */ | ||
90 | }; | 91 | }; |
91 | 92 | ||
92 | /* | 93 | /* |
@@ -116,16 +117,20 @@ struct pohmelfs_crypto | |||
116 | unsigned char data[0]; /* Algorithm string, key and IV */ | 117 | unsigned char data[0]; /* Algorithm string, key and IV */ |
117 | }; | 118 | }; |
118 | 119 | ||
120 | #define POHMELFS_IO_PERM_READ (1<<0) | ||
121 | #define POHMELFS_IO_PERM_WRITE (1<<1) | ||
122 | |||
119 | /* | 123 | /* |
120 | * Configuration command used to create table of different remote servers. | 124 | * Configuration command used to create table of different remote servers. |
121 | */ | 125 | */ |
122 | struct pohmelfs_ctl | 126 | struct pohmelfs_ctl |
123 | { | 127 | { |
124 | unsigned int idx; /* Config index */ | 128 | __u32 idx; /* Config index */ |
125 | unsigned int type; /* Socket type */ | 129 | __u32 type; /* Socket type */ |
126 | unsigned int proto; /* Socket protocol */ | 130 | __u32 proto; /* Socket protocol */ |
127 | unsigned int addrlen; /* Size of the address */ | 131 | __u16 addrlen; /* Size of the address */ |
128 | unsigned short unused; /* Align structure by 4 bytes */ | 132 | __u16 perm; /* IO permission */ |
133 | __u16 prio; /* IO priority */ | ||
129 | struct saddr addr; /* Remote server address */ | 134 | struct saddr addr; /* Remote server address */ |
130 | }; | 135 | }; |
131 | 136 | ||
@@ -921,12 +926,6 @@ static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb, | |||
921 | pohmelfs_mcache_free(psb, m); | 926 | pohmelfs_mcache_free(psb, m); |
922 | } | 927 | } |
923 | 928 | ||
924 | int pohmelfs_ftrans_init(void); | ||
925 | void pohmelfs_ftrans_exit(void); | ||
926 | void pohmelfs_ftrans_update(u64 id); | ||
927 | int pohmelfs_ftrans_check(u64 id); | ||
928 | void pohmelfs_ftrans_clean(u64 id); | ||
929 | |||
930 | #endif /* __KERNEL__*/ | 929 | #endif /* __KERNEL__*/ |
931 | 930 | ||
932 | #endif /* __NETFS_H */ | 931 | #endif /* __NETFS_H */ |
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c index bcb59425a21c..fef5f9bd6920 100644 --- a/drivers/staging/pohmelfs/trans.c +++ b/drivers/staging/pohmelfs/trans.c | |||
@@ -456,34 +456,25 @@ int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb) | |||
456 | __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state); | 456 | __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state); |
457 | #endif | 457 | #endif |
458 | mutex_lock(&psb->state_lock); | 458 | mutex_lock(&psb->state_lock); |
459 | list_for_each_entry(c, &psb->state_list, config_entry) { | ||
460 | st = &c->state; | ||
459 | 461 | ||
460 | if ((t->flags & NETFS_TRANS_SINGLE_DST) && psb->active_state) { | 462 | if (t->flags & NETFS_TRANS_SINGLE_DST) { |
461 | st = &psb->active_state->state; | 463 | if (!(st->ctl.perm & POHMELFS_IO_PERM_READ)) |
462 | 464 | continue; | |
463 | err = -EPIPE; | 465 | } else { |
464 | if (netfs_state_poll(st) & POLLOUT) { | 466 | if (!(st->ctl.perm & POHMELFS_IO_PERM_WRITE)) |
465 | err = netfs_trans_push_dst(t, st); | 467 | continue; |
466 | if (!err) { | ||
467 | err = netfs_trans_send(t, st); | ||
468 | if (err) { | ||
469 | netfs_trans_drop_last(t, st); | ||
470 | } else { | ||
471 | pohmelfs_switch_active(psb); | ||
472 | goto out; | ||
473 | } | ||
474 | } | ||
475 | } | 468 | } |
476 | pohmelfs_switch_active(psb); | ||
477 | } | ||
478 | 469 | ||
479 | list_for_each_entry(c, &psb->state_list, config_entry) { | 470 | if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio)) |
480 | st = &c->state; | 471 | st = &psb->active_state->state; |
481 | 472 | ||
482 | err = netfs_trans_push(t, st); | 473 | err = netfs_trans_push(t, st); |
483 | if (!err && (t->flags & NETFS_TRANS_SINGLE_DST)) | 474 | if (!err && (t->flags & NETFS_TRANS_SINGLE_DST)) |
484 | break; | 475 | break; |
485 | } | 476 | } |
486 | out: | 477 | |
487 | mutex_unlock(&psb->state_lock); | 478 | mutex_unlock(&psb->state_lock); |
488 | #if 0 | 479 | #if 0 |
489 | dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n", | 480 | dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n", |
@@ -501,8 +492,6 @@ int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb) | |||
501 | 492 | ||
502 | t->gen = atomic_inc_return(&psb->trans_gen); | 493 | t->gen = atomic_inc_return(&psb->trans_gen); |
503 | 494 | ||
504 | pohmelfs_ftrans_clean(t->gen); | ||
505 | |||
506 | cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) + | 495 | cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) + |
507 | t->attached_size + t->attached_pages * sizeof(struct netfs_cmd); | 496 | t->attached_size + t->attached_pages * sizeof(struct netfs_cmd); |
508 | cmd->cmd = NETFS_TRANS; | 497 | cmd->cmd = NETFS_TRANS; |
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c index cf17bcdd7333..6c4396f0903b 100644 --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c | |||
@@ -722,6 +722,20 @@ err: | |||
722 | return (-1); | 722 | return (-1); |
723 | } /* End of rt28xx_open */ | 723 | } /* End of rt28xx_open */ |
724 | 724 | ||
725 | static const struct net_device_ops rt2860_netdev_ops = { | ||
726 | .ndo_open = MainVirtualIF_open, | ||
727 | .ndo_stop = MainVirtualIF_close, | ||
728 | .ndo_do_ioctl = rt28xx_ioctl, | ||
729 | .ndo_get_stats = RT28xx_get_ether_stats, | ||
730 | .ndo_validate_addr = NULL, | ||
731 | .ndo_set_mac_address = eth_mac_addr, | ||
732 | .ndo_change_mtu = eth_change_mtu, | ||
733 | #ifdef IKANOS_VX_1X0 | ||
734 | .ndo_start_xmit = IKANOS_DataFramesTx, | ||
735 | #else | ||
736 | .ndo_start_xmit = rt28xx_send_packets, | ||
737 | #endif | ||
738 | }; | ||
725 | 739 | ||
726 | /* Must not be called for mdev and apdev */ | 740 | /* Must not be called for mdev and apdev */ |
727 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) | 741 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) |
@@ -733,11 +747,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
733 | 747 | ||
734 | 748 | ||
735 | //ether_setup(dev); | 749 | //ether_setup(dev); |
736 | dev->hard_start_xmit = rt28xx_send_packets; | ||
737 | |||
738 | #ifdef IKANOS_VX_1X0 | ||
739 | dev->hard_start_xmit = IKANOS_DataFramesTx; | ||
740 | #endif // IKANOS_VX_1X0 // | ||
741 | 750 | ||
742 | #ifdef CONFIG_STA_SUPPORT | 751 | #ifdef CONFIG_STA_SUPPORT |
743 | #if WIRELESS_EXT >= 12 | 752 | #if WIRELESS_EXT >= 12 |
@@ -760,12 +769,8 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
760 | #if WIRELESS_EXT < 21 | 769 | #if WIRELESS_EXT < 21 |
761 | dev->get_wireless_stats = rt28xx_get_wireless_stats; | 770 | dev->get_wireless_stats = rt28xx_get_wireless_stats; |
762 | #endif | 771 | #endif |
763 | dev->get_stats = RT28xx_get_ether_stats; | ||
764 | dev->open = MainVirtualIF_open; //rt28xx_open; | ||
765 | dev->stop = MainVirtualIF_close; //rt28xx_close; | ||
766 | dev->priv_flags = INT_MAIN; | 772 | dev->priv_flags = INT_MAIN; |
767 | dev->do_ioctl = rt28xx_ioctl; | 773 | dev->netdev_ops = &rt2860_netdev_ops; |
768 | dev->validate_addr = NULL; | ||
769 | // find available device name | 774 | // find available device name |
770 | for (i = 0; i < 8; i++) | 775 | for (i = 0; i < 8; i++) |
771 | { | 776 | { |
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h index 5dd15aac9ce7..a42caa370808 100644 --- a/drivers/staging/rt2870/rt2870.h +++ b/drivers/staging/rt2870/rt2870.h | |||
@@ -96,6 +96,7 @@ | |||
96 | {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ \ | 96 | {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ \ |
97 | {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \ | 97 | {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \ |
98 | {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \ | 98 | {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \ |
99 | {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */ \ | ||
99 | {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \ | 100 | {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \ |
100 | {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \ | 101 | {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \ |
101 | {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \ | 102 | {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \ |
diff --git a/drivers/staging/rt2870/rt_main_dev.c b/drivers/staging/rt2870/rt_main_dev.c index 313ecea0bfa8..48ad41136d0f 100644 --- a/drivers/staging/rt2870/rt_main_dev.c +++ b/drivers/staging/rt2870/rt_main_dev.c | |||
@@ -855,6 +855,20 @@ err: | |||
855 | return (-1); | 855 | return (-1); |
856 | } /* End of rt28xx_open */ | 856 | } /* End of rt28xx_open */ |
857 | 857 | ||
858 | static const struct net_device_ops rt2870_netdev_ops = { | ||
859 | .ndo_open = MainVirtualIF_open, | ||
860 | .ndo_stop = MainVirtualIF_close, | ||
861 | .ndo_do_ioctl = rt28xx_ioctl, | ||
862 | .ndo_get_stats = RT28xx_get_ether_stats, | ||
863 | .ndo_validate_addr = NULL, | ||
864 | .ndo_set_mac_address = eth_mac_addr, | ||
865 | .ndo_change_mtu = eth_change_mtu, | ||
866 | #ifdef IKANOS_VX_1X0 | ||
867 | .ndo_start_xmit = IKANOS_DataFramesTx, | ||
868 | #else | ||
869 | .ndo_start_xmit = rt28xx_send_packets, | ||
870 | #endif | ||
871 | }; | ||
858 | 872 | ||
859 | /* Must not be called for mdev and apdev */ | 873 | /* Must not be called for mdev and apdev */ |
860 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) | 874 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) |
@@ -866,12 +880,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
866 | 880 | ||
867 | 881 | ||
868 | //ether_setup(dev); | 882 | //ether_setup(dev); |
869 | dev->hard_start_xmit = rt28xx_send_packets; | ||
870 | |||
871 | #ifdef IKANOS_VX_1X0 | ||
872 | dev->hard_start_xmit = IKANOS_DataFramesTx; | ||
873 | #endif // IKANOS_VX_1X0 // | ||
874 | |||
875 | // dev->set_multicast_list = ieee80211_set_multicast_list; | 883 | // dev->set_multicast_list = ieee80211_set_multicast_list; |
876 | // dev->change_mtu = ieee80211_change_mtu; | 884 | // dev->change_mtu = ieee80211_change_mtu; |
877 | #ifdef CONFIG_STA_SUPPORT | 885 | #ifdef CONFIG_STA_SUPPORT |
@@ -895,16 +903,10 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
895 | #if WIRELESS_EXT < 21 | 903 | #if WIRELESS_EXT < 21 |
896 | dev->get_wireless_stats = rt28xx_get_wireless_stats; | 904 | dev->get_wireless_stats = rt28xx_get_wireless_stats; |
897 | #endif | 905 | #endif |
898 | dev->get_stats = RT28xx_get_ether_stats; | ||
899 | dev->open = MainVirtualIF_open; //rt28xx_open; | ||
900 | dev->stop = MainVirtualIF_close; //rt28xx_close; | ||
901 | // dev->uninit = ieee80211_if_reinit; | 906 | // dev->uninit = ieee80211_if_reinit; |
902 | // dev->destructor = ieee80211_if_free; | 907 | // dev->destructor = ieee80211_if_free; |
903 | dev->priv_flags = INT_MAIN; | 908 | dev->priv_flags = INT_MAIN; |
904 | dev->do_ioctl = rt28xx_ioctl; | 909 | dev->netdev_ops = &rt2870_netdev_ops; |
905 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) | ||
906 | dev->validate_addr = NULL; | ||
907 | #endif | ||
908 | // find available device name | 910 | // find available device name |
909 | for (i = 0; i < 8; i++) | 911 | for (i = 0; i < 8; i++) |
910 | { | 912 | { |
diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c index c000646286e6..81f769cf1096 100644 --- a/drivers/staging/rt3070/rt_main_dev.c +++ b/drivers/staging/rt3070/rt_main_dev.c | |||
@@ -436,7 +436,6 @@ static int rt28xx_init(IN struct net_device *net_dev) | |||
436 | // OID_SET_HT_PHYMODE SetHT; | 436 | // OID_SET_HT_PHYMODE SetHT; |
437 | // WPDMA_GLO_CFG_STRUC GloCfg; | 437 | // WPDMA_GLO_CFG_STRUC GloCfg; |
438 | UINT32 MacCsr0 = 0; | 438 | UINT32 MacCsr0 = 0; |
439 | UINT32 MacValue = 0; | ||
440 | 439 | ||
441 | #ifdef RT2870 | 440 | #ifdef RT2870 |
442 | #ifdef INF_AMAZON_SE | 441 | #ifdef INF_AMAZON_SE |
@@ -849,6 +848,20 @@ err: | |||
849 | return (-1); | 848 | return (-1); |
850 | } /* End of rt28xx_open */ | 849 | } /* End of rt28xx_open */ |
851 | 850 | ||
851 | static const struct net_device_ops rt3070_netdev_ops = { | ||
852 | .ndo_open = MainVirtualIF_open, | ||
853 | .ndo_stop = MainVirtualIF_close, | ||
854 | .ndo_do_ioctl = rt28xx_ioctl, | ||
855 | .ndo_get_stats = RT28xx_get_ether_stats, | ||
856 | .ndo_validate_addr = NULL, | ||
857 | .ndo_set_mac_address = eth_mac_addr, | ||
858 | .ndo_change_mtu = eth_change_mtu, | ||
859 | #ifdef IKANOS_VX_1X0 | ||
860 | .ndo_start_xmit = IKANOS_DataFramesTx, | ||
861 | #else | ||
862 | .ndo_start_xmit = rt28xx_send_packets, | ||
863 | #endif | ||
864 | }; | ||
852 | 865 | ||
853 | /* Must not be called for mdev and apdev */ | 866 | /* Must not be called for mdev and apdev */ |
854 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) | 867 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) |
@@ -860,12 +873,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
860 | 873 | ||
861 | 874 | ||
862 | //ether_setup(dev); | 875 | //ether_setup(dev); |
863 | dev->hard_start_xmit = rt28xx_send_packets; | ||
864 | |||
865 | #ifdef IKANOS_VX_1X0 | ||
866 | dev->hard_start_xmit = IKANOS_DataFramesTx; | ||
867 | #endif // IKANOS_VX_1X0 // | ||
868 | |||
869 | // dev->set_multicast_list = ieee80211_set_multicast_list; | 876 | // dev->set_multicast_list = ieee80211_set_multicast_list; |
870 | // dev->change_mtu = ieee80211_change_mtu; | 877 | // dev->change_mtu = ieee80211_change_mtu; |
871 | #ifdef CONFIG_STA_SUPPORT | 878 | #ifdef CONFIG_STA_SUPPORT |
@@ -889,16 +896,10 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
889 | #if WIRELESS_EXT < 21 | 896 | #if WIRELESS_EXT < 21 |
890 | dev->get_wireless_stats = rt28xx_get_wireless_stats; | 897 | dev->get_wireless_stats = rt28xx_get_wireless_stats; |
891 | #endif | 898 | #endif |
892 | dev->get_stats = RT28xx_get_ether_stats; | ||
893 | dev->open = MainVirtualIF_open; //rt28xx_open; | ||
894 | dev->stop = MainVirtualIF_close; //rt28xx_close; | ||
895 | // dev->uninit = ieee80211_if_reinit; | 899 | // dev->uninit = ieee80211_if_reinit; |
896 | // dev->destructor = ieee80211_if_free; | 900 | // dev->destructor = ieee80211_if_free; |
897 | dev->priv_flags = INT_MAIN; | 901 | dev->priv_flags = INT_MAIN; |
898 | dev->do_ioctl = rt28xx_ioctl; | 902 | dev->netdev_ops = &rt3070_netdev_ops; |
899 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) | ||
900 | dev->validate_addr = NULL; | ||
901 | #endif | ||
902 | // find available device name | 903 | // find available device name |
903 | for (i = 0; i < 8; i++) | 904 | for (i = 0; i < 8; i++) |
904 | { | 905 | { |
diff --git a/drivers/staging/slicoss/README b/drivers/staging/slicoss/README index 2d5b1127ce51..70f49099c065 100644 --- a/drivers/staging/slicoss/README +++ b/drivers/staging/slicoss/README | |||
@@ -10,7 +10,36 @@ TODO: | |||
10 | - move firmware loading to request_firmware() | 10 | - move firmware loading to request_firmware() |
11 | - remove direct memory access of structures | 11 | - remove direct memory access of structures |
12 | - any remaining sparse and checkpatch.pl warnings | 12 | - any remaining sparse and checkpatch.pl warnings |
13 | - any netdev recommended changes | 13 | |
14 | - use net_device_ops | ||
15 | - use dev->stats rather than adapter->stats | ||
16 | - don't cast netdev_priv it is already void | ||
17 | - use compare_ether_addr | ||
18 | - GET RID OF MACROS | ||
19 | - work on all architectures | ||
20 | - without CONFIG_X86_64 confusion | ||
21 | - do 64 bit correctly | ||
22 | - don't depend on order of union | ||
23 | - get rid of ASSERT(), use BUG() instead but only where necessary | ||
24 | looks like most aren't really useful | ||
25 | - no new SIOCDEVPRIVATE ioctl allowed | ||
26 | - don't use module_param for configuring interrupt mitigation | ||
27 | use ethtool instead | ||
28 | - reorder code to elminate use of forward declarations | ||
29 | - don't keep private linked list of drivers. | ||
30 | - remove all the gratiutous debug infrastructure | ||
31 | - use PCI_DEVICE() | ||
32 | - do ethtool correctly using ethtool_ops | ||
33 | - NAPI? | ||
34 | - wasted overhead of extra stats | ||
35 | - state variables for things that are | ||
36 | easily availble and shouldn't be kept in card structure, cardnum, ... | ||
37 | slotnumber, events, ... | ||
38 | - get rid of slic_spinlock wrapper | ||
39 | - volatile == bad design => bad code | ||
40 | - locking too fine grained, not designed just throw more locks | ||
41 | at problem | ||
42 | |||
14 | 43 | ||
15 | Please send patches to: | 44 | Please send patches to: |
16 | Greg Kroah-Hartman <gregkh@suse.de> | 45 | Greg Kroah-Hartman <gregkh@suse.de> |
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 948156348478..6f5d0bff4358 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c | |||
@@ -345,6 +345,19 @@ static void slic_init_adapter(struct net_device *netdev, | |||
345 | return; | 345 | return; |
346 | } | 346 | } |
347 | 347 | ||
348 | static const struct net_device_ops slic_netdev_ops = { | ||
349 | .ndo_open = slic_entry_open, | ||
350 | .ndo_stop = slic_entry_halt, | ||
351 | .ndo_start_xmit = slic_xmit_start, | ||
352 | .ndo_do_ioctl = slic_ioctl, | ||
353 | .ndo_set_mac_address = slic_mac_set_address, | ||
354 | .ndo_get_stats = slic_get_stats, | ||
355 | .ndo_set_multicast_list = slic_mcast_set_list, | ||
356 | .ndo_validate_addr = eth_validate_addr, | ||
357 | .ndo_set_mac_address = eth_mac_addr, | ||
358 | .ndo_change_mtu = eth_change_mtu, | ||
359 | }; | ||
360 | |||
348 | static int __devinit slic_entry_probe(struct pci_dev *pcidev, | 361 | static int __devinit slic_entry_probe(struct pci_dev *pcidev, |
349 | const struct pci_device_id *pci_tbl_entry) | 362 | const struct pci_device_id *pci_tbl_entry) |
350 | { | 363 | { |
@@ -442,13 +455,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev, | |||
442 | 455 | ||
443 | netdev->base_addr = (unsigned long)adapter->memorybase; | 456 | netdev->base_addr = (unsigned long)adapter->memorybase; |
444 | netdev->irq = adapter->irq; | 457 | netdev->irq = adapter->irq; |
445 | netdev->open = slic_entry_open; | 458 | netdev->netdev_ops = &slic_netdev_ops; |
446 | netdev->stop = slic_entry_halt; | ||
447 | netdev->hard_start_xmit = slic_xmit_start; | ||
448 | netdev->do_ioctl = slic_ioctl; | ||
449 | netdev->set_mac_address = slic_mac_set_address; | ||
450 | netdev->get_stats = slic_get_stats; | ||
451 | netdev->set_multicast_list = slic_mcast_set_list; | ||
452 | 459 | ||
453 | slic_debug_adapter_create(adapter); | 460 | slic_debug_adapter_create(adapter); |
454 | 461 | ||
@@ -1260,7 +1267,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address) | |||
1260 | } | 1267 | } |
1261 | 1268 | ||
1262 | /* Doesn't already exist. Allocate a structure to hold it */ | 1269 | /* Doesn't already exist. Allocate a structure to hold it */ |
1263 | mcaddr = kmalloc(sizeof(struct mcast_address), GFP_KERNEL); | 1270 | mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC); |
1264 | if (mcaddr == NULL) | 1271 | if (mcaddr == NULL) |
1265 | return 1; | 1272 | return 1; |
1266 | 1273 | ||
@@ -2284,7 +2291,7 @@ static u32 slic_card_locate(struct adapter *adapter) | |||
2284 | } | 2291 | } |
2285 | if (!physcard) { | 2292 | if (!physcard) { |
2286 | /* no structure allocated for this physical card yet */ | 2293 | /* no structure allocated for this physical card yet */ |
2287 | physcard = kzalloc(sizeof(struct physcard), GFP_KERNEL); | 2294 | physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC); |
2288 | ASSERT(physcard); | 2295 | ASSERT(physcard); |
2289 | 2296 | ||
2290 | physcard->next = slic_global.phys_card; | 2297 | physcard->next = slic_global.phys_card; |
diff --git a/drivers/staging/stlc45xx/Kconfig b/drivers/staging/stlc45xx/Kconfig index 8d3f46f190e8..947fb75a9c68 100644 --- a/drivers/staging/stlc45xx/Kconfig +++ b/drivers/staging/stlc45xx/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config STLC45XX | 1 | config STLC45XX |
2 | tristate "stlc4550/4560 support" | 2 | tristate "stlc4550/4560 support" |
3 | depends on MAC80211 && WLAN_80211 && SPI_MASTER | 3 | depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS |
4 | ---help--- | 4 | ---help--- |
5 | This is a driver for stlc4550 and stlc4560 chipsets. | 5 | This is a driver for stlc4550 and stlc4560 chipsets. |
6 | 6 | ||
diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c index 891f6e334672..076b3f7d39eb 100644 --- a/drivers/staging/sxg/sxg.c +++ b/drivers/staging/sxg/sxg.c | |||
@@ -322,6 +322,8 @@ int sxg_add_msi_isr(struct adapter_t *adapter) | |||
322 | int ret,i; | 322 | int ret,i; |
323 | 323 | ||
324 | if (!adapter->intrregistered) { | 324 | if (!adapter->intrregistered) { |
325 | spin_unlock_irqrestore(&sxg_global.driver_lock, | ||
326 | sxg_global.flags); | ||
325 | for (i=0; i<adapter->nr_msix_entries; i++) { | 327 | for (i=0; i<adapter->nr_msix_entries; i++) { |
326 | ret = request_irq (adapter->msi_entries[i].vector, | 328 | ret = request_irq (adapter->msi_entries[i].vector, |
327 | sxg_isr, | 329 | sxg_isr, |
@@ -329,6 +331,8 @@ int sxg_add_msi_isr(struct adapter_t *adapter) | |||
329 | adapter->netdev->name, | 331 | adapter->netdev->name, |
330 | adapter->netdev); | 332 | adapter->netdev); |
331 | if (ret) { | 333 | if (ret) { |
334 | spin_lock_irqsave(&sxg_global.driver_lock, | ||
335 | sxg_global.flags); | ||
332 | DBG_ERROR("sxg: MSI-X request_irq (%s) " | 336 | DBG_ERROR("sxg: MSI-X request_irq (%s) " |
333 | "FAILED [%x]\n", adapter->netdev->name, | 337 | "FAILED [%x]\n", adapter->netdev->name, |
334 | ret); | 338 | ret); |
@@ -336,6 +340,7 @@ int sxg_add_msi_isr(struct adapter_t *adapter) | |||
336 | } | 340 | } |
337 | } | 341 | } |
338 | } | 342 | } |
343 | spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); | ||
339 | adapter->msi_enabled = TRUE; | 344 | adapter->msi_enabled = TRUE; |
340 | adapter->intrregistered = 1; | 345 | adapter->intrregistered = 1; |
341 | adapter->IntRegistered = TRUE; | 346 | adapter->IntRegistered = TRUE; |
@@ -896,6 +901,22 @@ static inline int sxg_read_config(struct adapter_t *adapter) | |||
896 | return status; | 901 | return status; |
897 | } | 902 | } |
898 | 903 | ||
904 | static const struct net_device_ops sxg_netdev_ops = { | ||
905 | .ndo_open = sxg_entry_open, | ||
906 | .ndo_stop = sxg_entry_halt, | ||
907 | .ndo_start_xmit = sxg_send_packets, | ||
908 | .ndo_do_ioctl = sxg_ioctl, | ||
909 | .ndo_change_mtu = sxg_change_mtu, | ||
910 | .ndo_get_stats = sxg_get_stats, | ||
911 | .ndo_set_multicast_list = sxg_mcast_set_list, | ||
912 | .ndo_validate_addr = eth_validate_addr, | ||
913 | #if XXXTODO | ||
914 | .ndo_set_mac_address = sxg_mac_set_address, | ||
915 | #else | ||
916 | .ndo_set_mac_address = eth_mac_addr, | ||
917 | #endif | ||
918 | }; | ||
919 | |||
899 | static int sxg_entry_probe(struct pci_dev *pcidev, | 920 | static int sxg_entry_probe(struct pci_dev *pcidev, |
900 | const struct pci_device_id *pci_tbl_entry) | 921 | const struct pci_device_id *pci_tbl_entry) |
901 | { | 922 | { |
@@ -1095,16 +1116,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev, | |||
1095 | 1116 | ||
1096 | netdev->base_addr = (unsigned long)adapter->base_addr; | 1117 | netdev->base_addr = (unsigned long)adapter->base_addr; |
1097 | netdev->irq = adapter->irq; | 1118 | netdev->irq = adapter->irq; |
1098 | netdev->open = sxg_entry_open; | 1119 | netdev->netdev_ops = &sxg_netdev_ops; |
1099 | netdev->stop = sxg_entry_halt; | ||
1100 | netdev->hard_start_xmit = sxg_send_packets; | ||
1101 | netdev->do_ioctl = sxg_ioctl; | ||
1102 | netdev->change_mtu = sxg_change_mtu; | ||
1103 | #if XXXTODO | ||
1104 | netdev->set_mac_address = sxg_mac_set_address; | ||
1105 | #endif | ||
1106 | netdev->get_stats = sxg_get_stats; | ||
1107 | netdev->set_multicast_list = sxg_mcast_set_list; | ||
1108 | SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops); | 1120 | SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops); |
1109 | netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | 1121 | netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; |
1110 | err = sxg_set_interrupt_capability(adapter); | 1122 | err = sxg_set_interrupt_capability(adapter); |
@@ -2247,6 +2259,8 @@ static int sxg_entry_open(struct net_device *dev) | |||
2247 | DBG_ERROR("sxg: %s EXIT\n", __func__); | 2259 | DBG_ERROR("sxg: %s EXIT\n", __func__); |
2248 | 2260 | ||
2249 | spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); | 2261 | spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); |
2262 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
2263 | |||
2250 | return STATUS_SUCCESS; | 2264 | return STATUS_SUCCESS; |
2251 | } | 2265 | } |
2252 | 2266 | ||
@@ -2568,6 +2582,7 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2568 | u64 phys_addr; | 2582 | u64 phys_addr; |
2569 | unsigned long flags; | 2583 | unsigned long flags; |
2570 | unsigned long queue_id=0; | 2584 | unsigned long queue_id=0; |
2585 | int offload_cksum = 0; | ||
2571 | 2586 | ||
2572 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl", | 2587 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl", |
2573 | pSgl, SxgSgl, 0, 0); | 2588 | pSgl, SxgSgl, 0, 0); |
@@ -2606,7 +2621,11 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2606 | struct iphdr *ip; | 2621 | struct iphdr *ip; |
2607 | 2622 | ||
2608 | ip = ip_hdr(skb); | 2623 | ip = ip_hdr(skb); |
2609 | if ((ip->protocol == IPPROTO_TCP)&&(DataLength >= sizeof( | 2624 | if (ip->protocol == IPPROTO_TCP) |
2625 | offload_cksum = 1; | ||
2626 | if (!offload_cksum || !tcp_hdr(skb)) | ||
2627 | queue_id = 0; | ||
2628 | else if (offload_cksum && (DataLength >= sizeof( | ||
2610 | struct tcphdr))){ | 2629 | struct tcphdr))){ |
2611 | queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? | 2630 | queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? |
2612 | (ntohs (tcp_hdr(skb)->source) & | 2631 | (ntohs (tcp_hdr(skb)->source) & |
@@ -2615,8 +2634,11 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2615 | SXG_LARGE_SEND_QUEUE_MASK)); | 2634 | SXG_LARGE_SEND_QUEUE_MASK)); |
2616 | } | 2635 | } |
2617 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 2636 | } else if (skb->protocol == htons(ETH_P_IPV6)) { |
2618 | if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (DataLength >= | 2637 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) |
2619 | sizeof(struct tcphdr)) ) { | 2638 | offload_cksum = 1; |
2639 | if (!offload_cksum || !tcp_hdr(skb)) | ||
2640 | queue_id = 0; | ||
2641 | else if (offload_cksum && (DataLength>=sizeof(struct tcphdr))){ | ||
2620 | queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? | 2642 | queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? |
2621 | (ntohs (tcp_hdr(skb)->source) & | 2643 | (ntohs (tcp_hdr(skb)->source) & |
2622 | SXG_LARGE_SEND_QUEUE_MASK): | 2644 | SXG_LARGE_SEND_QUEUE_MASK): |
@@ -2645,23 +2667,38 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2645 | } | 2667 | } |
2646 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd", | 2668 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd", |
2647 | XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0); | 2669 | XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0); |
2648 | /* Update stats */ | 2670 | memset(XmtCmd, '\0', sizeof(*XmtCmd)); |
2649 | adapter->stats.tx_packets++; | 2671 | XmtCmd->SgEntries = 1; |
2650 | adapter->stats.tx_bytes += DataLength; | 2672 | XmtCmd->Flags = 0; |
2651 | #if XXXTODO /* Stats stuff */ | 2673 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
2652 | if (SXG_MULTICAST_PACKET(EtherHdr)) { | 2674 | /* |
2653 | if (SXG_BROADCAST_PACKET(EtherHdr)) { | 2675 | * We need to set the Checkum in IP header to 0. This is |
2654 | adapter->Stats.DumbXmtBcastPkts++; | 2676 | * required by hardware. |
2655 | adapter->Stats.DumbXmtBcastBytes += DataLength; | 2677 | */ |
2678 | if (offload_cksum) { | ||
2679 | ip_hdr(skb)->check = 0x0; | ||
2680 | XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP; | ||
2681 | XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP; | ||
2682 | /* | ||
2683 | * Dont know if length will require a change in | ||
2684 | * case of VLAN | ||
2685 | */ | ||
2686 | XmtCmd->CsumFlags.MacLen = ETH_HLEN; | ||
2687 | XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >> | ||
2688 | SXG_NW_HDR_LEN_SHIFT; | ||
2656 | } else { | 2689 | } else { |
2657 | adapter->Stats.DumbXmtMcastPkts++; | 2690 | if (skb_checksum_help(skb)){ |
2658 | adapter->Stats.DumbXmtMcastBytes += DataLength; | 2691 | printk(KERN_EMERG "Dropped UDP packet for" |
2692 | " incorrect checksum calculation\n"); | ||
2693 | if (XmtCmd) | ||
2694 | SXG_ABORT_CMD(XmtRingInfo); | ||
2695 | spin_unlock_irqrestore(&adapter->XmtZeroLock, | ||
2696 | flags); | ||
2697 | return STATUS_SUCCESS; | ||
2698 | } | ||
2659 | } | 2699 | } |
2660 | } else { | ||
2661 | adapter->Stats.DumbXmtUcastPkts++; | ||
2662 | adapter->Stats.DumbXmtUcastBytes += DataLength; | ||
2663 | } | 2700 | } |
2664 | #endif | 2701 | |
2665 | /* | 2702 | /* |
2666 | * Fill in the command | 2703 | * Fill in the command |
2667 | * Copy out the first SGE to the command and adjust for offset | 2704 | * Copy out the first SGE to the command and adjust for offset |
@@ -2679,31 +2716,17 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2679 | (SXG_INVALID_SGL(phys_addr,skb->data_len))) | 2716 | (SXG_INVALID_SGL(phys_addr,skb->data_len))) |
2680 | { | 2717 | { |
2681 | spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); | 2718 | spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); |
2719 | if (XmtCmd) | ||
2720 | SXG_ABORT_CMD(XmtRingInfo); | ||
2682 | /* Silently drop this packet */ | 2721 | /* Silently drop this packet */ |
2683 | printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n"); | 2722 | printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n"); |
2684 | return STATUS_SUCCESS; | 2723 | return STATUS_SUCCESS; |
2685 | } | 2724 | } |
2686 | memset(XmtCmd, '\0', sizeof(*XmtCmd)); | ||
2687 | XmtCmd->Buffer.FirstSgeAddress = phys_addr; | 2725 | XmtCmd->Buffer.FirstSgeAddress = phys_addr; |
2688 | XmtCmd->Buffer.FirstSgeLength = DataLength; | 2726 | XmtCmd->Buffer.FirstSgeLength = DataLength; |
2689 | XmtCmd->Buffer.SgeOffset = 0; | 2727 | XmtCmd->Buffer.SgeOffset = 0; |
2690 | XmtCmd->Buffer.TotalLength = DataLength; | 2728 | XmtCmd->Buffer.TotalLength = DataLength; |
2691 | XmtCmd->SgEntries = 1; | ||
2692 | XmtCmd->Flags = 0; | ||
2693 | 2729 | ||
2694 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
2695 | /* | ||
2696 | * We need to set the Checkum in IP header to 0. This is | ||
2697 | * required by hardware. | ||
2698 | */ | ||
2699 | ip_hdr(skb)->check = 0x0; | ||
2700 | XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP; | ||
2701 | XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP; | ||
2702 | /* Dont know if length will require a change in case of VLAN */ | ||
2703 | XmtCmd->CsumFlags.MacLen = ETH_HLEN; | ||
2704 | XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >> | ||
2705 | SXG_NW_HDR_LEN_SHIFT; | ||
2706 | } | ||
2707 | /* | 2730 | /* |
2708 | * Advance transmit cmd descripter by 1. | 2731 | * Advance transmit cmd descripter by 1. |
2709 | * NOTE - See comments in SxgTcpOutput where we write | 2732 | * NOTE - See comments in SxgTcpOutput where we write |
@@ -2715,6 +2738,24 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2715 | ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0); | 2738 | ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0); |
2716 | WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE); | 2739 | WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE); |
2717 | adapter->Stats.XmtQLen++; /* Stats within lock */ | 2740 | adapter->Stats.XmtQLen++; /* Stats within lock */ |
2741 | /* Update stats */ | ||
2742 | adapter->stats.tx_packets++; | ||
2743 | adapter->stats.tx_bytes += DataLength; | ||
2744 | #if XXXTODO /* Stats stuff */ | ||
2745 | if (SXG_MULTICAST_PACKET(EtherHdr)) { | ||
2746 | if (SXG_BROADCAST_PACKET(EtherHdr)) { | ||
2747 | adapter->Stats.DumbXmtBcastPkts++; | ||
2748 | adapter->Stats.DumbXmtBcastBytes += DataLength; | ||
2749 | } else { | ||
2750 | adapter->Stats.DumbXmtMcastPkts++; | ||
2751 | adapter->Stats.DumbXmtMcastBytes += DataLength; | ||
2752 | } | ||
2753 | } else { | ||
2754 | adapter->Stats.DumbXmtUcastPkts++; | ||
2755 | adapter->Stats.DumbXmtUcastBytes += DataLength; | ||
2756 | } | ||
2757 | #endif | ||
2758 | |||
2718 | spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); | 2759 | spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); |
2719 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2", | 2760 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2", |
2720 | XmtCmd, pSgl, SxgSgl, 0); | 2761 | XmtCmd, pSgl, SxgSgl, 0); |
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c index 85b705453066..9c62f787cc9c 100644 --- a/drivers/staging/uc2322/aten2011.c +++ b/drivers/staging/uc2322/aten2011.c | |||
@@ -603,10 +603,9 @@ static void ATEN2011_bulk_out_data_callback(struct urb *urb) | |||
603 | 603 | ||
604 | tty = tty_port_tty_get(&ATEN2011_port->port->port); | 604 | tty = tty_port_tty_get(&ATEN2011_port->port->port); |
605 | 605 | ||
606 | if (tty && ATEN2011_port->open) { | 606 | if (tty && ATEN2011_port->open) |
607 | /* tell the tty driver that something has changed */ | 607 | /* tell the tty driver that something has changed */ |
608 | wake_up_interruptible(&tty->write_wait); | 608 | tty_wakeup(tty); |
609 | } | ||
610 | 609 | ||
611 | /* schedule_work(&ATEN2011_port->port->work); */ | 610 | /* schedule_work(&ATEN2011_port->port->work); */ |
612 | tty_kref_put(tty); | 611 | tty_kref_put(tty); |
@@ -825,12 +824,6 @@ static int ATEN2011_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
825 | status = 0; | 824 | status = 0; |
826 | status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data); | 825 | status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data); |
827 | 826 | ||
828 | /* force low_latency on so that our tty_push actually forces * | ||
829 | * the data through,otherwise it is scheduled, and with * | ||
830 | * high data rates (like with OHCI) data can get lost. */ | ||
831 | |||
832 | if (tty) | ||
833 | tty->low_latency = 1; | ||
834 | /* | 827 | /* |
835 | * Check to see if we've set up our endpoint info yet | 828 | * Check to see if we've set up our endpoint info yet |
836 | * (can't set it up in ATEN2011_startup as the structures | 829 | * (can't set it up in ATEN2011_startup as the structures |
@@ -1473,22 +1466,7 @@ static void ATEN2011_set_termios(struct tty_struct *tty, | |||
1473 | 1466 | ||
1474 | cflag = tty->termios->c_cflag; | 1467 | cflag = tty->termios->c_cflag; |
1475 | 1468 | ||
1476 | if (!cflag) { | 1469 | dbg("%s - cflag %08x iflag %08x", __func__, |
1477 | dbg("%s %s", __func__, "cflag is NULL"); | ||
1478 | return; | ||
1479 | } | ||
1480 | |||
1481 | /* check that they really want us to change something */ | ||
1482 | if (old_termios) { | ||
1483 | if ((cflag == old_termios->c_cflag) && | ||
1484 | (RELEVANT_IFLAG(tty->termios->c_iflag) == | ||
1485 | RELEVANT_IFLAG(old_termios->c_iflag))) { | ||
1486 | dbg("%s", "Nothing to change"); | ||
1487 | return; | ||
1488 | } | ||
1489 | } | ||
1490 | |||
1491 | dbg("%s - clfag %08x iflag %08x", __func__, | ||
1492 | tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); | 1470 | tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); |
1493 | 1471 | ||
1494 | if (old_termios) { | 1472 | if (old_termios) { |
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index b2a606a36936..393e4df70dfd 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c | |||
@@ -711,6 +711,20 @@ static int wlan_change_mtu(netdevice_t *dev, int new_mtu) | |||
711 | return 0; | 711 | return 0; |
712 | } | 712 | } |
713 | 713 | ||
714 | static const struct net_device_ops p80211_netdev_ops = { | ||
715 | .ndo_init = p80211knetdev_init, | ||
716 | .ndo_open = p80211knetdev_open, | ||
717 | .ndo_stop = p80211knetdev_stop, | ||
718 | .ndo_get_stats = p80211knetdev_get_stats, | ||
719 | .ndo_start_xmit = p80211knetdev_hard_start_xmit, | ||
720 | .ndo_set_multicast_list = p80211knetdev_set_multicast_list, | ||
721 | .ndo_do_ioctl = p80211knetdev_do_ioctl, | ||
722 | .ndo_set_mac_address = p80211knetdev_set_mac_address, | ||
723 | .ndo_tx_timeout = p80211knetdev_tx_timeout, | ||
724 | .ndo_change_mtu = wlan_change_mtu, | ||
725 | .ndo_validate_addr = eth_validate_addr, | ||
726 | }; | ||
727 | |||
714 | /*---------------------------------------------------------------- | 728 | /*---------------------------------------------------------------- |
715 | * wlan_setup | 729 | * wlan_setup |
716 | * | 730 | * |
@@ -756,11 +770,7 @@ int wlan_setup(wlandevice_t *wlandev) | |||
756 | } else { | 770 | } else { |
757 | wlandev->netdev = dev; | 771 | wlandev->netdev = dev; |
758 | dev->ml_priv = wlandev; | 772 | dev->ml_priv = wlandev; |
759 | dev->hard_start_xmit = p80211knetdev_hard_start_xmit; | 773 | dev->netdev_ops = &p80211_netdev_ops; |
760 | dev->get_stats = p80211knetdev_get_stats; | ||
761 | dev->init = p80211knetdev_init; | ||
762 | dev->open = p80211knetdev_open; | ||
763 | dev->stop = p80211knetdev_stop; | ||
764 | 774 | ||
765 | mutex_init(&wlandev->ioctl_lock); | 775 | mutex_init(&wlandev->ioctl_lock); |
766 | /* block ioctls until fully initialised. Don't forget to call | 776 | /* block ioctls until fully initialised. Don't forget to call |
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c index c60b8fcf0e3e..28034c812914 100644 --- a/drivers/uio/uio_cif.c +++ b/drivers/uio/uio_cif.c | |||
@@ -147,5 +147,6 @@ static void __exit hilscher_exit_module(void) | |||
147 | module_init(hilscher_init_module); | 147 | module_init(hilscher_init_module); |
148 | module_exit(hilscher_exit_module); | 148 | module_exit(hilscher_exit_module); |
149 | 149 | ||
150 | MODULE_DEVICE_TABLE(pci, hilscher_pci_ids); | ||
150 | MODULE_LICENSE("GPL v2"); | 151 | MODULE_LICENSE("GPL v2"); |
151 | MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger"); | 152 | MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger"); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 869d47cb6db3..0a69c0977e3f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -546,10 +546,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
546 | tty->driver_data = acm; | 546 | tty->driver_data = acm; |
547 | acm->tty = tty; | 547 | acm->tty = tty; |
548 | 548 | ||
549 | /* force low_latency on so that our tty_push actually forces the data through, | ||
550 | otherwise it is scheduled, and with high data rates data can get lost. */ | ||
551 | tty->low_latency = 1; | ||
552 | |||
553 | if (usb_autopm_get_interface(acm->control) < 0) | 549 | if (usb_autopm_get_interface(acm->control) < 0) |
554 | goto early_bail; | 550 | goto early_bail; |
555 | else | 551 | else |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 3771d6e6d0cc..0fe434505ac4 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * This driver supports USB CDC WCM Device Management. | 4 | * This driver supports USB CDC WCM Device Management. |
5 | * | 5 | * |
6 | * Copyright (c) 2007-2008 Oliver Neukum | 6 | * Copyright (c) 2007-2009 Oliver Neukum |
7 | * | 7 | * |
8 | * Some code taken from cdc-acm.c | 8 | * Some code taken from cdc-acm.c |
9 | * | 9 | * |
@@ -610,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
610 | if (!buffer) | 610 | if (!buffer) |
611 | goto out; | 611 | goto out; |
612 | 612 | ||
613 | while (buflen > 0) { | 613 | while (buflen > 2) { |
614 | if (buffer [1] != USB_DT_CS_INTERFACE) { | 614 | if (buffer [1] != USB_DT_CS_INTERFACE) { |
615 | dev_err(&intf->dev, "skipping garbage\n"); | 615 | dev_err(&intf->dev, "skipping garbage\n"); |
616 | goto next_desc; | 616 | goto next_desc; |
@@ -646,16 +646,18 @@ next_desc: | |||
646 | spin_lock_init(&desc->iuspin); | 646 | spin_lock_init(&desc->iuspin); |
647 | init_waitqueue_head(&desc->wait); | 647 | init_waitqueue_head(&desc->wait); |
648 | desc->wMaxCommand = maxcom; | 648 | desc->wMaxCommand = maxcom; |
649 | /* this will be expanded and needed in hardware endianness */ | ||
649 | desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber); | 650 | desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber); |
650 | desc->intf = intf; | 651 | desc->intf = intf; |
651 | INIT_WORK(&desc->rxwork, wdm_rxwork); | 652 | INIT_WORK(&desc->rxwork, wdm_rxwork); |
652 | 653 | ||
653 | iface = &intf->altsetting[0]; | 654 | rv = -EINVAL; |
655 | iface = intf->cur_altsetting; | ||
656 | if (iface->desc.bNumEndpoints != 1) | ||
657 | goto err; | ||
654 | ep = &iface->endpoint[0].desc; | 658 | ep = &iface->endpoint[0].desc; |
655 | if (!usb_endpoint_is_int_in(ep)) { | 659 | if (!ep || !usb_endpoint_is_int_in(ep)) |
656 | rv = -EINVAL; | ||
657 | goto err; | 660 | goto err; |
658 | } | ||
659 | 661 | ||
660 | desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); | 662 | desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); |
661 | desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; | 663 | desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; |
@@ -711,12 +713,19 @@ next_desc: | |||
711 | 713 | ||
712 | usb_set_intfdata(intf, desc); | 714 | usb_set_intfdata(intf, desc); |
713 | rv = usb_register_dev(intf, &wdm_class); | 715 | rv = usb_register_dev(intf, &wdm_class); |
714 | dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", | ||
715 | intf->minor - WDM_MINOR_BASE); | ||
716 | if (rv < 0) | 716 | if (rv < 0) |
717 | goto err; | 717 | goto err3; |
718 | else | ||
719 | dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", | ||
720 | intf->minor - WDM_MINOR_BASE); | ||
718 | out: | 721 | out: |
719 | return rv; | 722 | return rv; |
723 | err3: | ||
724 | usb_set_intfdata(intf, NULL); | ||
725 | usb_buffer_free(interface_to_usbdev(desc->intf), | ||
726 | desc->bMaxPacketSize0, | ||
727 | desc->inbuf, | ||
728 | desc->response->transfer_dma); | ||
720 | err2: | 729 | err2: |
721 | usb_buffer_free(interface_to_usbdev(desc->intf), | 730 | usb_buffer_free(interface_to_usbdev(desc->intf), |
722 | desc->wMaxPacketSize, | 731 | desc->wMaxPacketSize, |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index cadb2dc1d28a..3ba2fff71490 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -119,7 +119,7 @@ void *hcd_buffer_alloc( | |||
119 | if (size <= pool_max [i]) | 119 | if (size <= pool_max [i]) |
120 | return dma_pool_alloc(hcd->pool [i], mem_flags, dma); | 120 | return dma_pool_alloc(hcd->pool [i], mem_flags, dma); |
121 | } | 121 | } |
122 | return dma_alloc_coherent(hcd->self.controller, size, dma, 0); | 122 | return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags); |
123 | } | 123 | } |
124 | 124 | ||
125 | void hcd_buffer_free( | 125 | void hcd_buffer_free( |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index df3c539f652a..308609039c73 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -841,7 +841,7 @@ static int proc_resetep(struct dev_state *ps, void __user *arg) | |||
841 | ret = checkintf(ps, ret); | 841 | ret = checkintf(ps, ret); |
842 | if (ret) | 842 | if (ret) |
843 | return ret; | 843 | return ret; |
844 | usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0); | 844 | usb_reset_endpoint(ps->dev, ep); |
845 | return 0; | 845 | return 0; |
846 | } | 846 | } |
847 | 847 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 81fa8506825d..42b93da1085d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1539,6 +1539,32 @@ void usb_hcd_disable_endpoint(struct usb_device *udev, | |||
1539 | hcd->driver->endpoint_disable(hcd, ep); | 1539 | hcd->driver->endpoint_disable(hcd, ep); |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | /** | ||
1543 | * usb_hcd_reset_endpoint - reset host endpoint state | ||
1544 | * @udev: USB device. | ||
1545 | * @ep: the endpoint to reset. | ||
1546 | * | ||
1547 | * Resets any host endpoint state such as the toggle bit, sequence | ||
1548 | * number and current window. | ||
1549 | */ | ||
1550 | void usb_hcd_reset_endpoint(struct usb_device *udev, | ||
1551 | struct usb_host_endpoint *ep) | ||
1552 | { | ||
1553 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
1554 | |||
1555 | if (hcd->driver->endpoint_reset) | ||
1556 | hcd->driver->endpoint_reset(hcd, ep); | ||
1557 | else { | ||
1558 | int epnum = usb_endpoint_num(&ep->desc); | ||
1559 | int is_out = usb_endpoint_dir_out(&ep->desc); | ||
1560 | int is_control = usb_endpoint_xfer_control(&ep->desc); | ||
1561 | |||
1562 | usb_settoggle(udev, epnum, is_out, 0); | ||
1563 | if (is_control) | ||
1564 | usb_settoggle(udev, epnum, !is_out, 0); | ||
1565 | } | ||
1566 | } | ||
1567 | |||
1542 | /* Protect against drivers that try to unlink URBs after the device | 1568 | /* Protect against drivers that try to unlink URBs after the device |
1543 | * is gone, by waiting until all unlinks for @udev are finished. | 1569 | * is gone, by waiting until all unlinks for @udev are finished. |
1544 | * Since we don't currently track URBs by device, simply wait until | 1570 | * Since we don't currently track URBs by device, simply wait until |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index f750eb1ab595..e7d4479de41c 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -206,6 +206,11 @@ struct hc_driver { | |||
206 | void (*endpoint_disable)(struct usb_hcd *hcd, | 206 | void (*endpoint_disable)(struct usb_hcd *hcd, |
207 | struct usb_host_endpoint *ep); | 207 | struct usb_host_endpoint *ep); |
208 | 208 | ||
209 | /* (optional) reset any endpoint state such as sequence number | ||
210 | and current window */ | ||
211 | void (*endpoint_reset)(struct usb_hcd *hcd, | ||
212 | struct usb_host_endpoint *ep); | ||
213 | |||
209 | /* root hub support */ | 214 | /* root hub support */ |
210 | int (*hub_status_data) (struct usb_hcd *hcd, char *buf); | 215 | int (*hub_status_data) (struct usb_hcd *hcd, char *buf); |
211 | int (*hub_control) (struct usb_hcd *hcd, | 216 | int (*hub_control) (struct usb_hcd *hcd, |
@@ -234,6 +239,8 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev, | |||
234 | struct usb_host_endpoint *ep); | 239 | struct usb_host_endpoint *ep); |
235 | extern void usb_hcd_disable_endpoint(struct usb_device *udev, | 240 | extern void usb_hcd_disable_endpoint(struct usb_device *udev, |
236 | struct usb_host_endpoint *ep); | 241 | struct usb_host_endpoint *ep); |
242 | extern void usb_hcd_reset_endpoint(struct usb_device *udev, | ||
243 | struct usb_host_endpoint *ep); | ||
237 | extern void usb_hcd_synchronize_unlinks(struct usb_device *udev); | 244 | extern void usb_hcd_synchronize_unlinks(struct usb_device *udev); |
238 | extern int usb_hcd_get_frame_number(struct usb_device *udev); | 245 | extern int usb_hcd_get_frame_number(struct usb_device *udev); |
239 | 246 | ||
@@ -279,6 +286,13 @@ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd); | |||
279 | extern void usb_hc_died(struct usb_hcd *hcd); | 286 | extern void usb_hc_died(struct usb_hcd *hcd); |
280 | extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); | 287 | extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); |
281 | 288 | ||
289 | /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ | ||
290 | #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) | ||
291 | #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) | ||
292 | #define usb_settoggle(dev, ep, out, bit) \ | ||
293 | ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \ | ||
294 | ((bit) << (ep))) | ||
295 | |||
282 | /* -------------------------------------------------------------------------- */ | 296 | /* -------------------------------------------------------------------------- */ |
283 | 297 | ||
284 | /* Enumeration is only for the hub driver, or HCD virtual root hubs */ | 298 | /* Enumeration is only for the hub driver, or HCD virtual root hubs */ |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 30a0690f3683..b62628377654 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1002,8 +1002,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe) | |||
1002 | * the copy in usb-storage, for as long as we need two copies. | 1002 | * the copy in usb-storage, for as long as we need two copies. |
1003 | */ | 1003 | */ |
1004 | 1004 | ||
1005 | /* toggle was reset by the clear */ | 1005 | usb_reset_endpoint(dev, endp); |
1006 | usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); | ||
1007 | 1006 | ||
1008 | return 0; | 1007 | return 0; |
1009 | } | 1008 | } |
@@ -1076,6 +1075,30 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, | |||
1076 | } | 1075 | } |
1077 | 1076 | ||
1078 | /** | 1077 | /** |
1078 | * usb_reset_endpoint - Reset an endpoint's state. | ||
1079 | * @dev: the device whose endpoint is to be reset | ||
1080 | * @epaddr: the endpoint's address. Endpoint number for output, | ||
1081 | * endpoint number + USB_DIR_IN for input | ||
1082 | * | ||
1083 | * Resets any host-side endpoint state such as the toggle bit, | ||
1084 | * sequence number or current window. | ||
1085 | */ | ||
1086 | void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr) | ||
1087 | { | ||
1088 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; | ||
1089 | struct usb_host_endpoint *ep; | ||
1090 | |||
1091 | if (usb_endpoint_out(epaddr)) | ||
1092 | ep = dev->ep_out[epnum]; | ||
1093 | else | ||
1094 | ep = dev->ep_in[epnum]; | ||
1095 | if (ep) | ||
1096 | usb_hcd_reset_endpoint(dev, ep); | ||
1097 | } | ||
1098 | EXPORT_SYMBOL_GPL(usb_reset_endpoint); | ||
1099 | |||
1100 | |||
1101 | /** | ||
1079 | * usb_disable_interface -- Disable all endpoints for an interface | 1102 | * usb_disable_interface -- Disable all endpoints for an interface |
1080 | * @dev: the device whose interface is being disabled | 1103 | * @dev: the device whose interface is being disabled |
1081 | * @intf: pointer to the interface descriptor | 1104 | * @intf: pointer to the interface descriptor |
@@ -1117,7 +1140,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1117 | usb_disable_endpoint(dev, i, true); | 1140 | usb_disable_endpoint(dev, i, true); |
1118 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); | 1141 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); |
1119 | } | 1142 | } |
1120 | dev->toggle[0] = dev->toggle[1] = 0; | ||
1121 | 1143 | ||
1122 | /* getting rid of interfaces will disconnect | 1144 | /* getting rid of interfaces will disconnect |
1123 | * any drivers bound to them (a key side effect) | 1145 | * any drivers bound to them (a key side effect) |
@@ -1154,28 +1176,24 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1154 | * usb_enable_endpoint - Enable an endpoint for USB communications | 1176 | * usb_enable_endpoint - Enable an endpoint for USB communications |
1155 | * @dev: the device whose interface is being enabled | 1177 | * @dev: the device whose interface is being enabled |
1156 | * @ep: the endpoint | 1178 | * @ep: the endpoint |
1157 | * @reset_toggle: flag to set the endpoint's toggle back to 0 | 1179 | * @reset_ep: flag to reset the endpoint state |
1158 | * | 1180 | * |
1159 | * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers. | 1181 | * Resets the endpoint state if asked, and sets dev->ep_{in,out} pointers. |
1160 | * For control endpoints, both the input and output sides are handled. | 1182 | * For control endpoints, both the input and output sides are handled. |
1161 | */ | 1183 | */ |
1162 | void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, | 1184 | void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, |
1163 | bool reset_toggle) | 1185 | bool reset_ep) |
1164 | { | 1186 | { |
1165 | int epnum = usb_endpoint_num(&ep->desc); | 1187 | int epnum = usb_endpoint_num(&ep->desc); |
1166 | int is_out = usb_endpoint_dir_out(&ep->desc); | 1188 | int is_out = usb_endpoint_dir_out(&ep->desc); |
1167 | int is_control = usb_endpoint_xfer_control(&ep->desc); | 1189 | int is_control = usb_endpoint_xfer_control(&ep->desc); |
1168 | 1190 | ||
1169 | if (is_out || is_control) { | 1191 | if (reset_ep) |
1170 | if (reset_toggle) | 1192 | usb_hcd_reset_endpoint(dev, ep); |
1171 | usb_settoggle(dev, epnum, 1, 0); | 1193 | if (is_out || is_control) |
1172 | dev->ep_out[epnum] = ep; | 1194 | dev->ep_out[epnum] = ep; |
1173 | } | 1195 | if (!is_out || is_control) |
1174 | if (!is_out || is_control) { | ||
1175 | if (reset_toggle) | ||
1176 | usb_settoggle(dev, epnum, 0, 0); | ||
1177 | dev->ep_in[epnum] = ep; | 1196 | dev->ep_in[epnum] = ep; |
1178 | } | ||
1179 | ep->enabled = 1; | 1197 | ep->enabled = 1; |
1180 | } | 1198 | } |
1181 | 1199 | ||
@@ -1183,18 +1201,18 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, | |||
1183 | * usb_enable_interface - Enable all the endpoints for an interface | 1201 | * usb_enable_interface - Enable all the endpoints for an interface |
1184 | * @dev: the device whose interface is being enabled | 1202 | * @dev: the device whose interface is being enabled |
1185 | * @intf: pointer to the interface descriptor | 1203 | * @intf: pointer to the interface descriptor |
1186 | * @reset_toggles: flag to set the endpoints' toggles back to 0 | 1204 | * @reset_eps: flag to reset the endpoints' state |
1187 | * | 1205 | * |
1188 | * Enables all the endpoints for the interface's current altsetting. | 1206 | * Enables all the endpoints for the interface's current altsetting. |
1189 | */ | 1207 | */ |
1190 | void usb_enable_interface(struct usb_device *dev, | 1208 | void usb_enable_interface(struct usb_device *dev, |
1191 | struct usb_interface *intf, bool reset_toggles) | 1209 | struct usb_interface *intf, bool reset_eps) |
1192 | { | 1210 | { |
1193 | struct usb_host_interface *alt = intf->cur_altsetting; | 1211 | struct usb_host_interface *alt = intf->cur_altsetting; |
1194 | int i; | 1212 | int i; |
1195 | 1213 | ||
1196 | for (i = 0; i < alt->desc.bNumEndpoints; ++i) | 1214 | for (i = 0; i < alt->desc.bNumEndpoints; ++i) |
1197 | usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles); | 1215 | usb_enable_endpoint(dev, &alt->endpoint[i], reset_eps); |
1198 | } | 1216 | } |
1199 | 1217 | ||
1200 | /** | 1218 | /** |
@@ -1335,7 +1353,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface); | |||
1335 | * This issues a standard SET_CONFIGURATION request to the device using | 1353 | * This issues a standard SET_CONFIGURATION request to the device using |
1336 | * the current configuration. The effect is to reset most USB-related | 1354 | * the current configuration. The effect is to reset most USB-related |
1337 | * state in the device, including interface altsettings (reset to zero), | 1355 | * state in the device, including interface altsettings (reset to zero), |
1338 | * endpoint halts (cleared), and data toggle (only for bulk and interrupt | 1356 | * endpoint halts (cleared), and endpoint state (only for bulk and interrupt |
1339 | * endpoints). Other usbcore state is unchanged, including bindings of | 1357 | * endpoints). Other usbcore state is unchanged, including bindings of |
1340 | * usb device drivers to interfaces. | 1358 | * usb device drivers to interfaces. |
1341 | * | 1359 | * |
@@ -1343,7 +1361,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface); | |||
1343 | * (multi-interface) devices. Instead, the driver for each interface may | 1361 | * (multi-interface) devices. Instead, the driver for each interface may |
1344 | * use usb_set_interface() on the interfaces it claims. Be careful though; | 1362 | * use usb_set_interface() on the interfaces it claims. Be careful though; |
1345 | * some devices don't support the SET_INTERFACE request, and others won't | 1363 | * some devices don't support the SET_INTERFACE request, and others won't |
1346 | * reset all the interface state (notably data toggles). Resetting the whole | 1364 | * reset all the interface state (notably endpoint state). Resetting the whole |
1347 | * configuration would affect other drivers' interfaces. | 1365 | * configuration would affect other drivers' interfaces. |
1348 | * | 1366 | * |
1349 | * The caller must own the device lock. | 1367 | * The caller must own the device lock. |
@@ -1376,8 +1394,6 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1376 | if (retval < 0) | 1394 | if (retval < 0) |
1377 | return retval; | 1395 | return retval; |
1378 | 1396 | ||
1379 | dev->toggle[0] = dev->toggle[1] = 0; | ||
1380 | |||
1381 | /* re-init hc/hcd interface/endpoint state */ | 1397 | /* re-init hc/hcd interface/endpoint state */ |
1382 | for (i = 0; i < config->desc.bNumInterfaces; i++) { | 1398 | for (i = 0; i < config->desc.bNumInterfaces; i++) { |
1383 | struct usb_interface *intf = config->interface[i]; | 1399 | struct usb_interface *intf = config->interface[i]; |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index dcfc072630c1..7eee400d3e32 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
362 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; | 362 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; |
363 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; | 363 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; |
364 | /* ep0 maxpacket comes later, from device descriptor */ | 364 | /* ep0 maxpacket comes later, from device descriptor */ |
365 | usb_enable_endpoint(dev, &dev->ep0, true); | 365 | usb_enable_endpoint(dev, &dev->ep0, false); |
366 | dev->can_submit = 1; | 366 | dev->can_submit = 1; |
367 | 367 | ||
368 | /* Save readable and stable topology id, distinguishing devices | 368 | /* Save readable and stable topology id, distinguishing devices |
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 22c65960c429..38e531ecae4d 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -51,6 +51,7 @@ | |||
51 | * - Gadget API (majority of optional features) | 51 | * - Gadget API (majority of optional features) |
52 | * - Suspend & Remote Wakeup | 52 | * - Suspend & Remote Wakeup |
53 | */ | 53 | */ |
54 | #include <linux/delay.h> | ||
54 | #include <linux/device.h> | 55 | #include <linux/device.h> |
55 | #include <linux/dmapool.h> | 56 | #include <linux/dmapool.h> |
56 | #include <linux/dma-mapping.h> | 57 | #include <linux/dma-mapping.h> |
@@ -142,7 +143,7 @@ static struct { | |||
142 | #define CAP_DEVICEADDR (0x014UL) | 143 | #define CAP_DEVICEADDR (0x014UL) |
143 | #define CAP_ENDPTLISTADDR (0x018UL) | 144 | #define CAP_ENDPTLISTADDR (0x018UL) |
144 | #define CAP_PORTSC (0x044UL) | 145 | #define CAP_PORTSC (0x044UL) |
145 | #define CAP_DEVLC (0x0B4UL) | 146 | #define CAP_DEVLC (0x084UL) |
146 | #define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL) | 147 | #define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL) |
147 | #define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL) | 148 | #define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL) |
148 | #define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL) | 149 | #define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL) |
@@ -1986,6 +1987,8 @@ static int ep_enable(struct usb_ep *ep, | |||
1986 | do { | 1987 | do { |
1987 | dbg_event(_usb_addr(mEp), "ENABLE", 0); | 1988 | dbg_event(_usb_addr(mEp), "ENABLE", 0); |
1988 | 1989 | ||
1990 | mEp->qh[mEp->dir].ptr->cap = 0; | ||
1991 | |||
1989 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) | 1992 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) |
1990 | mEp->qh[mEp->dir].ptr->cap |= QH_IOS; | 1993 | mEp->qh[mEp->dir].ptr->cap |= QH_IOS; |
1991 | else if (mEp->type == USB_ENDPOINT_XFER_ISOC) | 1994 | else if (mEp->type == USB_ENDPOINT_XFER_ISOC) |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 5c030b080d4c..381a53b3e11c 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -738,7 +738,6 @@ static struct fsg_dev *the_fsg; | |||
738 | static struct usb_gadget_driver fsg_driver; | 738 | static struct usb_gadget_driver fsg_driver; |
739 | 739 | ||
740 | static void close_backing_file(struct lun *curlun); | 740 | static void close_backing_file(struct lun *curlun); |
741 | static void close_all_backing_files(struct fsg_dev *fsg); | ||
742 | 741 | ||
743 | 742 | ||
744 | /*-------------------------------------------------------------------------*/ | 743 | /*-------------------------------------------------------------------------*/ |
@@ -3593,12 +3592,10 @@ static int fsg_main_thread(void *fsg_) | |||
3593 | fsg->thread_task = NULL; | 3592 | fsg->thread_task = NULL; |
3594 | spin_unlock_irq(&fsg->lock); | 3593 | spin_unlock_irq(&fsg->lock); |
3595 | 3594 | ||
3596 | /* In case we are exiting because of a signal, unregister the | 3595 | /* If we are exiting because of a signal, unregister the |
3597 | * gadget driver and close the backing file. */ | 3596 | * gadget driver. */ |
3598 | if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) { | 3597 | if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) |
3599 | usb_gadget_unregister_driver(&fsg_driver); | 3598 | usb_gadget_unregister_driver(&fsg_driver); |
3600 | close_all_backing_files(fsg); | ||
3601 | } | ||
3602 | 3599 | ||
3603 | /* Let the unbind and cleanup routines know the thread has exited */ | 3600 | /* Let the unbind and cleanup routines know the thread has exited */ |
3604 | complete_and_exit(&fsg->thread_notifier, 0); | 3601 | complete_and_exit(&fsg->thread_notifier, 0); |
@@ -3703,14 +3700,6 @@ static void close_backing_file(struct lun *curlun) | |||
3703 | } | 3700 | } |
3704 | } | 3701 | } |
3705 | 3702 | ||
3706 | static void close_all_backing_files(struct fsg_dev *fsg) | ||
3707 | { | ||
3708 | int i; | ||
3709 | |||
3710 | for (i = 0; i < fsg->nluns; ++i) | ||
3711 | close_backing_file(&fsg->luns[i]); | ||
3712 | } | ||
3713 | |||
3714 | 3703 | ||
3715 | static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf) | 3704 | static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf) |
3716 | { | 3705 | { |
@@ -3845,6 +3834,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) | |||
3845 | if (curlun->registered) { | 3834 | if (curlun->registered) { |
3846 | device_remove_file(&curlun->dev, &dev_attr_ro); | 3835 | device_remove_file(&curlun->dev, &dev_attr_ro); |
3847 | device_remove_file(&curlun->dev, &dev_attr_file); | 3836 | device_remove_file(&curlun->dev, &dev_attr_file); |
3837 | close_backing_file(curlun); | ||
3848 | device_unregister(&curlun->dev); | 3838 | device_unregister(&curlun->dev); |
3849 | curlun->registered = 0; | 3839 | curlun->registered = 0; |
3850 | } | 3840 | } |
@@ -4190,7 +4180,6 @@ autoconf_fail: | |||
4190 | out: | 4180 | out: |
4191 | fsg->state = FSG_STATE_TERMINATED; // The thread is dead | 4181 | fsg->state = FSG_STATE_TERMINATED; // The thread is dead |
4192 | fsg_unbind(gadget); | 4182 | fsg_unbind(gadget); |
4193 | close_all_backing_files(fsg); | ||
4194 | complete(&fsg->thread_notifier); | 4183 | complete(&fsg->thread_notifier); |
4195 | return rc; | 4184 | return rc; |
4196 | } | 4185 | } |
@@ -4284,7 +4273,6 @@ static void __exit fsg_cleanup(void) | |||
4284 | /* Wait for the thread to finish up */ | 4273 | /* Wait for the thread to finish up */ |
4285 | wait_for_completion(&fsg->thread_notifier); | 4274 | wait_for_completion(&fsg->thread_notifier); |
4286 | 4275 | ||
4287 | close_all_backing_files(fsg); | ||
4288 | kref_put(&fsg->ref, fsg_release); | 4276 | kref_put(&fsg->ref, fsg_release); |
4289 | } | 4277 | } |
4290 | module_exit(fsg_cleanup); | 4278 | module_exit(fsg_cleanup); |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 57d9641c6bf8..a2db0e174f2c 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -3104,7 +3104,6 @@ static int omap_udc_resume(struct platform_device *dev) | |||
3104 | /*-------------------------------------------------------------------------*/ | 3104 | /*-------------------------------------------------------------------------*/ |
3105 | 3105 | ||
3106 | static struct platform_driver udc_driver = { | 3106 | static struct platform_driver udc_driver = { |
3107 | .probe = omap_udc_probe, | ||
3108 | .remove = __exit_p(omap_udc_remove), | 3107 | .remove = __exit_p(omap_udc_remove), |
3109 | .suspend = omap_udc_suspend, | 3108 | .suspend = omap_udc_suspend, |
3110 | .resume = omap_udc_resume, | 3109 | .resume = omap_udc_resume, |
@@ -3122,7 +3121,7 @@ static int __init udc_init(void) | |||
3122 | #endif | 3121 | #endif |
3123 | "%s\n", driver_desc, | 3122 | "%s\n", driver_desc, |
3124 | use_dma ? " (dma)" : ""); | 3123 | use_dma ? " (dma)" : ""); |
3125 | return platform_driver_register(&udc_driver); | 3124 | return platform_driver_probe(&udc_driver, omap_udc_probe); |
3126 | } | 3125 | } |
3127 | module_init(udc_init); | 3126 | module_init(udc_init); |
3128 | 3127 | ||
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 96d65ca06ecd..4007770f7ed2 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -175,12 +175,6 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) | |||
175 | strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info); | 175 | strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info); |
176 | } | 176 | } |
177 | 177 | ||
178 | static u32 eth_get_link(struct net_device *net) | ||
179 | { | ||
180 | struct eth_dev *dev = netdev_priv(net); | ||
181 | return dev->gadget->speed != USB_SPEED_UNKNOWN; | ||
182 | } | ||
183 | |||
184 | /* REVISIT can also support: | 178 | /* REVISIT can also support: |
185 | * - WOL (by tracking suspends and issuing remote wakeup) | 179 | * - WOL (by tracking suspends and issuing remote wakeup) |
186 | * - msglevel (implies updated messaging) | 180 | * - msglevel (implies updated messaging) |
@@ -189,7 +183,7 @@ static u32 eth_get_link(struct net_device *net) | |||
189 | 183 | ||
190 | static struct ethtool_ops ops = { | 184 | static struct ethtool_ops ops = { |
191 | .get_drvinfo = eth_get_drvinfo, | 185 | .get_drvinfo = eth_get_drvinfo, |
192 | .get_link = eth_get_link | 186 | .get_link = ethtool_op_get_link, |
193 | }; | 187 | }; |
194 | 188 | ||
195 | static void defer_kevent(struct eth_dev *dev, int flag) | 189 | static void defer_kevent(struct eth_dev *dev, int flag) |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index ada5d2ba297b..556d0ec0c1f8 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -323,7 +323,7 @@ static int tt_available ( | |||
323 | * already scheduled transactions | 323 | * already scheduled transactions |
324 | */ | 324 | */ |
325 | if (125 < usecs) { | 325 | if (125 < usecs) { |
326 | int ufs = (usecs / 125) - 1; | 326 | int ufs = (usecs / 125); |
327 | int i; | 327 | int i; |
328 | for (i = uframe; i < (uframe + ufs) && i < 8; i++) | 328 | for (i = uframe; i < (uframe + ufs) && i < 8; i++) |
329 | if (0 < tt_usecs[i]) { | 329 | if (0 < tt_usecs[i]) { |
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 958751ccea43..c2050785a819 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c | |||
@@ -122,7 +122,8 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset) | |||
122 | process_inactive_qtd(whc, qset, td); | 122 | process_inactive_qtd(whc, qset, td); |
123 | } | 123 | } |
124 | 124 | ||
125 | update |= qset_add_qtds(whc, qset); | 125 | if (!qset->remove) |
126 | update |= qset_add_qtds(whc, qset); | ||
126 | 127 | ||
127 | done: | 128 | done: |
128 | /* | 129 | /* |
@@ -254,23 +255,29 @@ int asl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags) | |||
254 | 255 | ||
255 | spin_lock_irqsave(&whc->lock, flags); | 256 | spin_lock_irqsave(&whc->lock, flags); |
256 | 257 | ||
258 | err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
259 | if (err < 0) { | ||
260 | spin_unlock_irqrestore(&whc->lock, flags); | ||
261 | return err; | ||
262 | } | ||
263 | |||
257 | qset = get_qset(whc, urb, GFP_ATOMIC); | 264 | qset = get_qset(whc, urb, GFP_ATOMIC); |
258 | if (qset == NULL) | 265 | if (qset == NULL) |
259 | err = -ENOMEM; | 266 | err = -ENOMEM; |
260 | else | 267 | else |
261 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); | 268 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); |
262 | if (!err) { | 269 | if (!err) { |
263 | usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
264 | if (!qset->in_sw_list) | 270 | if (!qset->in_sw_list) |
265 | asl_qset_insert_begin(whc, qset); | 271 | asl_qset_insert_begin(whc, qset); |
266 | } | 272 | } else |
273 | usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb); | ||
267 | 274 | ||
268 | spin_unlock_irqrestore(&whc->lock, flags); | 275 | spin_unlock_irqrestore(&whc->lock, flags); |
269 | 276 | ||
270 | if (!err) | 277 | if (!err) |
271 | queue_work(whc->workqueue, &whc->async_work); | 278 | queue_work(whc->workqueue, &whc->async_work); |
272 | 279 | ||
273 | return 0; | 280 | return err; |
274 | } | 281 | } |
275 | 282 | ||
276 | /** | 283 | /** |
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index 1569afd6245b..e019a5058ab8 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c | |||
@@ -186,6 +186,28 @@ static void whc_endpoint_disable(struct usb_hcd *usb_hcd, | |||
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | static void whc_endpoint_reset(struct usb_hcd *usb_hcd, | ||
190 | struct usb_host_endpoint *ep) | ||
191 | { | ||
192 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); | ||
193 | struct whc *whc = wusbhc_to_whc(wusbhc); | ||
194 | struct whc_qset *qset; | ||
195 | |||
196 | qset = ep->hcpriv; | ||
197 | if (qset) { | ||
198 | qset->remove = 1; | ||
199 | |||
200 | if (usb_endpoint_xfer_bulk(&ep->desc) | ||
201 | || usb_endpoint_xfer_control(&ep->desc)) | ||
202 | queue_work(whc->workqueue, &whc->async_work); | ||
203 | else | ||
204 | queue_work(whc->workqueue, &whc->periodic_work); | ||
205 | |||
206 | qset_reset(whc, qset); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | |||
189 | static struct hc_driver whc_hc_driver = { | 211 | static struct hc_driver whc_hc_driver = { |
190 | .description = "whci-hcd", | 212 | .description = "whci-hcd", |
191 | .product_desc = "Wireless host controller", | 213 | .product_desc = "Wireless host controller", |
@@ -200,6 +222,7 @@ static struct hc_driver whc_hc_driver = { | |||
200 | .urb_enqueue = whc_urb_enqueue, | 222 | .urb_enqueue = whc_urb_enqueue, |
201 | .urb_dequeue = whc_urb_dequeue, | 223 | .urb_dequeue = whc_urb_dequeue, |
202 | .endpoint_disable = whc_endpoint_disable, | 224 | .endpoint_disable = whc_endpoint_disable, |
225 | .endpoint_reset = whc_endpoint_reset, | ||
203 | 226 | ||
204 | .hub_status_data = wusbhc_rh_status_data, | 227 | .hub_status_data = wusbhc_rh_status_data, |
205 | .hub_control = wusbhc_rh_control, | 228 | .hub_control = wusbhc_rh_control, |
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index df8b85f07092..ff4ef9e910d9 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c | |||
@@ -128,7 +128,8 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset) | |||
128 | process_inactive_qtd(whc, qset, td); | 128 | process_inactive_qtd(whc, qset, td); |
129 | } | 129 | } |
130 | 130 | ||
131 | update |= qset_add_qtds(whc, qset); | 131 | if (!qset->remove) |
132 | update |= qset_add_qtds(whc, qset); | ||
132 | 133 | ||
133 | done: | 134 | done: |
134 | /* | 135 | /* |
@@ -282,23 +283,29 @@ int pzl_urb_enqueue(struct whc *whc, struct urb *urb, gfp_t mem_flags) | |||
282 | 283 | ||
283 | spin_lock_irqsave(&whc->lock, flags); | 284 | spin_lock_irqsave(&whc->lock, flags); |
284 | 285 | ||
286 | err = usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
287 | if (err < 0) { | ||
288 | spin_unlock_irqrestore(&whc->lock, flags); | ||
289 | return err; | ||
290 | } | ||
291 | |||
285 | qset = get_qset(whc, urb, GFP_ATOMIC); | 292 | qset = get_qset(whc, urb, GFP_ATOMIC); |
286 | if (qset == NULL) | 293 | if (qset == NULL) |
287 | err = -ENOMEM; | 294 | err = -ENOMEM; |
288 | else | 295 | else |
289 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); | 296 | err = qset_add_urb(whc, qset, urb, GFP_ATOMIC); |
290 | if (!err) { | 297 | if (!err) { |
291 | usb_hcd_link_urb_to_ep(&whc->wusbhc.usb_hcd, urb); | ||
292 | if (!qset->in_sw_list) | 298 | if (!qset->in_sw_list) |
293 | qset_insert_in_sw_list(whc, qset); | 299 | qset_insert_in_sw_list(whc, qset); |
294 | } | 300 | } else |
301 | usb_hcd_unlink_urb_from_ep(&whc->wusbhc.usb_hcd, urb); | ||
295 | 302 | ||
296 | spin_unlock_irqrestore(&whc->lock, flags); | 303 | spin_unlock_irqrestore(&whc->lock, flags); |
297 | 304 | ||
298 | if (!err) | 305 | if (!err) |
299 | queue_work(whc->workqueue, &whc->periodic_work); | 306 | queue_work(whc->workqueue, &whc->periodic_work); |
300 | 307 | ||
301 | return 0; | 308 | return err; |
302 | } | 309 | } |
303 | 310 | ||
304 | /** | 311 | /** |
@@ -353,7 +360,6 @@ void pzl_qset_delete(struct whc *whc, struct whc_qset *qset) | |||
353 | qset_delete(whc, qset); | 360 | qset_delete(whc, qset); |
354 | } | 361 | } |
355 | 362 | ||
356 | |||
357 | /** | 363 | /** |
358 | * pzl_init - initialize the periodic zone list | 364 | * pzl_init - initialize the periodic zone list |
359 | * @whc: the WHCI host controller | 365 | * @whc: the WHCI host controller |
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 7be74314ee12..640b38fbd051 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c | |||
@@ -89,11 +89,16 @@ static void qset_fill_qh(struct whc_qset *qset, struct urb *urb) | |||
89 | QH_INFO3_TX_RATE_53_3 | 89 | QH_INFO3_TX_RATE_53_3 |
90 | | QH_INFO3_TX_PWR(0) /* 0 == max power */ | 90 | | QH_INFO3_TX_PWR(0) /* 0 == max power */ |
91 | ); | 91 | ); |
92 | |||
93 | qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1); | ||
92 | } | 94 | } |
93 | 95 | ||
94 | /** | 96 | /** |
95 | * qset_clear - clear fields in a qset so it may be reinserted into a | 97 | * qset_clear - clear fields in a qset so it may be reinserted into a |
96 | * schedule | 98 | * schedule. |
99 | * | ||
100 | * The sequence number and current window are not cleared (see | ||
101 | * qset_reset()). | ||
97 | */ | 102 | */ |
98 | void qset_clear(struct whc *whc, struct whc_qset *qset) | 103 | void qset_clear(struct whc *whc, struct whc_qset *qset) |
99 | { | 104 | { |
@@ -101,9 +106,8 @@ void qset_clear(struct whc *whc, struct whc_qset *qset) | |||
101 | qset->remove = 0; | 106 | qset->remove = 0; |
102 | 107 | ||
103 | qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T); | 108 | qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T); |
104 | qset->qh.status = cpu_to_le16(QH_STATUS_ICUR(qset->td_start)); | 109 | qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK; |
105 | qset->qh.err_count = 0; | 110 | qset->qh.err_count = 0; |
106 | qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1); | ||
107 | qset->qh.scratch[0] = 0; | 111 | qset->qh.scratch[0] = 0; |
108 | qset->qh.scratch[1] = 0; | 112 | qset->qh.scratch[1] = 0; |
109 | qset->qh.scratch[2] = 0; | 113 | qset->qh.scratch[2] = 0; |
@@ -114,6 +118,20 @@ void qset_clear(struct whc *whc, struct whc_qset *qset) | |||
114 | } | 118 | } |
115 | 119 | ||
116 | /** | 120 | /** |
121 | * qset_reset - reset endpoint state in a qset. | ||
122 | * | ||
123 | * Clears the sequence number and current window. This qset must not | ||
124 | * be in the ASL or PZL. | ||
125 | */ | ||
126 | void qset_reset(struct whc *whc, struct whc_qset *qset) | ||
127 | { | ||
128 | wait_for_completion(&qset->remove_complete); | ||
129 | |||
130 | qset->qh.status &= ~QH_STATUS_SEQ_MASK; | ||
131 | qset->qh.cur_window = cpu_to_le32((1 << qset->max_burst) - 1); | ||
132 | } | ||
133 | |||
134 | /** | ||
117 | * get_qset - get the qset for an async endpoint | 135 | * get_qset - get the qset for an async endpoint |
118 | * | 136 | * |
119 | * A new qset is created if one does not already exist. | 137 | * A new qset is created if one does not already exist. |
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index d3543a181dc9..24e94d983c5e 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h | |||
@@ -184,6 +184,7 @@ void qset_free(struct whc *whc, struct whc_qset *qset); | |||
184 | struct whc_qset *get_qset(struct whc *whc, struct urb *urb, gfp_t mem_flags); | 184 | struct whc_qset *get_qset(struct whc *whc, struct urb *urb, gfp_t mem_flags); |
185 | void qset_delete(struct whc *whc, struct whc_qset *qset); | 185 | void qset_delete(struct whc *whc, struct whc_qset *qset); |
186 | void qset_clear(struct whc *whc, struct whc_qset *qset); | 186 | void qset_clear(struct whc *whc, struct whc_qset *qset); |
187 | void qset_reset(struct whc *whc, struct whc_qset *qset); | ||
187 | int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb, | 188 | int qset_add_urb(struct whc *whc, struct whc_qset *qset, struct urb *urb, |
188 | gfp_t mem_flags); | 189 | gfp_t mem_flags); |
189 | void qset_free_std(struct whc *whc, struct whc_std *std); | 190 | void qset_free_std(struct whc *whc, struct whc_std *std); |
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h index 51df7e313b38..794dba0d0f0a 100644 --- a/drivers/usb/host/whci/whci-hc.h +++ b/drivers/usb/host/whci/whci-hc.h | |||
@@ -185,6 +185,7 @@ struct whc_qhead { | |||
185 | #define QH_STATUS_FLOW_CTRL (1 << 15) | 185 | #define QH_STATUS_FLOW_CTRL (1 << 15) |
186 | #define QH_STATUS_ICUR(i) ((i) << 5) | 186 | #define QH_STATUS_ICUR(i) ((i) << 5) |
187 | #define QH_STATUS_TO_ICUR(s) (((s) >> 5) & 0x7) | 187 | #define QH_STATUS_TO_ICUR(s) (((s) >> 5) & 0x7) |
188 | #define QH_STATUS_SEQ_MASK 0x1f | ||
188 | 189 | ||
189 | /** | 190 | /** |
190 | * usb_pipe_to_qh_type - USB core pipe type to QH transfer type | 191 | * usb_pipe_to_qh_type - USB core pipe type to QH transfer type |
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 569ef0fed0f6..1976e9b41800 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -579,6 +579,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx) | |||
579 | * trigger the "send a ZLP?" confusion. | 579 | * trigger the "send a ZLP?" confusion. |
580 | */ | 580 | */ |
581 | rndis = (maxpacket & 0x3f) == 0 | 581 | rndis = (maxpacket & 0x3f) == 0 |
582 | && length > maxpacket | ||
582 | && length < 0xffff | 583 | && length < 0xffff |
583 | && (length % maxpacket) != 0; | 584 | && (length % maxpacket) != 0; |
584 | 585 | ||
@@ -1228,27 +1229,7 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx) | |||
1228 | 1229 | ||
1229 | hw_ep = tx_ch->hw_ep; | 1230 | hw_ep = tx_ch->hw_ep; |
1230 | 1231 | ||
1231 | /* Peripheral role never repurposes the | 1232 | musb_dma_completion(musb, index + 1, 1); |
1232 | * endpoint, so immediate completion is | ||
1233 | * safe. Host role waits for the fifo | ||
1234 | * to empty (TXPKTRDY irq) before going | ||
1235 | * to the next queued bulk transfer. | ||
1236 | */ | ||
1237 | if (is_host_active(cppi->musb)) { | ||
1238 | #if 0 | ||
1239 | /* WORKAROUND because we may | ||
1240 | * not always get TXKPTRDY ... | ||
1241 | */ | ||
1242 | int csr; | ||
1243 | |||
1244 | csr = musb_readw(hw_ep->regs, | ||
1245 | MUSB_TXCSR); | ||
1246 | if (csr & MUSB_TXCSR_TXPKTRDY) | ||
1247 | #endif | ||
1248 | completed = false; | ||
1249 | } | ||
1250 | if (completed) | ||
1251 | musb_dma_completion(musb, index + 1, 1); | ||
1252 | 1233 | ||
1253 | } else { | 1234 | } else { |
1254 | /* Bigger transfer than we could fit in | 1235 | /* Bigger transfer than we could fit in |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 338cd1611ab3..4000cf6d1e81 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -2170,32 +2170,28 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message) | |||
2170 | return 0; | 2170 | return 0; |
2171 | } | 2171 | } |
2172 | 2172 | ||
2173 | static int musb_resume(struct platform_device *pdev) | 2173 | static int musb_resume_early(struct platform_device *pdev) |
2174 | { | 2174 | { |
2175 | unsigned long flags; | ||
2176 | struct musb *musb = dev_to_musb(&pdev->dev); | 2175 | struct musb *musb = dev_to_musb(&pdev->dev); |
2177 | 2176 | ||
2178 | if (!musb->clock) | 2177 | if (!musb->clock) |
2179 | return 0; | 2178 | return 0; |
2180 | 2179 | ||
2181 | spin_lock_irqsave(&musb->lock, flags); | ||
2182 | |||
2183 | if (musb->set_clock) | 2180 | if (musb->set_clock) |
2184 | musb->set_clock(musb->clock, 1); | 2181 | musb->set_clock(musb->clock, 1); |
2185 | else | 2182 | else |
2186 | clk_enable(musb->clock); | 2183 | clk_enable(musb->clock); |
2187 | 2184 | ||
2188 | /* for static cmos like DaVinci, register values were preserved | 2185 | /* for static cmos like DaVinci, register values were preserved |
2189 | * unless for some reason the whole soc powered down and we're | 2186 | * unless for some reason the whole soc powered down or the USB |
2190 | * not treating that as a whole-system restart (e.g. swsusp) | 2187 | * module got reset through the PSC (vs just being disabled). |
2191 | */ | 2188 | */ |
2192 | spin_unlock_irqrestore(&musb->lock, flags); | ||
2193 | return 0; | 2189 | return 0; |
2194 | } | 2190 | } |
2195 | 2191 | ||
2196 | #else | 2192 | #else |
2197 | #define musb_suspend NULL | 2193 | #define musb_suspend NULL |
2198 | #define musb_resume NULL | 2194 | #define musb_resume_early NULL |
2199 | #endif | 2195 | #endif |
2200 | 2196 | ||
2201 | static struct platform_driver musb_driver = { | 2197 | static struct platform_driver musb_driver = { |
@@ -2207,7 +2203,7 @@ static struct platform_driver musb_driver = { | |||
2207 | .remove = __devexit_p(musb_remove), | 2203 | .remove = __devexit_p(musb_remove), |
2208 | .shutdown = musb_shutdown, | 2204 | .shutdown = musb_shutdown, |
2209 | .suspend = musb_suspend, | 2205 | .suspend = musb_suspend, |
2210 | .resume = musb_resume, | 2206 | .resume_early = musb_resume_early, |
2211 | }; | 2207 | }; |
2212 | 2208 | ||
2213 | /*-------------------------------------------------------------------------*/ | 2209 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index c7ebd0867fcc..f79440cdfe7e 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -165,9 +165,15 @@ static void nuke(struct musb_ep *ep, const int status) | |||
165 | if (is_dma_capable() && ep->dma) { | 165 | if (is_dma_capable() && ep->dma) { |
166 | struct dma_controller *c = ep->musb->dma_controller; | 166 | struct dma_controller *c = ep->musb->dma_controller; |
167 | int value; | 167 | int value; |
168 | |||
168 | if (ep->is_in) { | 169 | if (ep->is_in) { |
170 | /* | ||
171 | * The programming guide says that we must not clear | ||
172 | * the DMAMODE bit before DMAENAB, so we only | ||
173 | * clear it in the second write... | ||
174 | */ | ||
169 | musb_writew(epio, MUSB_TXCSR, | 175 | musb_writew(epio, MUSB_TXCSR, |
170 | 0 | MUSB_TXCSR_FLUSHFIFO); | 176 | MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO); |
171 | musb_writew(epio, MUSB_TXCSR, | 177 | musb_writew(epio, MUSB_TXCSR, |
172 | 0 | MUSB_TXCSR_FLUSHFIFO); | 178 | 0 | MUSB_TXCSR_FLUSHFIFO); |
173 | } else { | 179 | } else { |
@@ -230,7 +236,7 @@ static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep) | |||
230 | | IN token(s) are recd from Host. | 236 | | IN token(s) are recd from Host. |
231 | | -> DMA interrupt on completion | 237 | | -> DMA interrupt on completion |
232 | | calls TxAvail. | 238 | | calls TxAvail. |
233 | | -> stop DMA, ~DmaEenab, | 239 | | -> stop DMA, ~DMAENAB, |
234 | | -> set TxPktRdy for last short pkt or zlp | 240 | | -> set TxPktRdy for last short pkt or zlp |
235 | | -> Complete Request | 241 | | -> Complete Request |
236 | | -> Continue next request (call txstate) | 242 | | -> Continue next request (call txstate) |
@@ -315,9 +321,17 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
315 | request->dma, request_size); | 321 | request->dma, request_size); |
316 | if (use_dma) { | 322 | if (use_dma) { |
317 | if (musb_ep->dma->desired_mode == 0) { | 323 | if (musb_ep->dma->desired_mode == 0) { |
318 | /* ASSERT: DMAENAB is clear */ | 324 | /* |
319 | csr &= ~(MUSB_TXCSR_AUTOSET | | 325 | * We must not clear the DMAMODE bit |
320 | MUSB_TXCSR_DMAMODE); | 326 | * before the DMAENAB bit -- and the |
327 | * latter doesn't always get cleared | ||
328 | * before we get here... | ||
329 | */ | ||
330 | csr &= ~(MUSB_TXCSR_AUTOSET | ||
331 | | MUSB_TXCSR_DMAENAB); | ||
332 | musb_writew(epio, MUSB_TXCSR, csr | ||
333 | | MUSB_TXCSR_P_WZC_BITS); | ||
334 | csr &= ~MUSB_TXCSR_DMAMODE; | ||
321 | csr |= (MUSB_TXCSR_DMAENAB | | 335 | csr |= (MUSB_TXCSR_DMAENAB | |
322 | MUSB_TXCSR_MODE); | 336 | MUSB_TXCSR_MODE); |
323 | /* against programming guide */ | 337 | /* against programming guide */ |
@@ -334,10 +348,7 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
334 | 348 | ||
335 | #elif defined(CONFIG_USB_TI_CPPI_DMA) | 349 | #elif defined(CONFIG_USB_TI_CPPI_DMA) |
336 | /* program endpoint CSR first, then setup DMA */ | 350 | /* program endpoint CSR first, then setup DMA */ |
337 | csr &= ~(MUSB_TXCSR_AUTOSET | 351 | csr &= ~(MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY); |
338 | | MUSB_TXCSR_DMAMODE | ||
339 | | MUSB_TXCSR_P_UNDERRUN | ||
340 | | MUSB_TXCSR_TXPKTRDY); | ||
341 | csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB; | 352 | csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB; |
342 | musb_writew(epio, MUSB_TXCSR, | 353 | musb_writew(epio, MUSB_TXCSR, |
343 | (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN) | 354 | (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN) |
@@ -364,8 +375,8 @@ static void txstate(struct musb *musb, struct musb_request *req) | |||
364 | if (!use_dma) { | 375 | if (!use_dma) { |
365 | c->channel_release(musb_ep->dma); | 376 | c->channel_release(musb_ep->dma); |
366 | musb_ep->dma = NULL; | 377 | musb_ep->dma = NULL; |
367 | /* ASSERT: DMAENAB clear */ | 378 | csr &= ~MUSB_TXCSR_DMAENAB; |
368 | csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE); | 379 | musb_writew(epio, MUSB_TXCSR, csr); |
369 | /* invariant: prequest->buf is non-null */ | 380 | /* invariant: prequest->buf is non-null */ |
370 | } | 381 | } |
371 | #elif defined(CONFIG_USB_TUSB_OMAP_DMA) | 382 | #elif defined(CONFIG_USB_TUSB_OMAP_DMA) |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 499c431a6d62..db1b57415ec7 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Copyright 2005 Mentor Graphics Corporation | 4 | * Copyright 2005 Mentor Graphics Corporation |
5 | * Copyright (C) 2005-2006 by Texas Instruments | 5 | * Copyright (C) 2005-2006 by Texas Instruments |
6 | * Copyright (C) 2006-2007 Nokia Corporation | 6 | * Copyright (C) 2006-2007 Nokia Corporation |
7 | * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com> | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
@@ -96,8 +97,8 @@ | |||
96 | 97 | ||
97 | 98 | ||
98 | static void musb_ep_program(struct musb *musb, u8 epnum, | 99 | static void musb_ep_program(struct musb *musb, u8 epnum, |
99 | struct urb *urb, unsigned int nOut, | 100 | struct urb *urb, int is_out, |
100 | u8 *buf, u32 len); | 101 | u8 *buf, u32 offset, u32 len); |
101 | 102 | ||
102 | /* | 103 | /* |
103 | * Clear TX fifo. Needed to avoid BABBLE errors. | 104 | * Clear TX fifo. Needed to avoid BABBLE errors. |
@@ -125,6 +126,29 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) | |||
125 | } | 126 | } |
126 | } | 127 | } |
127 | 128 | ||
129 | static void musb_h_ep0_flush_fifo(struct musb_hw_ep *ep) | ||
130 | { | ||
131 | void __iomem *epio = ep->regs; | ||
132 | u16 csr; | ||
133 | int retries = 5; | ||
134 | |||
135 | /* scrub any data left in the fifo */ | ||
136 | do { | ||
137 | csr = musb_readw(epio, MUSB_TXCSR); | ||
138 | if (!(csr & (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_RXPKTRDY))) | ||
139 | break; | ||
140 | musb_writew(epio, MUSB_TXCSR, MUSB_CSR0_FLUSHFIFO); | ||
141 | csr = musb_readw(epio, MUSB_TXCSR); | ||
142 | udelay(10); | ||
143 | } while (--retries); | ||
144 | |||
145 | WARN(!retries, "Could not flush host TX%d fifo: csr: %04x\n", | ||
146 | ep->epnum, csr); | ||
147 | |||
148 | /* and reset for the next transfer */ | ||
149 | musb_writew(epio, MUSB_TXCSR, 0); | ||
150 | } | ||
151 | |||
128 | /* | 152 | /* |
129 | * Start transmit. Caller is responsible for locking shared resources. | 153 | * Start transmit. Caller is responsible for locking shared resources. |
130 | * musb must be locked. | 154 | * musb must be locked. |
@@ -145,13 +169,15 @@ static inline void musb_h_tx_start(struct musb_hw_ep *ep) | |||
145 | 169 | ||
146 | } | 170 | } |
147 | 171 | ||
148 | static inline void cppi_host_txdma_start(struct musb_hw_ep *ep) | 172 | static inline void musb_h_tx_dma_start(struct musb_hw_ep *ep) |
149 | { | 173 | { |
150 | u16 txcsr; | 174 | u16 txcsr; |
151 | 175 | ||
152 | /* NOTE: no locks here; caller should lock and select EP */ | 176 | /* NOTE: no locks here; caller should lock and select EP */ |
153 | txcsr = musb_readw(ep->regs, MUSB_TXCSR); | 177 | txcsr = musb_readw(ep->regs, MUSB_TXCSR); |
154 | txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS; | 178 | txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS; |
179 | if (is_cppi_enabled()) | ||
180 | txcsr |= MUSB_TXCSR_DMAMODE; | ||
155 | musb_writew(ep->regs, MUSB_TXCSR, txcsr); | 181 | musb_writew(ep->regs, MUSB_TXCSR, txcsr); |
156 | } | 182 | } |
157 | 183 | ||
@@ -166,9 +192,10 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
166 | { | 192 | { |
167 | u16 frame; | 193 | u16 frame; |
168 | u32 len; | 194 | u32 len; |
169 | void *buf; | ||
170 | void __iomem *mbase = musb->mregs; | 195 | void __iomem *mbase = musb->mregs; |
171 | struct urb *urb = next_urb(qh); | 196 | struct urb *urb = next_urb(qh); |
197 | void *buf = urb->transfer_buffer; | ||
198 | u32 offset = 0; | ||
172 | struct musb_hw_ep *hw_ep = qh->hw_ep; | 199 | struct musb_hw_ep *hw_ep = qh->hw_ep; |
173 | unsigned pipe = urb->pipe; | 200 | unsigned pipe = urb->pipe; |
174 | u8 address = usb_pipedevice(pipe); | 201 | u8 address = usb_pipedevice(pipe); |
@@ -191,7 +218,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
191 | case USB_ENDPOINT_XFER_ISOC: | 218 | case USB_ENDPOINT_XFER_ISOC: |
192 | qh->iso_idx = 0; | 219 | qh->iso_idx = 0; |
193 | qh->frame = 0; | 220 | qh->frame = 0; |
194 | buf = urb->transfer_buffer + urb->iso_frame_desc[0].offset; | 221 | offset = urb->iso_frame_desc[0].offset; |
195 | len = urb->iso_frame_desc[0].length; | 222 | len = urb->iso_frame_desc[0].length; |
196 | break; | 223 | break; |
197 | default: /* bulk, interrupt */ | 224 | default: /* bulk, interrupt */ |
@@ -209,14 +236,14 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
209 | case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break; | 236 | case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break; |
210 | default: s = "-intr"; break; | 237 | default: s = "-intr"; break; |
211 | }; s; }), | 238 | }; s; }), |
212 | epnum, buf, len); | 239 | epnum, buf + offset, len); |
213 | 240 | ||
214 | /* Configure endpoint */ | 241 | /* Configure endpoint */ |
215 | if (is_in || hw_ep->is_shared_fifo) | 242 | if (is_in || hw_ep->is_shared_fifo) |
216 | hw_ep->in_qh = qh; | 243 | hw_ep->in_qh = qh; |
217 | else | 244 | else |
218 | hw_ep->out_qh = qh; | 245 | hw_ep->out_qh = qh; |
219 | musb_ep_program(musb, epnum, urb, !is_in, buf, len); | 246 | musb_ep_program(musb, epnum, urb, !is_in, buf, offset, len); |
220 | 247 | ||
221 | /* transmit may have more work: start it when it is time */ | 248 | /* transmit may have more work: start it when it is time */ |
222 | if (is_in) | 249 | if (is_in) |
@@ -227,7 +254,6 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
227 | case USB_ENDPOINT_XFER_ISOC: | 254 | case USB_ENDPOINT_XFER_ISOC: |
228 | case USB_ENDPOINT_XFER_INT: | 255 | case USB_ENDPOINT_XFER_INT: |
229 | DBG(3, "check whether there's still time for periodic Tx\n"); | 256 | DBG(3, "check whether there's still time for periodic Tx\n"); |
230 | qh->iso_idx = 0; | ||
231 | frame = musb_readw(mbase, MUSB_FRAME); | 257 | frame = musb_readw(mbase, MUSB_FRAME); |
232 | /* FIXME this doesn't implement that scheduling policy ... | 258 | /* FIXME this doesn't implement that scheduling policy ... |
233 | * or handle framecounter wrapping | 259 | * or handle framecounter wrapping |
@@ -256,7 +282,7 @@ start: | |||
256 | if (!hw_ep->tx_channel) | 282 | if (!hw_ep->tx_channel) |
257 | musb_h_tx_start(hw_ep); | 283 | musb_h_tx_start(hw_ep); |
258 | else if (is_cppi_enabled() || tusb_dma_omap()) | 284 | else if (is_cppi_enabled() || tusb_dma_omap()) |
259 | cppi_host_txdma_start(hw_ep); | 285 | musb_h_tx_dma_start(hw_ep); |
260 | } | 286 | } |
261 | } | 287 | } |
262 | 288 | ||
@@ -567,10 +593,17 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
567 | csr = musb_readw(ep->regs, MUSB_TXCSR); | 593 | csr = musb_readw(ep->regs, MUSB_TXCSR); |
568 | if (csr & MUSB_TXCSR_MODE) { | 594 | if (csr & MUSB_TXCSR_MODE) { |
569 | musb_h_tx_flush_fifo(ep); | 595 | musb_h_tx_flush_fifo(ep); |
596 | csr = musb_readw(ep->regs, MUSB_TXCSR); | ||
570 | musb_writew(ep->regs, MUSB_TXCSR, | 597 | musb_writew(ep->regs, MUSB_TXCSR, |
571 | MUSB_TXCSR_FRCDATATOG); | 598 | csr | MUSB_TXCSR_FRCDATATOG); |
572 | } | 599 | } |
573 | /* clear mode (and everything else) to enable Rx */ | 600 | |
601 | /* | ||
602 | * Clear the MODE bit (and everything else) to enable Rx. | ||
603 | * NOTE: we mustn't clear the DMAMODE bit before DMAENAB. | ||
604 | */ | ||
605 | if (csr & MUSB_TXCSR_DMAMODE) | ||
606 | musb_writew(ep->regs, MUSB_TXCSR, MUSB_TXCSR_DMAMODE); | ||
574 | musb_writew(ep->regs, MUSB_TXCSR, 0); | 607 | musb_writew(ep->regs, MUSB_TXCSR, 0); |
575 | 608 | ||
576 | /* scrub all previous state, clearing toggle */ | 609 | /* scrub all previous state, clearing toggle */ |
@@ -601,14 +634,68 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
601 | ep->rx_reinit = 0; | 634 | ep->rx_reinit = 0; |
602 | } | 635 | } |
603 | 636 | ||
637 | static bool musb_tx_dma_program(struct dma_controller *dma, | ||
638 | struct musb_hw_ep *hw_ep, struct musb_qh *qh, | ||
639 | struct urb *urb, u32 offset, u32 length) | ||
640 | { | ||
641 | struct dma_channel *channel = hw_ep->tx_channel; | ||
642 | void __iomem *epio = hw_ep->regs; | ||
643 | u16 pkt_size = qh->maxpacket; | ||
644 | u16 csr; | ||
645 | u8 mode; | ||
646 | |||
647 | #ifdef CONFIG_USB_INVENTRA_DMA | ||
648 | if (length > channel->max_len) | ||
649 | length = channel->max_len; | ||
650 | |||
651 | csr = musb_readw(epio, MUSB_TXCSR); | ||
652 | if (length > pkt_size) { | ||
653 | mode = 1; | ||
654 | csr |= MUSB_TXCSR_AUTOSET | ||
655 | | MUSB_TXCSR_DMAMODE | ||
656 | | MUSB_TXCSR_DMAENAB; | ||
657 | } else { | ||
658 | mode = 0; | ||
659 | csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE); | ||
660 | csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */ | ||
661 | } | ||
662 | channel->desired_mode = mode; | ||
663 | musb_writew(epio, MUSB_TXCSR, csr); | ||
664 | #else | ||
665 | if (!is_cppi_enabled() && !tusb_dma_omap()) | ||
666 | return false; | ||
667 | |||
668 | channel->actual_len = 0; | ||
669 | |||
670 | /* | ||
671 | * TX uses "RNDIS" mode automatically but needs help | ||
672 | * to identify the zero-length-final-packet case. | ||
673 | */ | ||
674 | mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0; | ||
675 | #endif | ||
676 | |||
677 | qh->segsize = length; | ||
678 | |||
679 | if (!dma->channel_program(channel, pkt_size, mode, | ||
680 | urb->transfer_dma + offset, length)) { | ||
681 | dma->channel_release(channel); | ||
682 | hw_ep->tx_channel = NULL; | ||
683 | |||
684 | csr = musb_readw(epio, MUSB_TXCSR); | ||
685 | csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB); | ||
686 | musb_writew(epio, MUSB_TXCSR, csr | MUSB_TXCSR_H_WZC_BITS); | ||
687 | return false; | ||
688 | } | ||
689 | return true; | ||
690 | } | ||
604 | 691 | ||
605 | /* | 692 | /* |
606 | * Program an HDRC endpoint as per the given URB | 693 | * Program an HDRC endpoint as per the given URB |
607 | * Context: irqs blocked, controller lock held | 694 | * Context: irqs blocked, controller lock held |
608 | */ | 695 | */ |
609 | static void musb_ep_program(struct musb *musb, u8 epnum, | 696 | static void musb_ep_program(struct musb *musb, u8 epnum, |
610 | struct urb *urb, unsigned int is_out, | 697 | struct urb *urb, int is_out, |
611 | u8 *buf, u32 len) | 698 | u8 *buf, u32 offset, u32 len) |
612 | { | 699 | { |
613 | struct dma_controller *dma_controller; | 700 | struct dma_controller *dma_controller; |
614 | struct dma_channel *dma_channel; | 701 | struct dma_channel *dma_channel; |
@@ -667,12 +754,17 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
667 | 754 | ||
668 | /* general endpoint setup */ | 755 | /* general endpoint setup */ |
669 | if (epnum) { | 756 | if (epnum) { |
670 | /* ASSERT: TXCSR_DMAENAB was already cleared */ | ||
671 | |||
672 | /* flush all old state, set default */ | 757 | /* flush all old state, set default */ |
673 | musb_h_tx_flush_fifo(hw_ep); | 758 | musb_h_tx_flush_fifo(hw_ep); |
759 | |||
760 | /* | ||
761 | * We must not clear the DMAMODE bit before or in | ||
762 | * the same cycle with the DMAENAB bit, so we clear | ||
763 | * the latter first... | ||
764 | */ | ||
674 | csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT | 765 | csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT |
675 | | MUSB_TXCSR_DMAMODE | 766 | | MUSB_TXCSR_AUTOSET |
767 | | MUSB_TXCSR_DMAENAB | ||
676 | | MUSB_TXCSR_FRCDATATOG | 768 | | MUSB_TXCSR_FRCDATATOG |
677 | | MUSB_TXCSR_H_RXSTALL | 769 | | MUSB_TXCSR_H_RXSTALL |
678 | | MUSB_TXCSR_H_ERROR | 770 | | MUSB_TXCSR_H_ERROR |
@@ -680,24 +772,20 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
680 | ); | 772 | ); |
681 | csr |= MUSB_TXCSR_MODE; | 773 | csr |= MUSB_TXCSR_MODE; |
682 | 774 | ||
683 | if (usb_gettoggle(urb->dev, | 775 | if (usb_gettoggle(urb->dev, qh->epnum, 1)) |
684 | qh->epnum, 1)) | ||
685 | csr |= MUSB_TXCSR_H_WR_DATATOGGLE | 776 | csr |= MUSB_TXCSR_H_WR_DATATOGGLE |
686 | | MUSB_TXCSR_H_DATATOGGLE; | 777 | | MUSB_TXCSR_H_DATATOGGLE; |
687 | else | 778 | else |
688 | csr |= MUSB_TXCSR_CLRDATATOG; | 779 | csr |= MUSB_TXCSR_CLRDATATOG; |
689 | 780 | ||
690 | /* twice in case of double packet buffering */ | ||
691 | musb_writew(epio, MUSB_TXCSR, csr); | 781 | musb_writew(epio, MUSB_TXCSR, csr); |
692 | /* REVISIT may need to clear FLUSHFIFO ... */ | 782 | /* REVISIT may need to clear FLUSHFIFO ... */ |
783 | csr &= ~MUSB_TXCSR_DMAMODE; | ||
693 | musb_writew(epio, MUSB_TXCSR, csr); | 784 | musb_writew(epio, MUSB_TXCSR, csr); |
694 | csr = musb_readw(epio, MUSB_TXCSR); | 785 | csr = musb_readw(epio, MUSB_TXCSR); |
695 | } else { | 786 | } else { |
696 | /* endpoint 0: just flush */ | 787 | /* endpoint 0: just flush */ |
697 | musb_writew(epio, MUSB_CSR0, | 788 | musb_h_ep0_flush_fifo(hw_ep); |
698 | csr | MUSB_CSR0_FLUSHFIFO); | ||
699 | musb_writew(epio, MUSB_CSR0, | ||
700 | csr | MUSB_CSR0_FLUSHFIFO); | ||
701 | } | 789 | } |
702 | 790 | ||
703 | /* target addr and (for multipoint) hub addr/port */ | 791 | /* target addr and (for multipoint) hub addr/port */ |
@@ -734,113 +822,14 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
734 | else | 822 | else |
735 | load_count = min((u32) packet_sz, len); | 823 | load_count = min((u32) packet_sz, len); |
736 | 824 | ||
737 | #ifdef CONFIG_USB_INVENTRA_DMA | 825 | if (dma_channel && musb_tx_dma_program(dma_controller, |
738 | if (dma_channel) { | 826 | hw_ep, qh, urb, offset, len)) |
739 | 827 | load_count = 0; | |
740 | /* clear previous state */ | ||
741 | csr = musb_readw(epio, MUSB_TXCSR); | ||
742 | csr &= ~(MUSB_TXCSR_AUTOSET | ||
743 | | MUSB_TXCSR_DMAMODE | ||
744 | | MUSB_TXCSR_DMAENAB); | ||
745 | csr |= MUSB_TXCSR_MODE; | ||
746 | musb_writew(epio, MUSB_TXCSR, | ||
747 | csr | MUSB_TXCSR_MODE); | ||
748 | |||
749 | qh->segsize = min(len, dma_channel->max_len); | ||
750 | |||
751 | if (qh->segsize <= packet_sz) | ||
752 | dma_channel->desired_mode = 0; | ||
753 | else | ||
754 | dma_channel->desired_mode = 1; | ||
755 | |||
756 | |||
757 | if (dma_channel->desired_mode == 0) { | ||
758 | csr &= ~(MUSB_TXCSR_AUTOSET | ||
759 | | MUSB_TXCSR_DMAMODE); | ||
760 | csr |= (MUSB_TXCSR_DMAENAB); | ||
761 | /* against programming guide */ | ||
762 | } else | ||
763 | csr |= (MUSB_TXCSR_AUTOSET | ||
764 | | MUSB_TXCSR_DMAENAB | ||
765 | | MUSB_TXCSR_DMAMODE); | ||
766 | |||
767 | musb_writew(epio, MUSB_TXCSR, csr); | ||
768 | |||
769 | dma_ok = dma_controller->channel_program( | ||
770 | dma_channel, packet_sz, | ||
771 | dma_channel->desired_mode, | ||
772 | urb->transfer_dma, | ||
773 | qh->segsize); | ||
774 | if (dma_ok) { | ||
775 | load_count = 0; | ||
776 | } else { | ||
777 | dma_controller->channel_release(dma_channel); | ||
778 | if (is_out) | ||
779 | hw_ep->tx_channel = NULL; | ||
780 | else | ||
781 | hw_ep->rx_channel = NULL; | ||
782 | dma_channel = NULL; | ||
783 | } | ||
784 | } | ||
785 | #endif | ||
786 | |||
787 | /* candidate for DMA */ | ||
788 | if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) { | ||
789 | |||
790 | /* program endpoint CSRs first, then setup DMA. | ||
791 | * assume CPPI setup succeeds. | ||
792 | * defer enabling dma. | ||
793 | */ | ||
794 | csr = musb_readw(epio, MUSB_TXCSR); | ||
795 | csr &= ~(MUSB_TXCSR_AUTOSET | ||
796 | | MUSB_TXCSR_DMAMODE | ||
797 | | MUSB_TXCSR_DMAENAB); | ||
798 | csr |= MUSB_TXCSR_MODE; | ||
799 | musb_writew(epio, MUSB_TXCSR, | ||
800 | csr | MUSB_TXCSR_MODE); | ||
801 | |||
802 | dma_channel->actual_len = 0L; | ||
803 | qh->segsize = len; | ||
804 | |||
805 | /* TX uses "rndis" mode automatically, but needs help | ||
806 | * to identify the zero-length-final-packet case. | ||
807 | */ | ||
808 | dma_ok = dma_controller->channel_program( | ||
809 | dma_channel, packet_sz, | ||
810 | (urb->transfer_flags | ||
811 | & URB_ZERO_PACKET) | ||
812 | == URB_ZERO_PACKET, | ||
813 | urb->transfer_dma, | ||
814 | qh->segsize); | ||
815 | if (dma_ok) { | ||
816 | load_count = 0; | ||
817 | } else { | ||
818 | dma_controller->channel_release(dma_channel); | ||
819 | hw_ep->tx_channel = NULL; | ||
820 | dma_channel = NULL; | ||
821 | |||
822 | /* REVISIT there's an error path here that | ||
823 | * needs handling: can't do dma, but | ||
824 | * there's no pio buffer address... | ||
825 | */ | ||
826 | } | ||
827 | } | ||
828 | 828 | ||
829 | if (load_count) { | 829 | if (load_count) { |
830 | /* ASSERT: TXCSR_DMAENAB was already cleared */ | ||
831 | |||
832 | /* PIO to load FIFO */ | 830 | /* PIO to load FIFO */ |
833 | qh->segsize = load_count; | 831 | qh->segsize = load_count; |
834 | musb_write_fifo(hw_ep, load_count, buf); | 832 | musb_write_fifo(hw_ep, load_count, buf); |
835 | csr = musb_readw(epio, MUSB_TXCSR); | ||
836 | csr &= ~(MUSB_TXCSR_DMAENAB | ||
837 | | MUSB_TXCSR_DMAMODE | ||
838 | | MUSB_TXCSR_AUTOSET); | ||
839 | /* write CSR */ | ||
840 | csr |= MUSB_TXCSR_MODE; | ||
841 | |||
842 | if (epnum) | ||
843 | musb_writew(epio, MUSB_TXCSR, csr); | ||
844 | } | 833 | } |
845 | 834 | ||
846 | /* re-enable interrupt */ | 835 | /* re-enable interrupt */ |
@@ -895,7 +884,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
895 | dma_channel, packet_sz, | 884 | dma_channel, packet_sz, |
896 | !(urb->transfer_flags | 885 | !(urb->transfer_flags |
897 | & URB_SHORT_NOT_OK), | 886 | & URB_SHORT_NOT_OK), |
898 | urb->transfer_dma, | 887 | urb->transfer_dma + offset, |
899 | qh->segsize); | 888 | qh->segsize); |
900 | if (!dma_ok) { | 889 | if (!dma_ok) { |
901 | dma_controller->channel_release( | 890 | dma_controller->channel_release( |
@@ -1063,11 +1052,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
1063 | csr &= ~MUSB_CSR0_H_NAKTIMEOUT; | 1052 | csr &= ~MUSB_CSR0_H_NAKTIMEOUT; |
1064 | musb_writew(epio, MUSB_CSR0, csr); | 1053 | musb_writew(epio, MUSB_CSR0, csr); |
1065 | } else { | 1054 | } else { |
1066 | csr |= MUSB_CSR0_FLUSHFIFO; | 1055 | musb_h_ep0_flush_fifo(hw_ep); |
1067 | musb_writew(epio, MUSB_CSR0, csr); | ||
1068 | musb_writew(epio, MUSB_CSR0, csr); | ||
1069 | csr &= ~MUSB_CSR0_H_NAKTIMEOUT; | ||
1070 | musb_writew(epio, MUSB_CSR0, csr); | ||
1071 | } | 1056 | } |
1072 | 1057 | ||
1073 | musb_writeb(epio, MUSB_NAKLIMIT0, 0); | 1058 | musb_writeb(epio, MUSB_NAKLIMIT0, 0); |
@@ -1081,10 +1066,7 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
1081 | * SHOULD NEVER HAPPEN! */ | 1066 | * SHOULD NEVER HAPPEN! */ |
1082 | ERR("no URB for end 0\n"); | 1067 | ERR("no URB for end 0\n"); |
1083 | 1068 | ||
1084 | musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO); | 1069 | musb_h_ep0_flush_fifo(hw_ep); |
1085 | musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO); | ||
1086 | musb_writew(epio, MUSB_CSR0, 0); | ||
1087 | |||
1088 | goto done; | 1070 | goto done; |
1089 | } | 1071 | } |
1090 | 1072 | ||
@@ -1145,8 +1127,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1145 | int pipe; | 1127 | int pipe; |
1146 | bool done = false; | 1128 | bool done = false; |
1147 | u16 tx_csr; | 1129 | u16 tx_csr; |
1148 | size_t wLength = 0; | 1130 | size_t length = 0; |
1149 | u8 *buf = NULL; | 1131 | size_t offset = 0; |
1150 | struct urb *urb; | 1132 | struct urb *urb; |
1151 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; | 1133 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; |
1152 | void __iomem *epio = hw_ep->regs; | 1134 | void __iomem *epio = hw_ep->regs; |
@@ -1164,7 +1146,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1164 | /* with CPPI, DMA sometimes triggers "extra" irqs */ | 1146 | /* with CPPI, DMA sometimes triggers "extra" irqs */ |
1165 | if (!urb) { | 1147 | if (!urb) { |
1166 | DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); | 1148 | DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); |
1167 | goto finish; | 1149 | return; |
1168 | } | 1150 | } |
1169 | 1151 | ||
1170 | pipe = urb->pipe; | 1152 | pipe = urb->pipe; |
@@ -1201,7 +1183,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1201 | musb_writew(epio, MUSB_TXCSR, | 1183 | musb_writew(epio, MUSB_TXCSR, |
1202 | MUSB_TXCSR_H_WZC_BITS | 1184 | MUSB_TXCSR_H_WZC_BITS |
1203 | | MUSB_TXCSR_TXPKTRDY); | 1185 | | MUSB_TXCSR_TXPKTRDY); |
1204 | goto finish; | 1186 | return; |
1205 | } | 1187 | } |
1206 | 1188 | ||
1207 | if (status) { | 1189 | if (status) { |
@@ -1233,29 +1215,89 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1233 | /* second cppi case */ | 1215 | /* second cppi case */ |
1234 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | 1216 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { |
1235 | DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); | 1217 | DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); |
1236 | goto finish; | 1218 | return; |
1219 | } | ||
1220 | |||
1221 | if (is_dma_capable() && dma && !status) { | ||
1222 | /* | ||
1223 | * DMA has completed. But if we're using DMA mode 1 (multi | ||
1224 | * packet DMA), we need a terminal TXPKTRDY interrupt before | ||
1225 | * we can consider this transfer completed, lest we trash | ||
1226 | * its last packet when writing the next URB's data. So we | ||
1227 | * switch back to mode 0 to get that interrupt; we'll come | ||
1228 | * back here once it happens. | ||
1229 | */ | ||
1230 | if (tx_csr & MUSB_TXCSR_DMAMODE) { | ||
1231 | /* | ||
1232 | * We shouldn't clear DMAMODE with DMAENAB set; so | ||
1233 | * clear them in a safe order. That should be OK | ||
1234 | * once TXPKTRDY has been set (and I've never seen | ||
1235 | * it being 0 at this moment -- DMA interrupt latency | ||
1236 | * is significant) but if it hasn't been then we have | ||
1237 | * no choice but to stop being polite and ignore the | ||
1238 | * programmer's guide... :-) | ||
1239 | * | ||
1240 | * Note that we must write TXCSR with TXPKTRDY cleared | ||
1241 | * in order not to re-trigger the packet send (this bit | ||
1242 | * can't be cleared by CPU), and there's another caveat: | ||
1243 | * TXPKTRDY may be set shortly and then cleared in the | ||
1244 | * double-buffered FIFO mode, so we do an extra TXCSR | ||
1245 | * read for debouncing... | ||
1246 | */ | ||
1247 | tx_csr &= musb_readw(epio, MUSB_TXCSR); | ||
1248 | if (tx_csr & MUSB_TXCSR_TXPKTRDY) { | ||
1249 | tx_csr &= ~(MUSB_TXCSR_DMAENAB | | ||
1250 | MUSB_TXCSR_TXPKTRDY); | ||
1251 | musb_writew(epio, MUSB_TXCSR, | ||
1252 | tx_csr | MUSB_TXCSR_H_WZC_BITS); | ||
1253 | } | ||
1254 | tx_csr &= ~(MUSB_TXCSR_DMAMODE | | ||
1255 | MUSB_TXCSR_TXPKTRDY); | ||
1256 | musb_writew(epio, MUSB_TXCSR, | ||
1257 | tx_csr | MUSB_TXCSR_H_WZC_BITS); | ||
1258 | |||
1259 | /* | ||
1260 | * There is no guarantee that we'll get an interrupt | ||
1261 | * after clearing DMAMODE as we might have done this | ||
1262 | * too late (after TXPKTRDY was cleared by controller). | ||
1263 | * Re-read TXCSR as we have spoiled its previous value. | ||
1264 | */ | ||
1265 | tx_csr = musb_readw(epio, MUSB_TXCSR); | ||
1266 | } | ||
1237 | 1267 | ||
1268 | /* | ||
1269 | * We may get here from a DMA completion or TXPKTRDY interrupt. | ||
1270 | * In any case, we must check the FIFO status here and bail out | ||
1271 | * only if the FIFO still has data -- that should prevent the | ||
1272 | * "missed" TXPKTRDY interrupts and deal with double-buffered | ||
1273 | * FIFO mode too... | ||
1274 | */ | ||
1275 | if (tx_csr & (MUSB_TXCSR_FIFONOTEMPTY | MUSB_TXCSR_TXPKTRDY)) { | ||
1276 | DBG(2, "DMA complete but packet still in FIFO, " | ||
1277 | "CSR %04x\n", tx_csr); | ||
1278 | return; | ||
1279 | } | ||
1238 | } | 1280 | } |
1239 | 1281 | ||
1240 | /* REVISIT this looks wrong... */ | ||
1241 | if (!status || dma || usb_pipeisoc(pipe)) { | 1282 | if (!status || dma || usb_pipeisoc(pipe)) { |
1242 | if (dma) | 1283 | if (dma) |
1243 | wLength = dma->actual_len; | 1284 | length = dma->actual_len; |
1244 | else | 1285 | else |
1245 | wLength = qh->segsize; | 1286 | length = qh->segsize; |
1246 | qh->offset += wLength; | 1287 | qh->offset += length; |
1247 | 1288 | ||
1248 | if (usb_pipeisoc(pipe)) { | 1289 | if (usb_pipeisoc(pipe)) { |
1249 | struct usb_iso_packet_descriptor *d; | 1290 | struct usb_iso_packet_descriptor *d; |
1250 | 1291 | ||
1251 | d = urb->iso_frame_desc + qh->iso_idx; | 1292 | d = urb->iso_frame_desc + qh->iso_idx; |
1252 | d->actual_length = qh->segsize; | 1293 | d->actual_length = length; |
1294 | d->status = status; | ||
1253 | if (++qh->iso_idx >= urb->number_of_packets) { | 1295 | if (++qh->iso_idx >= urb->number_of_packets) { |
1254 | done = true; | 1296 | done = true; |
1255 | } else { | 1297 | } else { |
1256 | d++; | 1298 | d++; |
1257 | buf = urb->transfer_buffer + d->offset; | 1299 | offset = d->offset; |
1258 | wLength = d->length; | 1300 | length = d->length; |
1259 | } | 1301 | } |
1260 | } else if (dma) { | 1302 | } else if (dma) { |
1261 | done = true; | 1303 | done = true; |
@@ -1268,10 +1310,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1268 | & URB_ZERO_PACKET)) | 1310 | & URB_ZERO_PACKET)) |
1269 | done = true; | 1311 | done = true; |
1270 | if (!done) { | 1312 | if (!done) { |
1271 | buf = urb->transfer_buffer | 1313 | offset = qh->offset; |
1272 | + qh->offset; | 1314 | length = urb->transfer_buffer_length - offset; |
1273 | wLength = urb->transfer_buffer_length | ||
1274 | - qh->offset; | ||
1275 | } | 1315 | } |
1276 | } | 1316 | } |
1277 | } | 1317 | } |
@@ -1290,28 +1330,31 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1290 | urb->status = status; | 1330 | urb->status = status; |
1291 | urb->actual_length = qh->offset; | 1331 | urb->actual_length = qh->offset; |
1292 | musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT); | 1332 | musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT); |
1333 | return; | ||
1334 | } else if (usb_pipeisoc(pipe) && dma) { | ||
1335 | if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb, | ||
1336 | offset, length)) | ||
1337 | return; | ||
1338 | } else if (tx_csr & MUSB_TXCSR_DMAENAB) { | ||
1339 | DBG(1, "not complete, but DMA enabled?\n"); | ||
1340 | return; | ||
1341 | } | ||
1293 | 1342 | ||
1294 | } else if (!(tx_csr & MUSB_TXCSR_DMAENAB)) { | 1343 | /* |
1295 | /* WARN_ON(!buf); */ | 1344 | * PIO: start next packet in this URB. |
1296 | 1345 | * | |
1297 | /* REVISIT: some docs say that when hw_ep->tx_double_buffered, | 1346 | * REVISIT: some docs say that when hw_ep->tx_double_buffered, |
1298 | * (and presumably, fifo is not half-full) we should write TWO | 1347 | * (and presumably, FIFO is not half-full) we should write *two* |
1299 | * packets before updating TXCSR ... other docs disagree ... | 1348 | * packets before updating TXCSR; other docs disagree... |
1300 | */ | 1349 | */ |
1301 | /* PIO: start next packet in this URB */ | 1350 | if (length > qh->maxpacket) |
1302 | if (wLength > qh->maxpacket) | 1351 | length = qh->maxpacket; |
1303 | wLength = qh->maxpacket; | 1352 | musb_write_fifo(hw_ep, length, urb->transfer_buffer + offset); |
1304 | musb_write_fifo(hw_ep, wLength, buf); | 1353 | qh->segsize = length; |
1305 | qh->segsize = wLength; | ||
1306 | |||
1307 | musb_ep_select(mbase, epnum); | ||
1308 | musb_writew(epio, MUSB_TXCSR, | ||
1309 | MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); | ||
1310 | } else | ||
1311 | DBG(1, "not complete, but dma enabled?\n"); | ||
1312 | 1354 | ||
1313 | finish: | 1355 | musb_ep_select(mbase, epnum); |
1314 | return; | 1356 | musb_writew(epio, MUSB_TXCSR, |
1357 | MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); | ||
1315 | } | 1358 | } |
1316 | 1359 | ||
1317 | 1360 | ||
@@ -1841,7 +1884,7 @@ static int musb_urb_enqueue( | |||
1841 | unsigned long flags; | 1884 | unsigned long flags; |
1842 | struct musb *musb = hcd_to_musb(hcd); | 1885 | struct musb *musb = hcd_to_musb(hcd); |
1843 | struct usb_host_endpoint *hep = urb->ep; | 1886 | struct usb_host_endpoint *hep = urb->ep; |
1844 | struct musb_qh *qh = hep->hcpriv; | 1887 | struct musb_qh *qh; |
1845 | struct usb_endpoint_descriptor *epd = &hep->desc; | 1888 | struct usb_endpoint_descriptor *epd = &hep->desc; |
1846 | int ret; | 1889 | int ret; |
1847 | unsigned type_reg; | 1890 | unsigned type_reg; |
@@ -1853,22 +1896,21 @@ static int musb_urb_enqueue( | |||
1853 | 1896 | ||
1854 | spin_lock_irqsave(&musb->lock, flags); | 1897 | spin_lock_irqsave(&musb->lock, flags); |
1855 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | 1898 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
1899 | qh = ret ? NULL : hep->hcpriv; | ||
1900 | if (qh) | ||
1901 | urb->hcpriv = qh; | ||
1856 | spin_unlock_irqrestore(&musb->lock, flags); | 1902 | spin_unlock_irqrestore(&musb->lock, flags); |
1857 | if (ret) | ||
1858 | return ret; | ||
1859 | 1903 | ||
1860 | /* DMA mapping was already done, if needed, and this urb is on | 1904 | /* DMA mapping was already done, if needed, and this urb is on |
1861 | * hep->urb_list ... so there's little to do unless hep wasn't | 1905 | * hep->urb_list now ... so we're done, unless hep wasn't yet |
1862 | * yet scheduled onto a live qh. | 1906 | * scheduled onto a live qh. |
1863 | * | 1907 | * |
1864 | * REVISIT best to keep hep->hcpriv valid until the endpoint gets | 1908 | * REVISIT best to keep hep->hcpriv valid until the endpoint gets |
1865 | * disabled, testing for empty qh->ring and avoiding qh setup costs | 1909 | * disabled, testing for empty qh->ring and avoiding qh setup costs |
1866 | * except for the first urb queued after a config change. | 1910 | * except for the first urb queued after a config change. |
1867 | */ | 1911 | */ |
1868 | if (qh) { | 1912 | if (qh || ret) |
1869 | urb->hcpriv = qh; | 1913 | return ret; |
1870 | return 0; | ||
1871 | } | ||
1872 | 1914 | ||
1873 | /* Allocate and initialize qh, minimizing the work done each time | 1915 | /* Allocate and initialize qh, minimizing the work done each time |
1874 | * hw_ep gets reprogrammed, or with irqs blocked. Then schedule it. | 1916 | * hw_ep gets reprogrammed, or with irqs blocked. Then schedule it. |
@@ -2044,7 +2086,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) | |||
2044 | * endpoint's irq status here to avoid bogus irqs. | 2086 | * endpoint's irq status here to avoid bogus irqs. |
2045 | * clearing that status is platform-specific... | 2087 | * clearing that status is platform-specific... |
2046 | */ | 2088 | */ |
2047 | } else { | 2089 | } else if (ep->epnum) { |
2048 | musb_h_tx_flush_fifo(ep); | 2090 | musb_h_tx_flush_fifo(ep); |
2049 | csr = musb_readw(epio, MUSB_TXCSR); | 2091 | csr = musb_readw(epio, MUSB_TXCSR); |
2050 | csr &= ~(MUSB_TXCSR_AUTOSET | 2092 | csr &= ~(MUSB_TXCSR_AUTOSET |
@@ -2058,6 +2100,8 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) | |||
2058 | musb_writew(epio, MUSB_TXCSR, csr); | 2100 | musb_writew(epio, MUSB_TXCSR, csr); |
2059 | /* flush cpu writebuffer */ | 2101 | /* flush cpu writebuffer */ |
2060 | csr = musb_readw(epio, MUSB_TXCSR); | 2102 | csr = musb_readw(epio, MUSB_TXCSR); |
2103 | } else { | ||
2104 | musb_h_ep0_flush_fifo(ep); | ||
2061 | } | 2105 | } |
2062 | if (status == 0) | 2106 | if (status == 0) |
2063 | musb_advance_schedule(ep->musb, urb, ep, is_in); | 2107 | musb_advance_schedule(ep->musb, urb, ep, is_in); |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 8662e9e159c3..5e83f96d6b77 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -195,30 +195,32 @@ static int dma_channel_abort(struct dma_channel *channel) | |||
195 | void __iomem *mbase = musb_channel->controller->base; | 195 | void __iomem *mbase = musb_channel->controller->base; |
196 | 196 | ||
197 | u8 bchannel = musb_channel->idx; | 197 | u8 bchannel = musb_channel->idx; |
198 | int offset; | ||
198 | u16 csr; | 199 | u16 csr; |
199 | 200 | ||
200 | if (channel->status == MUSB_DMA_STATUS_BUSY) { | 201 | if (channel->status == MUSB_DMA_STATUS_BUSY) { |
201 | if (musb_channel->transmit) { | 202 | if (musb_channel->transmit) { |
202 | 203 | offset = MUSB_EP_OFFSET(musb_channel->epnum, | |
203 | csr = musb_readw(mbase, | 204 | MUSB_TXCSR); |
204 | MUSB_EP_OFFSET(musb_channel->epnum, | 205 | |
205 | MUSB_TXCSR)); | 206 | /* |
206 | csr &= ~(MUSB_TXCSR_AUTOSET | | 207 | * The programming guide says that we must clear |
207 | MUSB_TXCSR_DMAENAB | | 208 | * the DMAENAB bit before the DMAMODE bit... |
208 | MUSB_TXCSR_DMAMODE); | 209 | */ |
209 | musb_writew(mbase, | 210 | csr = musb_readw(mbase, offset); |
210 | MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR), | 211 | csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB); |
211 | csr); | 212 | musb_writew(mbase, offset, csr); |
213 | csr &= ~MUSB_TXCSR_DMAMODE; | ||
214 | musb_writew(mbase, offset, csr); | ||
212 | } else { | 215 | } else { |
213 | csr = musb_readw(mbase, | 216 | offset = MUSB_EP_OFFSET(musb_channel->epnum, |
214 | MUSB_EP_OFFSET(musb_channel->epnum, | 217 | MUSB_RXCSR); |
215 | MUSB_RXCSR)); | 218 | |
219 | csr = musb_readw(mbase, offset); | ||
216 | csr &= ~(MUSB_RXCSR_AUTOCLEAR | | 220 | csr &= ~(MUSB_RXCSR_AUTOCLEAR | |
217 | MUSB_RXCSR_DMAENAB | | 221 | MUSB_RXCSR_DMAENAB | |
218 | MUSB_RXCSR_DMAMODE); | 222 | MUSB_RXCSR_DMAMODE); |
219 | musb_writew(mbase, | 223 | musb_writew(mbase, offset, csr); |
220 | MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR), | ||
221 | csr); | ||
222 | } | 224 | } |
223 | 225 | ||
224 | musb_writew(mbase, | 226 | musb_writew(mbase, |
@@ -296,20 +298,28 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
296 | && ((channel->desired_mode == 0) | 298 | && ((channel->desired_mode == 0) |
297 | || (channel->actual_len & | 299 | || (channel->actual_len & |
298 | (musb_channel->max_packet_sz - 1))) | 300 | (musb_channel->max_packet_sz - 1))) |
299 | ) { | 301 | ) { |
302 | u8 epnum = musb_channel->epnum; | ||
303 | int offset = MUSB_EP_OFFSET(epnum, | ||
304 | MUSB_TXCSR); | ||
305 | u16 txcsr; | ||
306 | |||
307 | /* | ||
308 | * The programming guide says that we | ||
309 | * must clear DMAENAB before DMAMODE. | ||
310 | */ | ||
311 | musb_ep_select(mbase, epnum); | ||
312 | txcsr = musb_readw(mbase, offset); | ||
313 | txcsr &= ~(MUSB_TXCSR_DMAENAB | ||
314 | | MUSB_TXCSR_AUTOSET); | ||
315 | musb_writew(mbase, offset, txcsr); | ||
300 | /* Send out the packet */ | 316 | /* Send out the packet */ |
301 | musb_ep_select(mbase, | 317 | txcsr &= ~MUSB_TXCSR_DMAMODE; |
302 | musb_channel->epnum); | 318 | txcsr |= MUSB_TXCSR_TXPKTRDY; |
303 | musb_writew(mbase, MUSB_EP_OFFSET( | 319 | musb_writew(mbase, offset, txcsr); |
304 | musb_channel->epnum, | ||
305 | MUSB_TXCSR), | ||
306 | MUSB_TXCSR_TXPKTRDY); | ||
307 | } else { | ||
308 | musb_dma_completion( | ||
309 | musb, | ||
310 | musb_channel->epnum, | ||
311 | musb_channel->transmit); | ||
312 | } | 320 | } |
321 | musb_dma_completion(musb, musb_channel->epnum, | ||
322 | musb_channel->transmit); | ||
313 | } | 323 | } |
314 | } | 324 | } |
315 | } | 325 | } |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 901dffdf23b1..60924ce08493 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -3,7 +3,6 @@ | |||
3 | * Some code has been taken from tusb6010.c | 3 | * Some code has been taken from tusb6010.c |
4 | * Copyrights for that are attributable to: | 4 | * Copyrights for that are attributable to: |
5 | * Copyright (C) 2006 Nokia Corporation | 5 | * Copyright (C) 2006 Nokia Corporation |
6 | * Jarkko Nikula <jarkko.nikula@nokia.com> | ||
7 | * Tony Lindgren <tony@atomide.com> | 6 | * Tony Lindgren <tony@atomide.com> |
8 | * | 7 | * |
9 | * This file is part of the Inventra Controller Driver for Linux. | 8 | * This file is part of the Inventra Controller Driver for Linux. |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 9e20fd070d71..4ac1477d3569 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -2,7 +2,6 @@ | |||
2 | * TUSB6010 USB 2.0 OTG Dual Role controller | 2 | * TUSB6010 USB 2.0 OTG Dual Role controller |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Nokia Corporation | 4 | * Copyright (C) 2006 Nokia Corporation |
5 | * Jarkko Nikula <jarkko.nikula@nokia.com> | ||
6 | * Tony Lindgren <tony@atomide.com> | 5 | * Tony Lindgren <tony@atomide.com> |
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/usb/musb/tusb6010.h b/drivers/usb/musb/tusb6010.h index ab8c96286ce6..35c933a5d991 100644 --- a/drivers/usb/musb/tusb6010.h +++ b/drivers/usb/musb/tusb6010.h | |||
@@ -2,7 +2,6 @@ | |||
2 | * Definitions for TUSB6010 USB 2.0 OTG Dual Role controller | 2 | * Definitions for TUSB6010 USB 2.0 OTG Dual Role controller |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Nokia Corporation | 4 | * Copyright (C) 2006 Nokia Corporation |
5 | * Jarkko Nikula <jarkko.nikula@nokia.com> | ||
6 | * Tony Lindgren <tony@atomide.com> | 5 | * Tony Lindgren <tony@atomide.com> |
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 4b933f646f2e..c567168f89af 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c | |||
@@ -36,14 +36,14 @@ struct nop_usb_xceiv { | |||
36 | struct device *dev; | 36 | struct device *dev; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static u64 nop_xceiv_dmamask = DMA_32BIT_MASK; | 39 | static u64 nop_xceiv_dmamask = DMA_BIT_MASK(32); |
40 | 40 | ||
41 | static struct platform_device nop_xceiv_device = { | 41 | static struct platform_device nop_xceiv_device = { |
42 | .name = "nop_usb_xceiv", | 42 | .name = "nop_usb_xceiv", |
43 | .id = -1, | 43 | .id = -1, |
44 | .dev = { | 44 | .dev = { |
45 | .dma_mask = &nop_xceiv_dmamask, | 45 | .dma_mask = &nop_xceiv_dmamask, |
46 | .coherent_dma_mask = DMA_32BIT_MASK, | 46 | .coherent_dma_mask = DMA_BIT_MASK(32), |
47 | .platform_data = NULL, | 47 | .platform_data = NULL, |
48 | }, | 48 | }, |
49 | }; | 49 | }; |
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index ff318fae7d4d..0a43a7db750f 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c | |||
@@ -43,7 +43,8 @@ EXPORT_SYMBOL(otg_get_transceiver); | |||
43 | */ | 43 | */ |
44 | void otg_put_transceiver(struct otg_transceiver *x) | 44 | void otg_put_transceiver(struct otg_transceiver *x) |
45 | { | 45 | { |
46 | put_device(x->dev); | 46 | if (x) |
47 | put_device(x->dev); | ||
47 | } | 48 | } |
48 | EXPORT_SYMBOL(otg_put_transceiver); | 49 | EXPORT_SYMBOL(otg_put_transceiver); |
49 | 50 | ||
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 858bdd038fbc..dd501bb63ed6 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -175,13 +175,6 @@ static int cyberjack_open(struct tty_struct *tty, | |||
175 | dbg("%s - usb_clear_halt", __func__); | 175 | dbg("%s - usb_clear_halt", __func__); |
176 | usb_clear_halt(port->serial->dev, port->write_urb->pipe); | 176 | usb_clear_halt(port->serial->dev, port->write_urb->pipe); |
177 | 177 | ||
178 | /* force low_latency on so that our tty_push actually forces | ||
179 | * the data through, otherwise it is scheduled, and with high | ||
180 | * data rates (like with OHCI) data can get lost. | ||
181 | */ | ||
182 | if (tty) | ||
183 | tty->low_latency = 1; | ||
184 | |||
185 | priv = usb_get_serial_port_data(port); | 178 | priv = usb_get_serial_port_data(port); |
186 | spin_lock_irqsave(&priv->lock, flags); | 179 | spin_lock_irqsave(&priv->lock, flags); |
187 | priv->rdtodo = 0; | 180 | priv->rdtodo = 0; |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index eae4740d448c..e568710b263f 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -656,10 +656,6 @@ static int cypress_open(struct tty_struct *tty, | |||
656 | priv->rx_flags = 0; | 656 | priv->rx_flags = 0; |
657 | spin_unlock_irqrestore(&priv->lock, flags); | 657 | spin_unlock_irqrestore(&priv->lock, flags); |
658 | 658 | ||
659 | /* setting to zero could cause data loss */ | ||
660 | if (tty) | ||
661 | tty->low_latency = 1; | ||
662 | |||
663 | /* raise both lines and set termios */ | 659 | /* raise both lines and set termios */ |
664 | spin_lock_irqsave(&priv->lock, flags); | 660 | spin_lock_irqsave(&priv->lock, flags); |
665 | priv->line_control = CONTROL_DTR | CONTROL_RTS; | 661 | priv->line_control = CONTROL_DTR | CONTROL_RTS; |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 8a69cce40b6d..c709ec474a80 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -478,12 +478,6 @@ static void empeg_set_termios(struct tty_struct *tty, | |||
478 | termios->c_cflag | 478 | termios->c_cflag |
479 | |= CS8; /* character size 8 bits */ | 479 | |= CS8; /* character size 8 bits */ |
480 | 480 | ||
481 | /* | ||
482 | * Force low_latency on; otherwise the pushes are scheduled; | ||
483 | * this is bad as it opens up the possibility of dropping bytes | ||
484 | * on the floor. We don't want to drop bytes on the floor. :) | ||
485 | */ | ||
486 | tty->low_latency = 1; | ||
487 | tty_encode_baud_rate(tty, 115200, 115200); | 481 | tty_encode_baud_rate(tty, 115200, 115200); |
488 | } | 482 | } |
489 | 483 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index dcc87aaa8628..8100f1d25904 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -668,6 +668,7 @@ static struct usb_device_id id_table_combined [] = { | |||
668 | { USB_DEVICE(DE_VID, WHT_PID) }, | 668 | { USB_DEVICE(DE_VID, WHT_PID) }, |
669 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), | 669 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), |
670 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 670 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
671 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | ||
671 | { }, /* Optional parameter entry */ | 672 | { }, /* Optional parameter entry */ |
672 | { } /* Terminating entry */ | 673 | { } /* Terminating entry */ |
673 | }; | 674 | }; |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index daaf63db0b50..c09f658a448b 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -913,6 +913,13 @@ | |||
913 | #define ADI_GNICE_PID 0xF000 | 913 | #define ADI_GNICE_PID 0xF000 |
914 | 914 | ||
915 | /* | 915 | /* |
916 | * JETI SPECTROMETER SPECBOS 1201 | ||
917 | * http://www.jeti.com/products/sys/scb/scb1201.php | ||
918 | */ | ||
919 | #define JETI_VID 0x0c6c | ||
920 | #define JETI_SPC1201_PID 0x04b2 | ||
921 | |||
922 | /* | ||
916 | * BmRequestType: 1100 0000b | 923 | * BmRequestType: 1100 0000b |
917 | * bRequest: FTDI_E2_READ | 924 | * bRequest: FTDI_E2_READ |
918 | * wValue: 0 | 925 | * wValue: 0 |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index a26a0e2cdb4a..586d30ff450b 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -973,14 +973,6 @@ static int garmin_open(struct tty_struct *tty, | |||
973 | 973 | ||
974 | dbg("%s - port %d", __func__, port->number); | 974 | dbg("%s - port %d", __func__, port->number); |
975 | 975 | ||
976 | /* | ||
977 | * Force low_latency on so that our tty_push actually forces the data | ||
978 | * through, otherwise it is scheduled, and with high data rates (like | ||
979 | * with OHCI) data can get lost. | ||
980 | */ | ||
981 | if (tty) | ||
982 | tty->low_latency = 1; | ||
983 | |||
984 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 976 | spin_lock_irqsave(&garmin_data_p->lock, flags); |
985 | garmin_data_p->mode = initial_mode; | 977 | garmin_data_p->mode = initial_mode; |
986 | garmin_data_p->count = 0; | 978 | garmin_data_p->count = 0; |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 9d57cace3731..4cec9906ccf3 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -122,12 +122,6 @@ int usb_serial_generic_open(struct tty_struct *tty, | |||
122 | 122 | ||
123 | dbg("%s - port %d", __func__, port->number); | 123 | dbg("%s - port %d", __func__, port->number); |
124 | 124 | ||
125 | /* force low_latency on so that our tty_push actually forces the data | ||
126 | through, otherwise it is scheduled, and with high data rates (like | ||
127 | with OHCI) data can get lost. */ | ||
128 | if (tty) | ||
129 | tty->low_latency = 1; | ||
130 | |||
131 | /* clear the throttle flags */ | 125 | /* clear the throttle flags */ |
132 | spin_lock_irqsave(&port->lock, flags); | 126 | spin_lock_irqsave(&port->lock, flags); |
133 | port->throttled = 0; | 127 | port->throttled = 0; |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index e85c8c0d1ad9..fb4a73d090f6 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -193,8 +193,6 @@ static const struct divisor_table_entry divisor_table[] = { | |||
193 | /* local variables */ | 193 | /* local variables */ |
194 | static int debug; | 194 | static int debug; |
195 | 195 | ||
196 | static int low_latency = 1; /* tty low latency flag, on by default */ | ||
197 | |||
198 | static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */ | 196 | static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */ |
199 | 197 | ||
200 | 198 | ||
@@ -867,9 +865,6 @@ static int edge_open(struct tty_struct *tty, | |||
867 | if (edge_port == NULL) | 865 | if (edge_port == NULL) |
868 | return -ENODEV; | 866 | return -ENODEV; |
869 | 867 | ||
870 | if (tty) | ||
871 | tty->low_latency = low_latency; | ||
872 | |||
873 | /* see if we've set up our endpoint info yet (can't set it up | 868 | /* see if we've set up our endpoint info yet (can't set it up |
874 | in edge_startup as the structures were not set up at that time.) */ | 869 | in edge_startup as the structures were not set up at that time.) */ |
875 | serial = port->serial; | 870 | serial = port->serial; |
@@ -3299,6 +3294,3 @@ MODULE_FIRMWARE("edgeport/down2.fw"); | |||
3299 | 3294 | ||
3300 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 3295 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
3301 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | 3296 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |
3302 | |||
3303 | module_param(low_latency, bool, S_IRUGO | S_IWUSR); | ||
3304 | MODULE_PARM_DESC(low_latency, "Low latency enabled or not"); | ||
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index c3cdd00ddc41..513b25e044c1 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -76,7 +76,6 @@ struct edgeport_uart_buf_desc { | |||
76 | #define EDGE_READ_URB_STOPPING 1 | 76 | #define EDGE_READ_URB_STOPPING 1 |
77 | #define EDGE_READ_URB_STOPPED 2 | 77 | #define EDGE_READ_URB_STOPPED 2 |
78 | 78 | ||
79 | #define EDGE_LOW_LATENCY 1 | ||
80 | #define EDGE_CLOSING_WAIT 4000 /* in .01 sec */ | 79 | #define EDGE_CLOSING_WAIT 4000 /* in .01 sec */ |
81 | 80 | ||
82 | #define EDGE_OUT_BUF_SIZE 1024 | 81 | #define EDGE_OUT_BUF_SIZE 1024 |
@@ -232,7 +231,6 @@ static unsigned short OperationalBuildNumber; | |||
232 | 231 | ||
233 | static int debug; | 232 | static int debug; |
234 | 233 | ||
235 | static int low_latency = EDGE_LOW_LATENCY; | ||
236 | static int closing_wait = EDGE_CLOSING_WAIT; | 234 | static int closing_wait = EDGE_CLOSING_WAIT; |
237 | static int ignore_cpu_rev; | 235 | static int ignore_cpu_rev; |
238 | static int default_uart_mode; /* RS232 */ | 236 | static int default_uart_mode; /* RS232 */ |
@@ -1850,9 +1848,6 @@ static int edge_open(struct tty_struct *tty, | |||
1850 | if (edge_port == NULL) | 1848 | if (edge_port == NULL) |
1851 | return -ENODEV; | 1849 | return -ENODEV; |
1852 | 1850 | ||
1853 | if (tty) | ||
1854 | tty->low_latency = low_latency; | ||
1855 | |||
1856 | port_number = port->number - port->serial->minor; | 1851 | port_number = port->number - port->serial->minor; |
1857 | switch (port_number) { | 1852 | switch (port_number) { |
1858 | case 0: | 1853 | case 0: |
@@ -3008,9 +3003,6 @@ MODULE_FIRMWARE("edgeport/down3.bin"); | |||
3008 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 3003 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
3009 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | 3004 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |
3010 | 3005 | ||
3011 | module_param(low_latency, bool, S_IRUGO | S_IWUSR); | ||
3012 | MODULE_PARM_DESC(low_latency, "Low latency enabled or not"); | ||
3013 | |||
3014 | module_param(closing_wait, int, S_IRUGO | S_IWUSR); | 3006 | module_param(closing_wait, int, S_IRUGO | S_IWUSR); |
3015 | MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs"); | 3007 | MODULE_PARM_DESC(closing_wait, "Maximum wait for data to drain, in .01 secs"); |
3016 | 3008 | ||
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index ef92095b0732..cd62825a9ac3 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -631,13 +631,7 @@ static int ipaq_open(struct tty_struct *tty, | |||
631 | priv->free_len += PACKET_SIZE; | 631 | priv->free_len += PACKET_SIZE; |
632 | } | 632 | } |
633 | 633 | ||
634 | /* | ||
635 | * Force low latency on. This will immediately push data to the line | ||
636 | * discipline instead of queueing. | ||
637 | */ | ||
638 | |||
639 | if (tty) { | 634 | if (tty) { |
640 | tty->low_latency = 1; | ||
641 | /* FIXME: These two are bogus */ | 635 | /* FIXME: These two are bogus */ |
642 | tty->raw = 1; | 636 | tty->raw = 1; |
643 | tty->real_raw = 1; | 637 | tty->real_raw = 1; |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index f530032ed93d..da2a2b46644a 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -207,9 +207,6 @@ static int ipw_open(struct tty_struct *tty, | |||
207 | if (!buf_flow_init) | 207 | if (!buf_flow_init) |
208 | return -ENOMEM; | 208 | return -ENOMEM; |
209 | 209 | ||
210 | if (tty) | ||
211 | tty->low_latency = 1; | ||
212 | |||
213 | /* --1: Tell the modem to initialize (we think) From sniffs this is | 210 | /* --1: Tell the modem to initialize (we think) From sniffs this is |
214 | * always the first thing that gets sent to the modem during | 211 | * always the first thing that gets sent to the modem during |
215 | * opening of the device */ | 212 | * opening of the device */ |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 2314c6ae4fc2..4473d442b2aa 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -1051,7 +1051,6 @@ static int iuu_open(struct tty_struct *tty, | |||
1051 | tty->termios->c_oflag = 0; | 1051 | tty->termios->c_oflag = 0; |
1052 | tty->termios->c_iflag = 0; | 1052 | tty->termios->c_iflag = 0; |
1053 | priv->termios_initialized = 1; | 1053 | priv->termios_initialized = 1; |
1054 | tty->low_latency = 1; | ||
1055 | priv->poll = 0; | 1054 | priv->poll = 0; |
1056 | } | 1055 | } |
1057 | spin_unlock_irqrestore(&priv->lock, flags); | 1056 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 6286baad9392..c148544953b3 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -231,13 +231,7 @@ static int kobil_open(struct tty_struct *tty, | |||
231 | /* someone sets the dev to 0 if the close method has been called */ | 231 | /* someone sets the dev to 0 if the close method has been called */ |
232 | port->interrupt_in_urb->dev = port->serial->dev; | 232 | port->interrupt_in_urb->dev = port->serial->dev; |
233 | 233 | ||
234 | |||
235 | /* force low_latency on so that our tty_push actually forces | ||
236 | * the data through, otherwise it is scheduled, and with high | ||
237 | * data rates (like with OHCI) data can get lost. | ||
238 | */ | ||
239 | if (tty) { | 234 | if (tty) { |
240 | tty->low_latency = 1; | ||
241 | 235 | ||
242 | /* Default to echo off and other sane device settings */ | 236 | /* Default to echo off and other sane device settings */ |
243 | tty->termios->c_lflag = 0; | 237 | tty->termios->c_lflag = 0; |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e772cc0a97fd..24e3b5d4b4d4 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -446,13 +446,6 @@ static int mos7720_open(struct tty_struct *tty, | |||
446 | data = 0x0c; | 446 | data = 0x0c; |
447 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); | 447 | send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data); |
448 | 448 | ||
449 | /* force low_latency on so that our tty_push actually forces * | ||
450 | * the data through,otherwise it is scheduled, and with * | ||
451 | * high data rates (like with OHCI) data can get lost. */ | ||
452 | |||
453 | if (tty) | ||
454 | tty->low_latency = 1; | ||
455 | |||
456 | /* see if we've set up our endpoint info yet * | 449 | /* see if we've set up our endpoint info yet * |
457 | * (can't set it up in mos7720_startup as the * | 450 | * (can't set it up in mos7720_startup as the * |
458 | * structures were not set up at that time.) */ | 451 | * structures were not set up at that time.) */ |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2c20e88a91b3..84fb1dcd30dc 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -38,7 +38,7 @@ | |||
38 | /* | 38 | /* |
39 | * Version Information | 39 | * Version Information |
40 | */ | 40 | */ |
41 | #define DRIVER_VERSION "1.3.1" | 41 | #define DRIVER_VERSION "1.3.2" |
42 | #define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver" | 42 | #define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver" |
43 | 43 | ||
44 | /* | 44 | /* |
@@ -123,6 +123,11 @@ | |||
123 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | 123 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 |
124 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 | 124 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 |
125 | 125 | ||
126 | /* This driver also supports the ATEN UC2324 device since it is mos7840 based | ||
127 | * - if I knew the device id it would also support the ATEN UC2322 */ | ||
128 | #define USB_VENDOR_ID_ATENINTL 0x0557 | ||
129 | #define ATENINTL_DEVICE_ID_UC2324 0x2011 | ||
130 | |||
126 | /* Interrupt Routine Defines */ | 131 | /* Interrupt Routine Defines */ |
127 | 132 | ||
128 | #define SERIAL_IIR_RLS 0x06 | 133 | #define SERIAL_IIR_RLS 0x06 |
@@ -170,6 +175,7 @@ static struct usb_device_id moschip_port_id_table[] = { | |||
170 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 175 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
171 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 176 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
172 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 177 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
178 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | ||
173 | {} /* terminating entry */ | 179 | {} /* terminating entry */ |
174 | }; | 180 | }; |
175 | 181 | ||
@@ -178,6 +184,7 @@ static __devinitdata struct usb_device_id moschip_id_table_combined[] = { | |||
178 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 184 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
179 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 185 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, |
180 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 186 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
187 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | ||
181 | {} /* terminating entry */ | 188 | {} /* terminating entry */ |
182 | }; | 189 | }; |
183 | 190 | ||
@@ -1000,12 +1007,6 @@ static int mos7840_open(struct tty_struct *tty, | |||
1000 | status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, | 1007 | status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, |
1001 | Data); | 1008 | Data); |
1002 | 1009 | ||
1003 | /* force low_latency on so that our tty_push actually forces * | ||
1004 | * the data through,otherwise it is scheduled, and with * | ||
1005 | * high data rates (like with OHCI) data can get lost. */ | ||
1006 | if (tty) | ||
1007 | tty->low_latency = 1; | ||
1008 | |||
1009 | /* Check to see if we've set up our endpoint info yet * | 1010 | /* Check to see if we've set up our endpoint info yet * |
1010 | * (can't set it up in mos7840_startup as the structures * | 1011 | * (can't set it up in mos7840_startup as the structures * |
1011 | * were not set up at that time.) */ | 1012 | * were not set up at that time.) */ |
@@ -2477,9 +2478,14 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2477 | mos7840_set_port_private(serial->port[i], mos7840_port); | 2478 | mos7840_set_port_private(serial->port[i], mos7840_port); |
2478 | spin_lock_init(&mos7840_port->pool_lock); | 2479 | spin_lock_init(&mos7840_port->pool_lock); |
2479 | 2480 | ||
2480 | mos7840_port->port_num = ((serial->port[i]->number - | 2481 | /* minor is not initialised until later by |
2481 | (serial->port[i]->serial->minor)) + | 2482 | * usb-serial.c:get_free_serial() and cannot therefore be used |
2482 | 1); | 2483 | * to index device instances */ |
2484 | mos7840_port->port_num = i + 1; | ||
2485 | dbg ("serial->port[i]->number = %d", serial->port[i]->number); | ||
2486 | dbg ("serial->port[i]->serial->minor = %d", serial->port[i]->serial->minor); | ||
2487 | dbg ("mos7840_port->port_num = %d", mos7840_port->port_num); | ||
2488 | dbg ("serial->minor = %d", serial->minor); | ||
2483 | 2489 | ||
2484 | if (mos7840_port->port_num == 1) { | 2490 | if (mos7840_port->port_num == 1) { |
2485 | mos7840_port->SpRegOffset = 0x0; | 2491 | mos7840_port->SpRegOffset = 0x0; |
@@ -2690,13 +2696,16 @@ static void mos7840_shutdown(struct usb_serial *serial) | |||
2690 | 2696 | ||
2691 | for (i = 0; i < serial->num_ports; ++i) { | 2697 | for (i = 0; i < serial->num_ports; ++i) { |
2692 | mos7840_port = mos7840_get_port_private(serial->port[i]); | 2698 | mos7840_port = mos7840_get_port_private(serial->port[i]); |
2693 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); | 2699 | dbg ("mos7840_port %d = %p", i, mos7840_port); |
2694 | mos7840_port->zombie = 1; | 2700 | if (mos7840_port) { |
2695 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); | 2701 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); |
2696 | usb_kill_urb(mos7840_port->control_urb); | 2702 | mos7840_port->zombie = 1; |
2697 | kfree(mos7840_port->ctrl_buf); | 2703 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); |
2698 | kfree(mos7840_port->dr); | 2704 | usb_kill_urb(mos7840_port->control_urb); |
2699 | kfree(mos7840_port); | 2705 | kfree(mos7840_port->ctrl_buf); |
2706 | kfree(mos7840_port->dr); | ||
2707 | kfree(mos7840_port); | ||
2708 | } | ||
2700 | mos7840_set_port_private(serial->port[i], NULL); | 2709 | mos7840_set_port_private(serial->port[i], NULL); |
2701 | } | 2710 | } |
2702 | 2711 | ||
diff --git a/drivers/usb/serial/moto_modem.c b/drivers/usb/serial/moto_modem.c index 2e8e05462ef7..b66b71ccd12b 100644 --- a/drivers/usb/serial/moto_modem.c +++ b/drivers/usb/serial/moto_modem.c | |||
@@ -25,6 +25,7 @@ static struct usb_device_id id_table [] = { | |||
25 | { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ | 25 | { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ |
26 | { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ | 26 | { USB_DEVICE(0x0c44, 0x0022) }, /* unknown Mororola phone */ |
27 | { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ | 27 | { USB_DEVICE(0x22b8, 0x2a64) }, /* Motorola KRZR K1m */ |
28 | { USB_DEVICE(0x22b8, 0x2c64) }, /* Motorola V950 phone */ | ||
28 | { }, | 29 | { }, |
29 | }; | 30 | }; |
30 | MODULE_DEVICE_TABLE(usb, id_table); | 31 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 839583dc8b6a..b500ad10b758 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -159,14 +159,6 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
159 | priv->port = port; | 159 | priv->port = port; |
160 | spin_unlock_irqrestore(&priv->lock, flags); | 160 | spin_unlock_irqrestore(&priv->lock, flags); |
161 | 161 | ||
162 | /* | ||
163 | * Force low_latency on so that our tty_push actually forces the data | ||
164 | * through, otherwise it is scheduled, and with high data rates (like | ||
165 | * with OHCI) data can get lost. | ||
166 | */ | ||
167 | if (tty) | ||
168 | tty->low_latency = 1; | ||
169 | |||
170 | /* Start reading from the device */ | 162 | /* Start reading from the device */ |
171 | usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, | 163 | usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, |
172 | usb_rcvbulkpipe(priv->udev, | 164 | usb_rcvbulkpipe(priv->udev, |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d560c0b54e6e..7817b82889ca 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -300,6 +300,10 @@ static int option_resume(struct usb_serial *serial); | |||
300 | #define BENQ_VENDOR_ID 0x04a5 | 300 | #define BENQ_VENDOR_ID 0x04a5 |
301 | #define BENQ_PRODUCT_H10 0x4068 | 301 | #define BENQ_PRODUCT_H10 0x4068 |
302 | 302 | ||
303 | #define DLINK_VENDOR_ID 0x1186 | ||
304 | #define DLINK_PRODUCT_DWM_652 0x3e04 | ||
305 | |||
306 | |||
303 | static struct usb_device_id option_ids[] = { | 307 | static struct usb_device_id option_ids[] = { |
304 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 308 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
305 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 309 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -516,6 +520,7 @@ static struct usb_device_id option_ids[] = { | |||
516 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, | 520 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, |
517 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, | 521 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, |
518 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 522 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
523 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | ||
519 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ | 524 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ |
520 | { } /* Terminating entry */ | 525 | { } /* Terminating entry */ |
521 | }; | 526 | }; |
@@ -931,9 +936,6 @@ static int option_open(struct tty_struct *tty, | |||
931 | usb_pipeout(urb->pipe), 0); */ | 936 | usb_pipeout(urb->pipe), 0); */ |
932 | } | 937 | } |
933 | 938 | ||
934 | if (tty) | ||
935 | tty->low_latency = 1; | ||
936 | |||
937 | option_send_setup(tty, port); | 939 | option_send_setup(tty, port); |
938 | 940 | ||
939 | return 0; | 941 | return 0; |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index e6d6b0c17fd9..7528b8d57f1c 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -26,6 +26,27 @@ static struct usb_device_id id_table[] = { | |||
26 | {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 26 | {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
27 | {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 27 | {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
28 | {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ | 28 | {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ |
29 | {USB_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ | ||
30 | {USB_DEVICE(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */ | ||
31 | {USB_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ | ||
32 | {USB_DEVICE(0x413c, 0x8171)}, /* Dell Gobi QDL device */ | ||
33 | {USB_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ | ||
34 | {USB_DEVICE(0x1410, 0xa008)}, /* Novatel Gobi QDL device */ | ||
35 | {USB_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ | ||
36 | {USB_DEVICE(0x0b05, 0x1774)}, /* Asus Gobi QDL device */ | ||
37 | {USB_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ | ||
38 | {USB_DEVICE(0x19d2, 0xfff2)}, /* ONDA Gobi QDL device */ | ||
39 | {USB_DEVICE(0x1557, 0x0a80)}, /* OQO Gobi QDL device */ | ||
40 | {USB_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ | ||
41 | {USB_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ | ||
42 | {USB_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ | ||
43 | {USB_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ | ||
44 | {USB_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ | ||
45 | {USB_DEVICE(0x05c6, 0x9008)}, /* Generic Gobi QDL device */ | ||
46 | {USB_DEVICE(0x05c6, 0x9201)}, /* Generic Gobi QDL device */ | ||
47 | {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ | ||
48 | {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ | ||
49 | {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ | ||
29 | { } /* Terminating entry */ | 50 | { } /* Terminating entry */ |
30 | }; | 51 | }; |
31 | MODULE_DEVICE_TABLE(usb, id_table); | 52 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index d9bf9a5c20ec..913225c61610 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -14,7 +14,7 @@ | |||
14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define DRIVER_VERSION "v.1.3.2" | 17 | #define DRIVER_VERSION "v.1.3.3" |
18 | #define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>" | 18 | #define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>" |
19 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 19 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
20 | 20 | ||
@@ -259,9 +259,21 @@ static int sierra_send_setup(struct tty_struct *tty, | |||
259 | val |= 0x02; | 259 | val |= 0x02; |
260 | 260 | ||
261 | /* If composite device then properly report interface */ | 261 | /* If composite device then properly report interface */ |
262 | if (serial->num_ports == 1) | 262 | if (serial->num_ports == 1) { |
263 | interface = sierra_calc_interface(serial); | 263 | interface = sierra_calc_interface(serial); |
264 | 264 | ||
265 | /* Control message is sent only to interfaces with | ||
266 | * interrupt_in endpoints | ||
267 | */ | ||
268 | if (port->interrupt_in_urb) { | ||
269 | /* send control message */ | ||
270 | return usb_control_msg(serial->dev, | ||
271 | usb_rcvctrlpipe(serial->dev, 0), | ||
272 | 0x22, 0x21, val, interface, | ||
273 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
274 | } | ||
275 | } | ||
276 | |||
265 | /* Otherwise the need to do non-composite mapping */ | 277 | /* Otherwise the need to do non-composite mapping */ |
266 | else { | 278 | else { |
267 | if (port->bulk_out_endpointAddress == 2) | 279 | if (port->bulk_out_endpointAddress == 2) |
@@ -270,12 +282,13 @@ static int sierra_send_setup(struct tty_struct *tty, | |||
270 | interface = 1; | 282 | interface = 1; |
271 | else if (port->bulk_out_endpointAddress == 5) | 283 | else if (port->bulk_out_endpointAddress == 5) |
272 | interface = 2; | 284 | interface = 2; |
273 | } | ||
274 | 285 | ||
275 | return usb_control_msg(serial->dev, | 286 | return usb_control_msg(serial->dev, |
276 | usb_rcvctrlpipe(serial->dev, 0), | 287 | usb_rcvctrlpipe(serial->dev, 0), |
277 | 0x22, 0x21, val, interface, | 288 | 0x22, 0x21, val, interface, |
278 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 289 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
290 | |||
291 | } | ||
279 | } | 292 | } |
280 | 293 | ||
281 | return 0; | 294 | return 0; |
@@ -585,9 +598,6 @@ static int sierra_open(struct tty_struct *tty, | |||
585 | } | 598 | } |
586 | } | 599 | } |
587 | 600 | ||
588 | if (tty) | ||
589 | tty->low_latency = 1; | ||
590 | |||
591 | sierra_send_setup(tty, port); | 601 | sierra_send_setup(tty, port); |
592 | 602 | ||
593 | /* start up the interrupt endpoint if we have one */ | 603 | /* start up the interrupt endpoint if we have one */ |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 2620bf6fe5e1..0a64bac306ee 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -50,11 +50,10 @@ | |||
50 | 50 | ||
51 | #define TI_TRANSFER_TIMEOUT 2 | 51 | #define TI_TRANSFER_TIMEOUT 2 |
52 | 52 | ||
53 | #define TI_DEFAULT_LOW_LATENCY 0 | ||
54 | #define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */ | 53 | #define TI_DEFAULT_CLOSING_WAIT 4000 /* in .01 secs */ |
55 | 54 | ||
56 | /* supported setserial flags */ | 55 | /* supported setserial flags */ |
57 | #define TI_SET_SERIAL_FLAGS (ASYNC_LOW_LATENCY) | 56 | #define TI_SET_SERIAL_FLAGS 0 |
58 | 57 | ||
59 | /* read urb states */ | 58 | /* read urb states */ |
60 | #define TI_READ_URB_RUNNING 0 | 59 | #define TI_READ_URB_RUNNING 0 |
@@ -161,7 +160,6 @@ static int ti_buf_get(struct circ_buf *cb, char *buf, int count); | |||
161 | 160 | ||
162 | /* module parameters */ | 161 | /* module parameters */ |
163 | static int debug; | 162 | static int debug; |
164 | static int low_latency = TI_DEFAULT_LOW_LATENCY; | ||
165 | static int closing_wait = TI_DEFAULT_CLOSING_WAIT; | 163 | static int closing_wait = TI_DEFAULT_CLOSING_WAIT; |
166 | static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT]; | 164 | static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT]; |
167 | static unsigned int vendor_3410_count; | 165 | static unsigned int vendor_3410_count; |
@@ -296,10 +294,6 @@ MODULE_FIRMWARE("mts_edge.fw"); | |||
296 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 294 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
297 | MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes"); | 295 | MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes"); |
298 | 296 | ||
299 | module_param(low_latency, bool, S_IRUGO | S_IWUSR); | ||
300 | MODULE_PARM_DESC(low_latency, | ||
301 | "TTY low_latency flag, 0=off, 1=on, default is off"); | ||
302 | |||
303 | module_param(closing_wait, int, S_IRUGO | S_IWUSR); | 297 | module_param(closing_wait, int, S_IRUGO | S_IWUSR); |
304 | MODULE_PARM_DESC(closing_wait, | 298 | MODULE_PARM_DESC(closing_wait, |
305 | "Maximum wait for data to drain in close, in .01 secs, default is 4000"); | 299 | "Maximum wait for data to drain in close, in .01 secs, default is 4000"); |
@@ -448,7 +442,6 @@ static int ti_startup(struct usb_serial *serial) | |||
448 | spin_lock_init(&tport->tp_lock); | 442 | spin_lock_init(&tport->tp_lock); |
449 | tport->tp_uart_base_addr = (i == 0 ? | 443 | tport->tp_uart_base_addr = (i == 0 ? |
450 | TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR); | 444 | TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR); |
451 | tport->tp_flags = low_latency ? ASYNC_LOW_LATENCY : 0; | ||
452 | tport->tp_closing_wait = closing_wait; | 445 | tport->tp_closing_wait = closing_wait; |
453 | init_waitqueue_head(&tport->tp_msr_wait); | 446 | init_waitqueue_head(&tport->tp_msr_wait); |
454 | init_waitqueue_head(&tport->tp_write_wait); | 447 | init_waitqueue_head(&tport->tp_write_wait); |
@@ -528,10 +521,6 @@ static int ti_open(struct tty_struct *tty, | |||
528 | if (mutex_lock_interruptible(&tdev->td_open_close_lock)) | 521 | if (mutex_lock_interruptible(&tdev->td_open_close_lock)) |
529 | return -ERESTARTSYS; | 522 | return -ERESTARTSYS; |
530 | 523 | ||
531 | if (tty) | ||
532 | tty->low_latency = | ||
533 | (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0; | ||
534 | |||
535 | port_number = port->number - port->serial->minor; | 524 | port_number = port->number - port->serial->minor; |
536 | 525 | ||
537 | memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount)); | 526 | memset(&(tport->tp_icount), 0x00, sizeof(tport->tp_icount)); |
@@ -1215,20 +1204,22 @@ static void ti_bulk_in_callback(struct urb *urb) | |||
1215 | } | 1204 | } |
1216 | 1205 | ||
1217 | tty = tty_port_tty_get(&port->port); | 1206 | tty = tty_port_tty_get(&port->port); |
1218 | if (tty && urb->actual_length) { | 1207 | if (tty) { |
1219 | usb_serial_debug_data(debug, dev, __func__, | 1208 | if (urb->actual_length) { |
1220 | urb->actual_length, urb->transfer_buffer); | 1209 | usb_serial_debug_data(debug, dev, __func__, |
1221 | 1210 | urb->actual_length, urb->transfer_buffer); | |
1222 | if (!tport->tp_is_open) | 1211 | |
1223 | dbg("%s - port closed, dropping data", __func__); | 1212 | if (!tport->tp_is_open) |
1224 | else | 1213 | dbg("%s - port closed, dropping data", |
1225 | ti_recv(&urb->dev->dev, tty, | 1214 | __func__); |
1215 | else | ||
1216 | ti_recv(&urb->dev->dev, tty, | ||
1226 | urb->transfer_buffer, | 1217 | urb->transfer_buffer, |
1227 | urb->actual_length); | 1218 | urb->actual_length); |
1228 | 1219 | spin_lock(&tport->tp_lock); | |
1229 | spin_lock(&tport->tp_lock); | 1220 | tport->tp_icount.rx += urb->actual_length; |
1230 | tport->tp_icount.rx += urb->actual_length; | 1221 | spin_unlock(&tport->tp_lock); |
1231 | spin_unlock(&tport->tp_lock); | 1222 | } |
1232 | tty_kref_put(tty); | 1223 | tty_kref_put(tty); |
1233 | } | 1224 | } |
1234 | 1225 | ||
@@ -1452,7 +1443,6 @@ static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport, | |||
1452 | return -EFAULT; | 1443 | return -EFAULT; |
1453 | 1444 | ||
1454 | tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS; | 1445 | tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS; |
1455 | tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0; | ||
1456 | tport->tp_closing_wait = new_serial.closing_wait; | 1446 | tport->tp_closing_wait = new_serial.closing_wait; |
1457 | 1447 | ||
1458 | return 0; | 1448 | return 0; |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2a70563bbee1..0a566eea49c0 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -137,22 +137,10 @@ static void destroy_serial(struct kref *kref) | |||
137 | 137 | ||
138 | dbg("%s - %s", __func__, serial->type->description); | 138 | dbg("%s - %s", __func__, serial->type->description); |
139 | 139 | ||
140 | serial->type->shutdown(serial); | ||
141 | |||
142 | /* return the minor range that this device had */ | 140 | /* return the minor range that this device had */ |
143 | if (serial->minor != SERIAL_TTY_NO_MINOR) | 141 | if (serial->minor != SERIAL_TTY_NO_MINOR) |
144 | return_serial(serial); | 142 | return_serial(serial); |
145 | 143 | ||
146 | for (i = 0; i < serial->num_ports; ++i) | ||
147 | serial->port[i]->port.count = 0; | ||
148 | |||
149 | /* the ports are cleaned up and released in port_release() */ | ||
150 | for (i = 0; i < serial->num_ports; ++i) | ||
151 | if (serial->port[i]->dev.parent != NULL) { | ||
152 | device_unregister(&serial->port[i]->dev); | ||
153 | serial->port[i] = NULL; | ||
154 | } | ||
155 | |||
156 | /* If this is a "fake" port, we have to clean it up here, as it will | 144 | /* If this is a "fake" port, we have to clean it up here, as it will |
157 | * not get cleaned up in port_release() as it was never registered with | 145 | * not get cleaned up in port_release() as it was never registered with |
158 | * the driver core */ | 146 | * the driver core */ |
@@ -187,7 +175,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
187 | struct usb_serial *serial; | 175 | struct usb_serial *serial; |
188 | struct usb_serial_port *port; | 176 | struct usb_serial_port *port; |
189 | unsigned int portNumber; | 177 | unsigned int portNumber; |
190 | int retval; | 178 | int retval = 0; |
191 | 179 | ||
192 | dbg("%s", __func__); | 180 | dbg("%s", __func__); |
193 | 181 | ||
@@ -198,21 +186,24 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
198 | return -ENODEV; | 186 | return -ENODEV; |
199 | } | 187 | } |
200 | 188 | ||
189 | mutex_lock(&serial->disc_mutex); | ||
201 | portNumber = tty->index - serial->minor; | 190 | portNumber = tty->index - serial->minor; |
202 | port = serial->port[portNumber]; | 191 | port = serial->port[portNumber]; |
203 | if (!port) { | 192 | if (!port || serial->disconnected) |
204 | retval = -ENODEV; | ||
205 | goto bailout_kref_put; | ||
206 | } | ||
207 | |||
208 | if (port->serial->disconnected) { | ||
209 | retval = -ENODEV; | 193 | retval = -ENODEV; |
210 | goto bailout_kref_put; | 194 | else |
211 | } | 195 | get_device(&port->dev); |
196 | /* | ||
197 | * Note: Our locking order requirement does not allow port->mutex | ||
198 | * to be acquired while serial->disc_mutex is held. | ||
199 | */ | ||
200 | mutex_unlock(&serial->disc_mutex); | ||
201 | if (retval) | ||
202 | goto bailout_serial_put; | ||
212 | 203 | ||
213 | if (mutex_lock_interruptible(&port->mutex)) { | 204 | if (mutex_lock_interruptible(&port->mutex)) { |
214 | retval = -ERESTARTSYS; | 205 | retval = -ERESTARTSYS; |
215 | goto bailout_kref_put; | 206 | goto bailout_port_put; |
216 | } | 207 | } |
217 | 208 | ||
218 | ++port->port.count; | 209 | ++port->port.count; |
@@ -232,14 +223,20 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
232 | goto bailout_mutex_unlock; | 223 | goto bailout_mutex_unlock; |
233 | } | 224 | } |
234 | 225 | ||
235 | retval = usb_autopm_get_interface(serial->interface); | 226 | mutex_lock(&serial->disc_mutex); |
227 | if (serial->disconnected) | ||
228 | retval = -ENODEV; | ||
229 | else | ||
230 | retval = usb_autopm_get_interface(serial->interface); | ||
236 | if (retval) | 231 | if (retval) |
237 | goto bailout_module_put; | 232 | goto bailout_module_put; |
233 | |||
238 | /* only call the device specific open if this | 234 | /* only call the device specific open if this |
239 | * is the first time the port is opened */ | 235 | * is the first time the port is opened */ |
240 | retval = serial->type->open(tty, port, filp); | 236 | retval = serial->type->open(tty, port, filp); |
241 | if (retval) | 237 | if (retval) |
242 | goto bailout_interface_put; | 238 | goto bailout_interface_put; |
239 | mutex_unlock(&serial->disc_mutex); | ||
243 | } | 240 | } |
244 | 241 | ||
245 | mutex_unlock(&port->mutex); | 242 | mutex_unlock(&port->mutex); |
@@ -248,13 +245,16 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
248 | bailout_interface_put: | 245 | bailout_interface_put: |
249 | usb_autopm_put_interface(serial->interface); | 246 | usb_autopm_put_interface(serial->interface); |
250 | bailout_module_put: | 247 | bailout_module_put: |
248 | mutex_unlock(&serial->disc_mutex); | ||
251 | module_put(serial->type->driver.owner); | 249 | module_put(serial->type->driver.owner); |
252 | bailout_mutex_unlock: | 250 | bailout_mutex_unlock: |
253 | port->port.count = 0; | 251 | port->port.count = 0; |
254 | tty->driver_data = NULL; | 252 | tty->driver_data = NULL; |
255 | tty_port_tty_set(&port->port, NULL); | 253 | tty_port_tty_set(&port->port, NULL); |
256 | mutex_unlock(&port->mutex); | 254 | mutex_unlock(&port->mutex); |
257 | bailout_kref_put: | 255 | bailout_port_put: |
256 | put_device(&port->dev); | ||
257 | bailout_serial_put: | ||
258 | usb_serial_put(serial); | 258 | usb_serial_put(serial); |
259 | return retval; | 259 | return retval; |
260 | } | 260 | } |
@@ -262,6 +262,9 @@ bailout_kref_put: | |||
262 | static void serial_close(struct tty_struct *tty, struct file *filp) | 262 | static void serial_close(struct tty_struct *tty, struct file *filp) |
263 | { | 263 | { |
264 | struct usb_serial_port *port = tty->driver_data; | 264 | struct usb_serial_port *port = tty->driver_data; |
265 | struct usb_serial *serial; | ||
266 | struct module *owner; | ||
267 | int count; | ||
265 | 268 | ||
266 | if (!port) | 269 | if (!port) |
267 | return; | 270 | return; |
@@ -269,6 +272,8 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
269 | dbg("%s - port %d", __func__, port->number); | 272 | dbg("%s - port %d", __func__, port->number); |
270 | 273 | ||
271 | mutex_lock(&port->mutex); | 274 | mutex_lock(&port->mutex); |
275 | serial = port->serial; | ||
276 | owner = serial->type->driver.owner; | ||
272 | 277 | ||
273 | if (port->port.count == 0) { | 278 | if (port->port.count == 0) { |
274 | mutex_unlock(&port->mutex); | 279 | mutex_unlock(&port->mutex); |
@@ -281,7 +286,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
281 | * this before we drop the port count. The call is protected | 286 | * this before we drop the port count. The call is protected |
282 | * by the port mutex | 287 | * by the port mutex |
283 | */ | 288 | */ |
284 | port->serial->type->close(tty, port, filp); | 289 | serial->type->close(tty, port, filp); |
285 | 290 | ||
286 | if (port->port.count == (port->console ? 2 : 1)) { | 291 | if (port->port.count == (port->console ? 2 : 1)) { |
287 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 292 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
@@ -295,17 +300,23 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
295 | } | 300 | } |
296 | } | 301 | } |
297 | 302 | ||
298 | if (port->port.count == 1) { | ||
299 | mutex_lock(&port->serial->disc_mutex); | ||
300 | if (!port->serial->disconnected) | ||
301 | usb_autopm_put_interface(port->serial->interface); | ||
302 | mutex_unlock(&port->serial->disc_mutex); | ||
303 | module_put(port->serial->type->driver.owner); | ||
304 | } | ||
305 | --port->port.count; | 303 | --port->port.count; |
306 | 304 | count = port->port.count; | |
307 | mutex_unlock(&port->mutex); | 305 | mutex_unlock(&port->mutex); |
308 | usb_serial_put(port->serial); | 306 | put_device(&port->dev); |
307 | |||
308 | /* Mustn't dereference port any more */ | ||
309 | if (count == 0) { | ||
310 | mutex_lock(&serial->disc_mutex); | ||
311 | if (!serial->disconnected) | ||
312 | usb_autopm_put_interface(serial->interface); | ||
313 | mutex_unlock(&serial->disc_mutex); | ||
314 | } | ||
315 | usb_serial_put(serial); | ||
316 | |||
317 | /* Mustn't dereference serial any more */ | ||
318 | if (count == 0) | ||
319 | module_put(owner); | ||
309 | } | 320 | } |
310 | 321 | ||
311 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, | 322 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, |
@@ -549,7 +560,13 @@ static void kill_traffic(struct usb_serial_port *port) | |||
549 | 560 | ||
550 | static void port_free(struct usb_serial_port *port) | 561 | static void port_free(struct usb_serial_port *port) |
551 | { | 562 | { |
563 | /* | ||
564 | * Stop all the traffic before cancelling the work, so that | ||
565 | * nobody will restart it by calling usb_serial_port_softint. | ||
566 | */ | ||
552 | kill_traffic(port); | 567 | kill_traffic(port); |
568 | cancel_work_sync(&port->work); | ||
569 | |||
553 | usb_free_urb(port->read_urb); | 570 | usb_free_urb(port->read_urb); |
554 | usb_free_urb(port->write_urb); | 571 | usb_free_urb(port->write_urb); |
555 | usb_free_urb(port->interrupt_in_urb); | 572 | usb_free_urb(port->interrupt_in_urb); |
@@ -558,7 +575,6 @@ static void port_free(struct usb_serial_port *port) | |||
558 | kfree(port->bulk_out_buffer); | 575 | kfree(port->bulk_out_buffer); |
559 | kfree(port->interrupt_in_buffer); | 576 | kfree(port->interrupt_in_buffer); |
560 | kfree(port->interrupt_out_buffer); | 577 | kfree(port->interrupt_out_buffer); |
561 | flush_scheduled_work(); /* port->work */ | ||
562 | kfree(port); | 578 | kfree(port); |
563 | } | 579 | } |
564 | 580 | ||
@@ -1043,6 +1059,12 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1043 | usb_set_intfdata(interface, NULL); | 1059 | usb_set_intfdata(interface, NULL); |
1044 | /* must set a flag, to signal subdrivers */ | 1060 | /* must set a flag, to signal subdrivers */ |
1045 | serial->disconnected = 1; | 1061 | serial->disconnected = 1; |
1062 | mutex_unlock(&serial->disc_mutex); | ||
1063 | |||
1064 | /* Unfortunately, many of the sub-drivers expect the port structures | ||
1065 | * to exist when their shutdown method is called, so we have to go | ||
1066 | * through this awkward two-step unregistration procedure. | ||
1067 | */ | ||
1046 | for (i = 0; i < serial->num_ports; ++i) { | 1068 | for (i = 0; i < serial->num_ports; ++i) { |
1047 | port = serial->port[i]; | 1069 | port = serial->port[i]; |
1048 | if (port) { | 1070 | if (port) { |
@@ -1052,11 +1074,21 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1052 | tty_kref_put(tty); | 1074 | tty_kref_put(tty); |
1053 | } | 1075 | } |
1054 | kill_traffic(port); | 1076 | kill_traffic(port); |
1077 | cancel_work_sync(&port->work); | ||
1078 | device_del(&port->dev); | ||
1079 | } | ||
1080 | } | ||
1081 | serial->type->shutdown(serial); | ||
1082 | for (i = 0; i < serial->num_ports; ++i) { | ||
1083 | port = serial->port[i]; | ||
1084 | if (port) { | ||
1085 | put_device(&port->dev); | ||
1086 | serial->port[i] = NULL; | ||
1055 | } | 1087 | } |
1056 | } | 1088 | } |
1089 | |||
1057 | /* let the last holder of this object | 1090 | /* let the last holder of this object |
1058 | * cause it to be cleaned up */ | 1091 | * cause it to be cleaned up */ |
1059 | mutex_unlock(&serial->disc_mutex); | ||
1060 | usb_serial_put(serial); | 1092 | usb_serial_put(serial); |
1061 | dev_info(dev, "device disconnected\n"); | 1093 | dev_info(dev, "device disconnected\n"); |
1062 | } | 1094 | } |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 4facce3d9364..5ac414bda718 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -296,14 +296,6 @@ static int visor_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
296 | priv->throttled = 0; | 296 | priv->throttled = 0; |
297 | spin_unlock_irqrestore(&priv->lock, flags); | 297 | spin_unlock_irqrestore(&priv->lock, flags); |
298 | 298 | ||
299 | /* | ||
300 | * Force low_latency on so that our tty_push actually forces the data | ||
301 | * through, otherwise it is scheduled, and with high data rates (like | ||
302 | * with OHCI) data can get lost. | ||
303 | */ | ||
304 | if (tty) | ||
305 | tty->low_latency = 1; | ||
306 | |||
307 | /* Start reading from the device */ | 299 | /* Start reading from the device */ |
308 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 300 | usb_fill_bulk_urb(port->read_urb, serial->dev, |
309 | usb_rcvbulkpipe(serial->dev, | 301 | usb_rcvbulkpipe(serial->dev, |
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 5be54c019662..ef7e5a8ceab5 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
@@ -17,7 +17,8 @@ usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ | |||
17 | ifeq ($(CONFIG_USB_LIBUSUAL),) | 17 | ifeq ($(CONFIG_USB_LIBUSUAL),) |
18 | usb-storage-objs += usual-tables.o | 18 | usb-storage-objs += usual-tables.o |
19 | else | 19 | else |
20 | obj-$(CONFIG_USB) += libusual.o usual-tables.o | 20 | obj-$(CONFIG_USB) += usb-libusual.o |
21 | usb-libusual-objs := libusual.o usual-tables.o | ||
21 | endif | 22 | endif |
22 | 23 | ||
23 | obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o | 24 | obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o |
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 49aedb36dc19..fcb320217218 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
@@ -247,10 +247,8 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) | |||
247 | USB_ENDPOINT_HALT, endp, | 247 | USB_ENDPOINT_HALT, endp, |
248 | NULL, 0, 3*HZ); | 248 | NULL, 0, 3*HZ); |
249 | 249 | ||
250 | /* reset the endpoint toggle */ | ||
251 | if (result >= 0) | 250 | if (result >= 0) |
252 | usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe), | 251 | usb_reset_endpoint(us->pusb_dev, endp); |
253 | usb_pipeout(pipe), 0); | ||
254 | 252 | ||
255 | US_DEBUGP("%s: result = %d\n", __func__, result); | 253 | US_DEBUGP("%s: result = %d\n", __func__, result); |
256 | return result; | 254 | return result; |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 1c1f643e8a78..fa65a3b08601 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -975,12 +975,14 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, | |||
975 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 975 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
976 | US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ), | 976 | US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ), |
977 | 977 | ||
978 | /* Reported by Rauch Wolke <rauchwolke@gmx.net> */ | 978 | /* Reported by Rauch Wolke <rauchwolke@gmx.net> |
979 | * and augmented by binbin <binbinsh@gmail.com> (Bugzilla #12882) | ||
980 | */ | ||
979 | UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, | 981 | UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, |
980 | "Simple Tech/Datafab", | 982 | "Simple Tech/Datafab", |
981 | "CF+SM Reader", | 983 | "CF+SM Reader", |
982 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 984 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
983 | US_FL_IGNORE_RESIDUE ), | 985 | US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ), |
984 | 986 | ||
985 | /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant | 987 | /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant |
986 | * to the USB storage specification in two ways: | 988 | * to the USB storage specification in two ways: |
@@ -1376,6 +1378,14 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100, | |||
1376 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1378 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1377 | 0), | 1379 | 0), |
1378 | 1380 | ||
1381 | /* Reported by Pascal Terjan <pterjan@mandriva.com> | ||
1382 | * Ignore driver CD mode and force into modem mode by default. | ||
1383 | */ | ||
1384 | UNUSUAL_DEV( 0x1186, 0x3e04, 0x0000, 0x0000, | ||
1385 | "D-Link", | ||
1386 | "USB Mass Storage", | ||
1387 | US_SC_DEVICE, US_PR_DEVICE, option_ms_init, 0), | ||
1388 | |||
1379 | /* Reported by Kevin Lloyd <linux@sierrawireless.com> | 1389 | /* Reported by Kevin Lloyd <linux@sierrawireless.com> |
1380 | * Entry is needed for the initializer function override, | 1390 | * Entry is needed for the initializer function override, |
1381 | * which instructs the device to load as a modem | 1391 | * which instructs the device to load as a modem |
@@ -1841,6 +1851,12 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, | |||
1841 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1851 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1842 | US_FL_CAPACITY_HEURISTICS), | 1852 | US_FL_CAPACITY_HEURISTICS), |
1843 | 1853 | ||
1854 | /* Reported by Alessio Treglia <quadrispro@ubuntu.com> */ | ||
1855 | UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001, | ||
1856 | "TGE", | ||
1857 | "Digital MP3 Audio Player", | ||
1858 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), | ||
1859 | |||
1844 | /* Control/Bulk transport for all SubClass values */ | 1860 | /* Control/Bulk transport for all SubClass values */ |
1845 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), | 1861 | USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), |
1846 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), | 1862 | USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR), |
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 386eaa22d215..4ac4300a3f9a 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
@@ -267,6 +267,8 @@ static void wusbhc_devconnect_acked_work(struct work_struct *work) | |||
267 | mutex_lock(&wusbhc->mutex); | 267 | mutex_lock(&wusbhc->mutex); |
268 | wusbhc_devconnect_acked(wusbhc, wusb_dev); | 268 | wusbhc_devconnect_acked(wusbhc, wusb_dev); |
269 | mutex_unlock(&wusbhc->mutex); | 269 | mutex_unlock(&wusbhc->mutex); |
270 | |||
271 | wusb_dev_put(wusb_dev); | ||
270 | } | 272 | } |
271 | 273 | ||
272 | /* | 274 | /* |
@@ -396,7 +398,8 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | |||
396 | 398 | ||
397 | /* After a device disconnects, change the GTK (see [WUSB] | 399 | /* After a device disconnects, change the GTK (see [WUSB] |
398 | * section 6.2.11.2). */ | 400 | * section 6.2.11.2). */ |
399 | wusbhc_gtk_rekey(wusbhc); | 401 | if (wusbhc->active) |
402 | wusbhc_gtk_rekey(wusbhc); | ||
400 | 403 | ||
401 | /* The Wireless USB part has forgotten about the device already; now | 404 | /* The Wireless USB part has forgotten about the device already; now |
402 | * khubd's timer will pick up the disconnection and remove the USB | 405 | * khubd's timer will pick up the disconnection and remove the USB |
@@ -1084,15 +1087,21 @@ error_mmcie_set: | |||
1084 | * wusbhc_devconnect_stop - stop managing connected devices | 1087 | * wusbhc_devconnect_stop - stop managing connected devices |
1085 | * @wusbhc: the WUSB HC | 1088 | * @wusbhc: the WUSB HC |
1086 | * | 1089 | * |
1087 | * Removes the Host Info IE and stops the keep alives. | 1090 | * Disconnects any devices still connected, stops the keep alives and |
1088 | * | 1091 | * removes the Host Info IE. |
1089 | * FIXME: should this disconnect all devices? | ||
1090 | */ | 1092 | */ |
1091 | void wusbhc_devconnect_stop(struct wusbhc *wusbhc) | 1093 | void wusbhc_devconnect_stop(struct wusbhc *wusbhc) |
1092 | { | 1094 | { |
1093 | cancel_delayed_work_sync(&wusbhc->keep_alive_timer); | 1095 | int i; |
1094 | WARN_ON(!list_empty(&wusbhc->cack_list)); | ||
1095 | 1096 | ||
1097 | mutex_lock(&wusbhc->mutex); | ||
1098 | for (i = 0; i < wusbhc->ports_max; i++) { | ||
1099 | if (wusbhc->port[i].wusb_dev) | ||
1100 | __wusbhc_dev_disconnect(wusbhc, &wusbhc->port[i]); | ||
1101 | } | ||
1102 | mutex_unlock(&wusbhc->mutex); | ||
1103 | |||
1104 | cancel_delayed_work_sync(&wusbhc->keep_alive_timer); | ||
1096 | wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr); | 1105 | wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr); |
1097 | kfree(wusbhc->wuie_host_info); | 1106 | kfree(wusbhc->wuie_host_info); |
1098 | wusbhc->wuie_host_info = NULL; | 1107 | wusbhc->wuie_host_info = NULL; |
diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c index 07c63a31c799..ee6256f23636 100644 --- a/drivers/usb/wusbcore/wusbhc.c +++ b/drivers/usb/wusbcore/wusbhc.c | |||
@@ -88,33 +88,31 @@ static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show, | |||
88 | wusb_trust_timeout_store); | 88 | wusb_trust_timeout_store); |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Show & store the current WUSB CHID | 91 | * Show the current WUSB CHID. |
92 | */ | 92 | */ |
93 | static ssize_t wusb_chid_show(struct device *dev, | 93 | static ssize_t wusb_chid_show(struct device *dev, |
94 | struct device_attribute *attr, char *buf) | 94 | struct device_attribute *attr, char *buf) |
95 | { | 95 | { |
96 | struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); | 96 | struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev); |
97 | const struct wusb_ckhdid *chid; | ||
97 | ssize_t result = 0; | 98 | ssize_t result = 0; |
98 | 99 | ||
99 | if (wusbhc->wuie_host_info != NULL) | 100 | if (wusbhc->wuie_host_info != NULL) |
100 | result += ckhdid_printf(buf, PAGE_SIZE, | 101 | chid = &wusbhc->wuie_host_info->CHID; |
101 | &wusbhc->wuie_host_info->CHID); | 102 | else |
103 | chid = &wusb_ckhdid_zero; | ||
104 | |||
105 | result += ckhdid_printf(buf, PAGE_SIZE, chid); | ||
106 | result += sprintf(buf + result, "\n"); | ||
107 | |||
102 | return result; | 108 | return result; |
103 | } | 109 | } |
104 | 110 | ||
105 | /* | 111 | /* |
106 | * Store a new CHID | 112 | * Store a new CHID. |
107 | * | ||
108 | * This will (FIXME) trigger many changes. | ||
109 | * | ||
110 | * - Send an all zeros CHID and it will stop the controller | ||
111 | * - Send a non-zero CHID and it will start it | ||
112 | * (unless it was started, it will just change the CHID, | ||
113 | * diconnecting all devices first). | ||
114 | * | 113 | * |
115 | * So first we scan the MMC we are sent and then we act on it. We | 114 | * - Write an all zeros CHID and it will stop the controller |
116 | * read it in the same format as we print it, an ASCII string of 16 | 115 | * - Write a non-zero CHID and it will start it. |
117 | * hex bytes. | ||
118 | * | 116 | * |
119 | * See wusbhc_chid_set() for more info. | 117 | * See wusbhc_chid_set() for more info. |
120 | */ | 118 | */ |
@@ -339,13 +337,15 @@ void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb, int status) | |||
339 | { | 337 | { |
340 | struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); | 338 | struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); |
341 | 339 | ||
342 | if (status == 0) { | 340 | if (status == 0 && wusb_dev) { |
343 | wusb_dev->entry_ts = jiffies; | 341 | wusb_dev->entry_ts = jiffies; |
344 | 342 | ||
345 | /* wusbhc_devconnect_acked() can't be called from from | 343 | /* wusbhc_devconnect_acked() can't be called from |
346 | atomic context so defer it to a work queue. */ | 344 | atomic context so defer it to a work queue. */ |
347 | if (!list_empty(&wusb_dev->cack_node)) | 345 | if (!list_empty(&wusb_dev->cack_node)) |
348 | queue_work(wusbd, &wusb_dev->devconnect_acked_work); | 346 | queue_work(wusbd, &wusb_dev->devconnect_acked_work); |
347 | else | ||
348 | wusb_dev_put(wusb_dev); | ||
349 | } | 349 | } |
350 | 350 | ||
351 | usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status); | 351 | usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status); |
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index 1a1f946d8fef..9fe90ce928fb 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c | |||
@@ -533,6 +533,7 @@ static int __devinit init_asiliant(struct fb_info *p, unsigned long addr) | |||
533 | 533 | ||
534 | writeb(0xff, mmio_base + 0x78c); | 534 | writeb(0xff, mmio_base + 0x78c); |
535 | chips_hw_init(p); | 535 | chips_hw_init(p); |
536 | return 0; | ||
536 | } | 537 | } |
537 | 538 | ||
538 | static int __devinit | 539 | static int __devinit |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 16bb7e3c0310..6c37e8ee5efe 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -698,8 +698,8 @@ static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo) | |||
698 | found: | 698 | found: |
699 | /* | 699 | /* |
700 | * Some methods fail to retrieve SCLK and MCLK values, we apply default | 700 | * Some methods fail to retrieve SCLK and MCLK values, we apply default |
701 | * settings in this case (200Mhz). If that really happne often, we could | 701 | * settings in this case (200Mhz). If that really happens often, we |
702 | * fetch from registers instead... | 702 | * could fetch from registers instead... |
703 | */ | 703 | */ |
704 | if (rinfo->pll.mclk == 0) | 704 | if (rinfo->pll.mclk == 0) |
705 | rinfo->pll.mclk = 20000; | 705 | rinfo->pll.mclk = 20000; |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index dd37cbcaf8ce..157057c79ca3 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -35,8 +35,6 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
35 | return 0; | 35 | return 0; |
36 | 36 | ||
37 | bd = container_of(self, struct backlight_device, fb_notif); | 37 | bd = container_of(self, struct backlight_device, fb_notif); |
38 | if (!lock_fb_info(evdata->info)) | ||
39 | return -ENODEV; | ||
40 | mutex_lock(&bd->ops_lock); | 38 | mutex_lock(&bd->ops_lock); |
41 | if (bd->ops) | 39 | if (bd->ops) |
42 | if (!bd->ops->check_fb || | 40 | if (!bd->ops->check_fb || |
@@ -49,7 +47,6 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
49 | backlight_update_status(bd); | 47 | backlight_update_status(bd); |
50 | } | 48 | } |
51 | mutex_unlock(&bd->ops_lock); | 49 | mutex_unlock(&bd->ops_lock); |
52 | unlock_fb_info(evdata->info); | ||
53 | return 0; | 50 | return 0; |
54 | } | 51 | } |
55 | 52 | ||
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 0bb13df0fa89..b6449470106c 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -40,8 +40,6 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
40 | if (!ld->ops) | 40 | if (!ld->ops) |
41 | return 0; | 41 | return 0; |
42 | 42 | ||
43 | if (!lock_fb_info(evdata->info)) | ||
44 | return -ENODEV; | ||
45 | mutex_lock(&ld->ops_lock); | 43 | mutex_lock(&ld->ops_lock); |
46 | if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { | 44 | if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { |
47 | if (event == FB_EVENT_BLANK) { | 45 | if (event == FB_EVENT_BLANK) { |
@@ -53,7 +51,6 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
53 | } | 51 | } |
54 | } | 52 | } |
55 | mutex_unlock(&ld->ops_lock); | 53 | mutex_unlock(&ld->ops_lock); |
56 | unlock_fb_info(evdata->info); | ||
57 | return 0; | 54 | return 0; |
58 | } | 55 | } |
59 | 56 | ||
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index d42e385f091c..4c2bf923418c 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -567,9 +567,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, | |||
567 | default: | 567 | default: |
568 | dev_dbg(info->device, | 568 | dev_dbg(info->device, |
569 | "Unsupported bpp size: %d\n", var->bits_per_pixel); | 569 | "Unsupported bpp size: %d\n", var->bits_per_pixel); |
570 | assert(false); | 570 | return -EINVAL; |
571 | /* should never occur */ | ||
572 | break; | ||
573 | } | 571 | } |
574 | 572 | ||
575 | if (var->xres_virtual < var->xres) | 573 | if (var->xres_virtual < var->xres) |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 2cd500a304f2..471a9a60376a 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -2263,9 +2263,12 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, | |||
2263 | } | 2263 | } |
2264 | 2264 | ||
2265 | 2265 | ||
2266 | if (!lock_fb_info(info)) | ||
2267 | return; | ||
2266 | event.info = info; | 2268 | event.info = info; |
2267 | event.data = ␣ | 2269 | event.data = ␣ |
2268 | fb_notifier_call_chain(FB_EVENT_CONBLANK, &event); | 2270 | fb_notifier_call_chain(FB_EVENT_CONBLANK, &event); |
2271 | unlock_fb_info(info); | ||
2269 | } | 2272 | } |
2270 | 2273 | ||
2271 | static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) | 2274 | static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) |
@@ -2956,8 +2959,6 @@ static int fbcon_fb_unregistered(struct fb_info *info) | |||
2956 | { | 2959 | { |
2957 | int i, idx; | 2960 | int i, idx; |
2958 | 2961 | ||
2959 | if (!lock_fb_info(info)) | ||
2960 | return -ENODEV; | ||
2961 | idx = info->node; | 2962 | idx = info->node; |
2962 | for (i = first_fb_vc; i <= last_fb_vc; i++) { | 2963 | for (i = first_fb_vc; i <= last_fb_vc; i++) { |
2963 | if (con2fb_map[i] == idx) | 2964 | if (con2fb_map[i] == idx) |
@@ -2985,8 +2986,6 @@ static int fbcon_fb_unregistered(struct fb_info *info) | |||
2985 | if (primary_device == idx) | 2986 | if (primary_device == idx) |
2986 | primary_device = -1; | 2987 | primary_device = -1; |
2987 | 2988 | ||
2988 | unlock_fb_info(info); | ||
2989 | |||
2990 | if (!num_registered_fb) | 2989 | if (!num_registered_fb) |
2991 | unregister_con_driver(&fb_con); | 2990 | unregister_con_driver(&fb_con); |
2992 | 2991 | ||
@@ -3027,11 +3026,8 @@ static int fbcon_fb_registered(struct fb_info *info) | |||
3027 | { | 3026 | { |
3028 | int ret = 0, i, idx; | 3027 | int ret = 0, i, idx; |
3029 | 3028 | ||
3030 | if (!lock_fb_info(info)) | ||
3031 | return -ENODEV; | ||
3032 | idx = info->node; | 3029 | idx = info->node; |
3033 | fbcon_select_primary(info); | 3030 | fbcon_select_primary(info); |
3034 | unlock_fb_info(info); | ||
3035 | 3031 | ||
3036 | if (info_idx == -1) { | 3032 | if (info_idx == -1) { |
3037 | for (i = first_fb_vc; i <= last_fb_vc; i++) { | 3033 | for (i = first_fb_vc; i <= last_fb_vc; i++) { |
@@ -3152,53 +3148,23 @@ static int fbcon_event_notify(struct notifier_block *self, | |||
3152 | 3148 | ||
3153 | switch(action) { | 3149 | switch(action) { |
3154 | case FB_EVENT_SUSPEND: | 3150 | case FB_EVENT_SUSPEND: |
3155 | if (!lock_fb_info(info)) { | ||
3156 | ret = -ENODEV; | ||
3157 | goto done; | ||
3158 | } | ||
3159 | fbcon_suspended(info); | 3151 | fbcon_suspended(info); |
3160 | unlock_fb_info(info); | ||
3161 | break; | 3152 | break; |
3162 | case FB_EVENT_RESUME: | 3153 | case FB_EVENT_RESUME: |
3163 | if (!lock_fb_info(info)) { | ||
3164 | ret = -ENODEV; | ||
3165 | goto done; | ||
3166 | } | ||
3167 | fbcon_resumed(info); | 3154 | fbcon_resumed(info); |
3168 | unlock_fb_info(info); | ||
3169 | break; | 3155 | break; |
3170 | case FB_EVENT_MODE_CHANGE: | 3156 | case FB_EVENT_MODE_CHANGE: |
3171 | if (!lock_fb_info(info)) { | ||
3172 | ret = -ENODEV; | ||
3173 | goto done; | ||
3174 | } | ||
3175 | fbcon_modechanged(info); | 3157 | fbcon_modechanged(info); |
3176 | unlock_fb_info(info); | ||
3177 | break; | 3158 | break; |
3178 | case FB_EVENT_MODE_CHANGE_ALL: | 3159 | case FB_EVENT_MODE_CHANGE_ALL: |
3179 | if (!lock_fb_info(info)) { | ||
3180 | ret = -ENODEV; | ||
3181 | goto done; | ||
3182 | } | ||
3183 | fbcon_set_all_vcs(info); | 3160 | fbcon_set_all_vcs(info); |
3184 | unlock_fb_info(info); | ||
3185 | break; | 3161 | break; |
3186 | case FB_EVENT_MODE_DELETE: | 3162 | case FB_EVENT_MODE_DELETE: |
3187 | mode = event->data; | 3163 | mode = event->data; |
3188 | if (!lock_fb_info(info)) { | ||
3189 | ret = -ENODEV; | ||
3190 | goto done; | ||
3191 | } | ||
3192 | ret = fbcon_mode_deleted(info, mode); | 3164 | ret = fbcon_mode_deleted(info, mode); |
3193 | unlock_fb_info(info); | ||
3194 | break; | 3165 | break; |
3195 | case FB_EVENT_FB_UNBIND: | 3166 | case FB_EVENT_FB_UNBIND: |
3196 | if (!lock_fb_info(info)) { | ||
3197 | ret = -ENODEV; | ||
3198 | goto done; | ||
3199 | } | ||
3200 | idx = info->node; | 3167 | idx = info->node; |
3201 | unlock_fb_info(info); | ||
3202 | ret = fbcon_fb_unbind(idx); | 3168 | ret = fbcon_fb_unbind(idx); |
3203 | break; | 3169 | break; |
3204 | case FB_EVENT_FB_REGISTERED: | 3170 | case FB_EVENT_FB_REGISTERED: |
@@ -3217,29 +3183,14 @@ static int fbcon_event_notify(struct notifier_block *self, | |||
3217 | con2fb->framebuffer = con2fb_map[con2fb->console - 1]; | 3183 | con2fb->framebuffer = con2fb_map[con2fb->console - 1]; |
3218 | break; | 3184 | break; |
3219 | case FB_EVENT_BLANK: | 3185 | case FB_EVENT_BLANK: |
3220 | if (!lock_fb_info(info)) { | ||
3221 | ret = -ENODEV; | ||
3222 | goto done; | ||
3223 | } | ||
3224 | fbcon_fb_blanked(info, *(int *)event->data); | 3186 | fbcon_fb_blanked(info, *(int *)event->data); |
3225 | unlock_fb_info(info); | ||
3226 | break; | 3187 | break; |
3227 | case FB_EVENT_NEW_MODELIST: | 3188 | case FB_EVENT_NEW_MODELIST: |
3228 | if (!lock_fb_info(info)) { | ||
3229 | ret = -ENODEV; | ||
3230 | goto done; | ||
3231 | } | ||
3232 | fbcon_new_modelist(info); | 3189 | fbcon_new_modelist(info); |
3233 | unlock_fb_info(info); | ||
3234 | break; | 3190 | break; |
3235 | case FB_EVENT_GET_REQ: | 3191 | case FB_EVENT_GET_REQ: |
3236 | caps = event->data; | 3192 | caps = event->data; |
3237 | if (!lock_fb_info(info)) { | ||
3238 | ret = -ENODEV; | ||
3239 | goto done; | ||
3240 | } | ||
3241 | fbcon_get_requirement(info, caps); | 3193 | fbcon_get_requirement(info, caps); |
3242 | unlock_fb_info(info); | ||
3243 | break; | 3194 | break; |
3244 | } | 3195 | } |
3245 | done: | 3196 | done: |
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index 0c5b9a9fd56f..8dea2bc92705 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -210,12 +210,15 @@ static int __init efifb_probe(struct platform_device *dev) | |||
210 | unsigned int size_total; | 210 | unsigned int size_total; |
211 | int request_succeeded = 0; | 211 | int request_succeeded = 0; |
212 | 212 | ||
213 | printk(KERN_INFO "efifb: probing for efifb\n"); | ||
214 | |||
215 | if (!screen_info.lfb_depth) | 213 | if (!screen_info.lfb_depth) |
216 | screen_info.lfb_depth = 32; | 214 | screen_info.lfb_depth = 32; |
217 | if (!screen_info.pages) | 215 | if (!screen_info.pages) |
218 | screen_info.pages = 1; | 216 | screen_info.pages = 1; |
217 | if (!screen_info.lfb_base) { | ||
218 | printk(KERN_DEBUG "efifb: invalid framebuffer address\n"); | ||
219 | return -ENODEV; | ||
220 | } | ||
221 | printk(KERN_INFO "efifb: probing for efifb\n"); | ||
219 | 222 | ||
220 | /* just assume they're all unset if any are */ | 223 | /* just assume they're all unset if any are */ |
221 | if (!screen_info.blue_size) { | 224 | if (!screen_info.blue_size) { |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 2ac32e6b5953..d412a1ddc12f 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1097,8 +1097,11 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
1097 | return -EINVAL; | 1097 | return -EINVAL; |
1098 | con2fb.framebuffer = -1; | 1098 | con2fb.framebuffer = -1; |
1099 | event.data = &con2fb; | 1099 | event.data = &con2fb; |
1100 | if (!lock_fb_info(info)) | ||
1101 | return -ENODEV; | ||
1100 | event.info = info; | 1102 | event.info = info; |
1101 | fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); | 1103 | fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); |
1104 | unlock_fb_info(info); | ||
1102 | ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; | 1105 | ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; |
1103 | break; | 1106 | break; |
1104 | case FBIOPUT_CON2FBMAP: | 1107 | case FBIOPUT_CON2FBMAP: |
@@ -1115,8 +1118,11 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
1115 | break; | 1118 | break; |
1116 | } | 1119 | } |
1117 | event.data = &con2fb; | 1120 | event.data = &con2fb; |
1121 | if (!lock_fb_info(info)) | ||
1122 | return -ENODEV; | ||
1118 | event.info = info; | 1123 | event.info = info; |
1119 | ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); | 1124 | ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); |
1125 | unlock_fb_info(info); | ||
1120 | break; | 1126 | break; |
1121 | case FBIOBLANK: | 1127 | case FBIOBLANK: |
1122 | if (!lock_fb_info(info)) | 1128 | if (!lock_fb_info(info)) |
@@ -1521,7 +1527,10 @@ register_framebuffer(struct fb_info *fb_info) | |||
1521 | registered_fb[i] = fb_info; | 1527 | registered_fb[i] = fb_info; |
1522 | 1528 | ||
1523 | event.info = fb_info; | 1529 | event.info = fb_info; |
1530 | if (!lock_fb_info(fb_info)) | ||
1531 | return -ENODEV; | ||
1524 | fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); | 1532 | fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); |
1533 | unlock_fb_info(fb_info); | ||
1525 | return 0; | 1534 | return 0; |
1526 | } | 1535 | } |
1527 | 1536 | ||
@@ -1555,8 +1564,12 @@ unregister_framebuffer(struct fb_info *fb_info) | |||
1555 | goto done; | 1564 | goto done; |
1556 | } | 1565 | } |
1557 | 1566 | ||
1567 | |||
1568 | if (!lock_fb_info(fb_info)) | ||
1569 | return -ENODEV; | ||
1558 | event.info = fb_info; | 1570 | event.info = fb_info; |
1559 | ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); | 1571 | ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); |
1572 | unlock_fb_info(fb_info); | ||
1560 | 1573 | ||
1561 | if (ret) { | 1574 | if (ret) { |
1562 | ret = -EINVAL; | 1575 | ret = -EINVAL; |
@@ -1590,6 +1603,8 @@ void fb_set_suspend(struct fb_info *info, int state) | |||
1590 | { | 1603 | { |
1591 | struct fb_event event; | 1604 | struct fb_event event; |
1592 | 1605 | ||
1606 | if (!lock_fb_info(info)) | ||
1607 | return; | ||
1593 | event.info = info; | 1608 | event.info = info; |
1594 | if (state) { | 1609 | if (state) { |
1595 | fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); | 1610 | fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); |
@@ -1598,6 +1613,7 @@ void fb_set_suspend(struct fb_info *info, int state) | |||
1598 | info->state = FBINFO_STATE_RUNNING; | 1613 | info->state = FBINFO_STATE_RUNNING; |
1599 | fb_notifier_call_chain(FB_EVENT_RESUME, &event); | 1614 | fb_notifier_call_chain(FB_EVENT_RESUME, &event); |
1600 | } | 1615 | } |
1616 | unlock_fb_info(info); | ||
1601 | } | 1617 | } |
1602 | 1618 | ||
1603 | /** | 1619 | /** |
@@ -1667,8 +1683,11 @@ int fb_new_modelist(struct fb_info *info) | |||
1667 | err = 1; | 1683 | err = 1; |
1668 | 1684 | ||
1669 | if (!list_empty(&info->modelist)) { | 1685 | if (!list_empty(&info->modelist)) { |
1686 | if (!lock_fb_info(info)) | ||
1687 | return -ENODEV; | ||
1670 | event.info = info; | 1688 | event.info = info; |
1671 | err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); | 1689 | err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); |
1690 | unlock_fb_info(info); | ||
1672 | } | 1691 | } |
1673 | 1692 | ||
1674 | return err; | 1693 | return err; |
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index a50bea614804..40984551c927 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h | |||
@@ -53,6 +53,7 @@ | |||
53 | #define PCI_DEVICE_ID_INTEL_830M 0x3577 | 53 | #define PCI_DEVICE_ID_INTEL_830M 0x3577 |
54 | #define PCI_DEVICE_ID_INTEL_845G 0x2562 | 54 | #define PCI_DEVICE_ID_INTEL_845G 0x2562 |
55 | #define PCI_DEVICE_ID_INTEL_85XGM 0x3582 | 55 | #define PCI_DEVICE_ID_INTEL_85XGM 0x3582 |
56 | #define PCI_DEVICE_ID_INTEL_854 0x358E | ||
56 | #define PCI_DEVICE_ID_INTEL_865G 0x2572 | 57 | #define PCI_DEVICE_ID_INTEL_865G 0x2572 |
57 | #define PCI_DEVICE_ID_INTEL_915G 0x2582 | 58 | #define PCI_DEVICE_ID_INTEL_915G 0x2582 |
58 | #define PCI_DEVICE_ID_INTEL_915GM 0x2592 | 59 | #define PCI_DEVICE_ID_INTEL_915GM 0x2592 |
@@ -154,6 +155,7 @@ enum intel_chips { | |||
154 | INTEL_85XGM, | 155 | INTEL_85XGM, |
155 | INTEL_852GM, | 156 | INTEL_852GM, |
156 | INTEL_852GME, | 157 | INTEL_852GME, |
158 | INTEL_854, | ||
157 | INTEL_855GM, | 159 | INTEL_855GM, |
158 | INTEL_855GME, | 160 | INTEL_855GME, |
159 | INTEL_865G, | 161 | INTEL_865G, |
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c index b3065492bb20..487f2be47460 100644 --- a/drivers/video/intelfb/intelfb_i2c.c +++ b/drivers/video/intelfb/intelfb_i2c.c | |||
@@ -156,6 +156,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo) | |||
156 | switch(dinfo->chipset) { | 156 | switch(dinfo->chipset) { |
157 | case INTEL_830M: | 157 | case INTEL_830M: |
158 | case INTEL_845G: | 158 | case INTEL_845G: |
159 | case INTEL_854: | ||
159 | case INTEL_855GM: | 160 | case INTEL_855GM: |
160 | case INTEL_865G: | 161 | case INTEL_865G: |
161 | dinfo->output[i].type = INTELFB_OUTPUT_DVO; | 162 | dinfo->output[i].type = INTELFB_OUTPUT_DVO; |
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 6d8e5415c809..ace14fe02fc4 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -182,6 +182,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = { | |||
182 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G }, | 182 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G }, |
183 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM }, | 183 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM }, |
184 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, | 184 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, |
185 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_854, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_854 }, | ||
185 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, | 186 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, |
186 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, | 187 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, |
187 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, | 188 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, |
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 8b26b27c2db6..0689f97c5238 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
@@ -84,6 +84,11 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo) | |||
84 | dinfo->mobile = 0; | 84 | dinfo->mobile = 0; |
85 | dinfo->pll_index = PLLS_I8xx; | 85 | dinfo->pll_index = PLLS_I8xx; |
86 | return 0; | 86 | return 0; |
87 | case PCI_DEVICE_ID_INTEL_854: | ||
88 | dinfo->mobile = 1; | ||
89 | dinfo->name = "Intel(R) 854"; | ||
90 | dinfo->chipset = INTEL_854; | ||
91 | return 0; | ||
87 | case PCI_DEVICE_ID_INTEL_85XGM: | 92 | case PCI_DEVICE_ID_INTEL_85XGM: |
88 | tmp = 0; | 93 | tmp = 0; |
89 | dinfo->mobile = 1; | 94 | dinfo->mobile = 1; |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 84f63205c46d..0889d50c3288 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -1439,7 +1439,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) | |||
1439 | static irqreturn_t pxafb_handle_irq(int irq, void *dev_id) | 1439 | static irqreturn_t pxafb_handle_irq(int irq, void *dev_id) |
1440 | { | 1440 | { |
1441 | struct pxafb_info *fbi = dev_id; | 1441 | struct pxafb_info *fbi = dev_id; |
1442 | unsigned int lccr0, lcsr, lcsr1; | 1442 | unsigned int lccr0, lcsr; |
1443 | 1443 | ||
1444 | lcsr = lcd_readl(fbi, LCSR); | 1444 | lcsr = lcd_readl(fbi, LCSR); |
1445 | if (lcsr & LCSR_LDD) { | 1445 | if (lcsr & LCSR_LDD) { |
@@ -1455,14 +1455,16 @@ static irqreturn_t pxafb_handle_irq(int irq, void *dev_id) | |||
1455 | lcd_writel(fbi, LCSR, lcsr); | 1455 | lcd_writel(fbi, LCSR, lcsr); |
1456 | 1456 | ||
1457 | #ifdef CONFIG_FB_PXA_OVERLAY | 1457 | #ifdef CONFIG_FB_PXA_OVERLAY |
1458 | lcsr1 = lcd_readl(fbi, LCSR1); | 1458 | { |
1459 | if (lcsr1 & LCSR1_BS(1)) | 1459 | unsigned int lcsr1 = lcd_readl(fbi, LCSR1); |
1460 | complete(&fbi->overlay[0].branch_done); | 1460 | if (lcsr1 & LCSR1_BS(1)) |
1461 | complete(&fbi->overlay[0].branch_done); | ||
1461 | 1462 | ||
1462 | if (lcsr1 & LCSR1_BS(2)) | 1463 | if (lcsr1 & LCSR1_BS(2)) |
1463 | complete(&fbi->overlay[1].branch_done); | 1464 | complete(&fbi->overlay[1].branch_done); |
1464 | 1465 | ||
1465 | lcd_writel(fbi, LCSR1, lcsr1); | 1466 | lcd_writel(fbi, LCSR1, lcsr1); |
1467 | } | ||
1466 | #endif | 1468 | #endif |
1467 | return IRQ_HANDLED; | 1469 | return IRQ_HANDLED; |
1468 | } | 1470 | } |
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c index 4dcec48a1d78..c3fad34309ed 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/s3fb.c | |||
@@ -45,11 +45,11 @@ struct s3fb_info { | |||
45 | static const struct svga_fb_format s3fb_formats[] = { | 45 | static const struct svga_fb_format s3fb_formats[] = { |
46 | { 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, | 46 | { 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, |
47 | FB_TYPE_TEXT, FB_AUX_TEXT_SVGA_STEP4, FB_VISUAL_PSEUDOCOLOR, 8, 16}, | 47 | FB_TYPE_TEXT, FB_AUX_TEXT_SVGA_STEP4, FB_VISUAL_PSEUDOCOLOR, 8, 16}, |
48 | { 4, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, | 48 | { 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 0, |
49 | FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 16}, | 49 | FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 16}, |
50 | { 4, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 1, | 50 | { 4, {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0}, 1, |
51 | FB_TYPE_INTERLEAVED_PLANES, 1, FB_VISUAL_PSEUDOCOLOR, 8, 16}, | 51 | FB_TYPE_INTERLEAVED_PLANES, 1, FB_VISUAL_PSEUDOCOLOR, 8, 16}, |
52 | { 8, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0, | 52 | { 8, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0, |
53 | FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 4, 8}, | 53 | FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 4, 8}, |
54 | {16, {10, 5, 0}, {5, 5, 0}, {0, 5, 0}, {0, 0, 0}, 0, | 54 | {16, {10, 5, 0}, {5, 5, 0}, {0, 5, 0}, {0, 0, 0}, 0, |
55 | FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 2, 4}, | 55 | FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 2, 4}, |
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index fad58cf9ef73..10ddad8e17d6 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c | |||
@@ -199,16 +199,20 @@ | |||
199 | extern void (*sa1100fb_backlight_power)(int on); | 199 | extern void (*sa1100fb_backlight_power)(int on); |
200 | extern void (*sa1100fb_lcd_power)(int on); | 200 | extern void (*sa1100fb_lcd_power)(int on); |
201 | 201 | ||
202 | /* | 202 | static struct sa1100fb_rgb rgb_4 = { |
203 | * IMHO this looks wrong. In 8BPP, length should be 8. | ||
204 | */ | ||
205 | static struct sa1100fb_rgb rgb_8 = { | ||
206 | .red = { .offset = 0, .length = 4, }, | 203 | .red = { .offset = 0, .length = 4, }, |
207 | .green = { .offset = 0, .length = 4, }, | 204 | .green = { .offset = 0, .length = 4, }, |
208 | .blue = { .offset = 0, .length = 4, }, | 205 | .blue = { .offset = 0, .length = 4, }, |
209 | .transp = { .offset = 0, .length = 0, }, | 206 | .transp = { .offset = 0, .length = 0, }, |
210 | }; | 207 | }; |
211 | 208 | ||
209 | static struct sa1100fb_rgb rgb_8 = { | ||
210 | .red = { .offset = 0, .length = 8, }, | ||
211 | .green = { .offset = 0, .length = 8, }, | ||
212 | .blue = { .offset = 0, .length = 8, }, | ||
213 | .transp = { .offset = 0, .length = 0, }, | ||
214 | }; | ||
215 | |||
212 | static struct sa1100fb_rgb def_rgb_16 = { | 216 | static struct sa1100fb_rgb def_rgb_16 = { |
213 | .red = { .offset = 11, .length = 5, }, | 217 | .red = { .offset = 11, .length = 5, }, |
214 | .green = { .offset = 5, .length = 6, }, | 218 | .green = { .offset = 5, .length = 6, }, |
@@ -613,7 +617,7 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
613 | DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); | 617 | DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel); |
614 | switch (var->bits_per_pixel) { | 618 | switch (var->bits_per_pixel) { |
615 | case 4: | 619 | case 4: |
616 | rgbidx = RGB_8; | 620 | rgbidx = RGB_4; |
617 | break; | 621 | break; |
618 | case 8: | 622 | case 8: |
619 | rgbidx = RGB_8; | 623 | rgbidx = RGB_8; |
@@ -1382,6 +1386,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) | |||
1382 | fbi->fb.monspecs = monspecs; | 1386 | fbi->fb.monspecs = monspecs; |
1383 | fbi->fb.pseudo_palette = (fbi + 1); | 1387 | fbi->fb.pseudo_palette = (fbi + 1); |
1384 | 1388 | ||
1389 | fbi->rgb[RGB_4] = &rgb_4; | ||
1385 | fbi->rgb[RGB_8] = &rgb_8; | 1390 | fbi->rgb[RGB_8] = &rgb_8; |
1386 | fbi->rgb[RGB_16] = &def_rgb_16; | 1391 | fbi->rgb[RGB_16] = &def_rgb_16; |
1387 | 1392 | ||
diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h index 86831db9a042..1c3b459865d8 100644 --- a/drivers/video/sa1100fb.h +++ b/drivers/video/sa1100fb.h | |||
@@ -57,9 +57,10 @@ struct sa1100fb_lcd_reg { | |||
57 | unsigned long lccr3; | 57 | unsigned long lccr3; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | #define RGB_8 (0) | 60 | #define RGB_4 (0) |
61 | #define RGB_16 (1) | 61 | #define RGB_8 (1) |
62 | #define NR_RGB 2 | 62 | #define RGB_16 (2) |
63 | #define NR_RGB 3 | ||
63 | 64 | ||
64 | struct sa1100fb_info { | 65 | struct sa1100fb_info { |
65 | struct fb_info fb; | 66 | struct fb_info fb; |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 346d6458cf76..7e17ee95a97a 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -1129,7 +1129,7 @@ sisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var) | |||
1129 | switch(var->bits_per_pixel) { | 1129 | switch(var->bits_per_pixel) { |
1130 | case 8: | 1130 | case 8: |
1131 | var->red.offset = var->green.offset = var->blue.offset = 0; | 1131 | var->red.offset = var->green.offset = var->blue.offset = 0; |
1132 | var->red.length = var->green.length = var->blue.length = 6; | 1132 | var->red.length = var->green.length = var->blue.length = 8; |
1133 | break; | 1133 | break; |
1134 | case 16: | 1134 | case 16: |
1135 | var->red.offset = 11; | 1135 | var->red.offset = 11; |
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c index a439159204a8..89158bc71da2 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/skeletonfb.c | |||
@@ -308,9 +308,11 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
308 | * color depth = SUM(var->{color}.length) | 308 | * color depth = SUM(var->{color}.length) |
309 | * | 309 | * |
310 | * Pseudocolor: | 310 | * Pseudocolor: |
311 | * var->{color}.offset is 0 | 311 | * var->{color}.offset is 0 unless the palette index takes less than |
312 | * var->{color}.length contains width of DAC or the number of unique | 312 | * bits_per_pixel bits and is stored in the upper |
313 | * colors available (color depth) | 313 | * bits of the pixel value |
314 | * var->{color}.length is set so that 1 << length is the number of | ||
315 | * available palette entries | ||
314 | * pseudo_palette is not used | 316 | * pseudo_palette is not used |
315 | * RAMDAC[X] is programmed to (red, green, blue) | 317 | * RAMDAC[X] is programmed to (red, green, blue) |
316 | * color depth = var->{color}.length | 318 | * color depth = var->{color}.length |
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index 0b370aebdbfd..421770b5e6ab 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c | |||
@@ -55,6 +55,7 @@ static u16 maxvf __devinitdata; /* maximum vertical frequency */ | |||
55 | static u16 maxhf __devinitdata; /* maximum horizontal frequency */ | 55 | static u16 maxhf __devinitdata; /* maximum horizontal frequency */ |
56 | static u16 vbemode __devinitdata; /* force use of a specific VBE mode */ | 56 | static u16 vbemode __devinitdata; /* force use of a specific VBE mode */ |
57 | static char *mode_option __devinitdata; | 57 | static char *mode_option __devinitdata; |
58 | static u8 dac_width = 6; | ||
58 | 59 | ||
59 | static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX]; | 60 | static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX]; |
60 | static DEFINE_MUTEX(uvfb_lock); | 61 | static DEFINE_MUTEX(uvfb_lock); |
@@ -303,22 +304,10 @@ static void uvesafb_setup_var(struct fb_var_screeninfo *var, | |||
303 | var->blue.offset = 0; | 304 | var->blue.offset = 0; |
304 | var->transp.offset = 0; | 305 | var->transp.offset = 0; |
305 | 306 | ||
306 | /* | 307 | var->red.length = 8; |
307 | * We're assuming that we can switch the DAC to 8 bits. If | 308 | var->green.length = 8; |
308 | * this proves to be incorrect, we'll update the fields | 309 | var->blue.length = 8; |
309 | * later in set_par(). | 310 | var->transp.length = 0; |
310 | */ | ||
311 | if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) { | ||
312 | var->red.length = 8; | ||
313 | var->green.length = 8; | ||
314 | var->blue.length = 8; | ||
315 | var->transp.length = 0; | ||
316 | } else { | ||
317 | var->red.length = 6; | ||
318 | var->green.length = 6; | ||
319 | var->blue.length = 6; | ||
320 | var->transp.length = 0; | ||
321 | } | ||
322 | } | 311 | } |
323 | } | 312 | } |
324 | 313 | ||
@@ -1006,7 +995,7 @@ static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1006 | struct fb_info *info) | 995 | struct fb_info *info) |
1007 | { | 996 | { |
1008 | struct uvesafb_pal_entry entry; | 997 | struct uvesafb_pal_entry entry; |
1009 | int shift = 16 - info->var.green.length; | 998 | int shift = 16 - dac_width; |
1010 | int err = 0; | 999 | int err = 0; |
1011 | 1000 | ||
1012 | if (regno >= info->cmap.len) | 1001 | if (regno >= info->cmap.len) |
@@ -1055,7 +1044,7 @@ static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1055 | static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info) | 1044 | static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info) |
1056 | { | 1045 | { |
1057 | struct uvesafb_pal_entry *entries; | 1046 | struct uvesafb_pal_entry *entries; |
1058 | int shift = 16 - info->var.green.length; | 1047 | int shift = 16 - dac_width; |
1059 | int i, err = 0; | 1048 | int i, err = 0; |
1060 | 1049 | ||
1061 | if (info->var.bits_per_pixel == 8) { | 1050 | if (info->var.bits_per_pixel == 8) { |
@@ -1317,13 +1306,9 @@ setmode: | |||
1317 | err = uvesafb_exec(task); | 1306 | err = uvesafb_exec(task); |
1318 | if (err || (task->t.regs.eax & 0xffff) != 0x004f || | 1307 | if (err || (task->t.regs.eax & 0xffff) != 0x004f || |
1319 | ((task->t.regs.ebx & 0xff00) >> 8) != 8) { | 1308 | ((task->t.regs.ebx & 0xff00) >> 8) != 8) { |
1320 | /* | 1309 | dac_width = 6; |
1321 | * We've failed to set the DAC palette format - | 1310 | } else { |
1322 | * time to correct var. | 1311 | dac_width = 8; |
1323 | */ | ||
1324 | info->var.red.length = 6; | ||
1325 | info->var.green.length = 6; | ||
1326 | info->var.blue.length = 6; | ||
1327 | } | 1312 | } |
1328 | } | 1313 | } |
1329 | 1314 | ||
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index cc919ae46571..050d432c7d95 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c | |||
@@ -318,13 +318,16 @@ static int vfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
318 | * {hardwarespecific} contains width of RAMDAC | 318 | * {hardwarespecific} contains width of RAMDAC |
319 | * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) | 319 | * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) |
320 | * RAMDAC[X] is programmed to (red, green, blue) | 320 | * RAMDAC[X] is programmed to (red, green, blue) |
321 | * | 321 | * |
322 | * Pseudocolor: | 322 | * Pseudocolor: |
323 | * uses offset = 0 && length = RAMDAC register width. | 323 | * var->{color}.offset is 0 unless the palette index takes less than |
324 | * var->{color}.offset is 0 | 324 | * bits_per_pixel bits and is stored in the upper |
325 | * var->{color}.length contains widht of DAC | 325 | * bits of the pixel value |
326 | * var->{color}.length is set so that 1 << length is the number of available | ||
327 | * palette entries | ||
326 | * cmap is not used | 328 | * cmap is not used |
327 | * RAMDAC[X] is programmed to (red, green, blue) | 329 | * RAMDAC[X] is programmed to (red, green, blue) |
330 | * | ||
328 | * Truecolor: | 331 | * Truecolor: |
329 | * does not use DAC. Usually 3 are present. | 332 | * does not use DAC. Usually 3 are present. |
330 | * var->{color}.offset contains start of bitfield | 333 | * var->{color}.offset contains start of bitfield |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 59268266b79a..9c76a061a04d 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -190,7 +190,8 @@ static int balloon(void *_vballoon) | |||
190 | try_to_freeze(); | 190 | try_to_freeze(); |
191 | wait_event_interruptible(vb->config_change, | 191 | wait_event_interruptible(vb->config_change, |
192 | (diff = towards_target(vb)) != 0 | 192 | (diff = towards_target(vb)) != 0 |
193 | || kthread_should_stop()); | 193 | || kthread_should_stop() |
194 | || freezing(current)); | ||
194 | if (diff > 0) | 195 | if (diff > 0) |
195 | fill_balloon(vb, diff); | 196 | fill_balloon(vb, diff); |
196 | else if (diff < 0) | 197 | else if (diff < 0) |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 63024145215d..5eb8f21da82e 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -240,8 +240,6 @@ config ORION5X_WATCHDOG | |||
240 | To compile this driver as a module, choose M here: the | 240 | To compile this driver as a module, choose M here: the |
241 | module will be called orion5x_wdt. | 241 | module will be called orion5x_wdt. |
242 | 242 | ||
243 | # ARM26 Architecture | ||
244 | |||
245 | # AVR32 Architecture | 243 | # AVR32 Architecture |
246 | 244 | ||
247 | config AT32AP700X_WDT | 245 | config AT32AP700X_WDT |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 806b3eb08536..7f8c56b14f58 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -42,8 +42,6 @@ obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o | |||
42 | obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o | 42 | obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o |
43 | obj-$(CONFIG_ORION5X_WATCHDOG) += orion5x_wdt.o | 43 | obj-$(CONFIG_ORION5X_WATCHDOG) += orion5x_wdt.o |
44 | 44 | ||
45 | # ARM26 Architecture | ||
46 | |||
47 | # AVR32 Architecture | 45 | # AVR32 Architecture |
48 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o | 46 | obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o |
49 | 47 | ||
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index e35d54589232..29e52c237a3b 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c | |||
@@ -197,7 +197,7 @@ static struct miscdevice at91wdt_miscdev = { | |||
197 | .fops = &at91wdt_fops, | 197 | .fops = &at91wdt_fops, |
198 | }; | 198 | }; |
199 | 199 | ||
200 | static int __init at91wdt_probe(struct platform_device *pdev) | 200 | static int __devinit at91wdt_probe(struct platform_device *pdev) |
201 | { | 201 | { |
202 | int res; | 202 | int res; |
203 | 203 | ||
@@ -214,7 +214,7 @@ static int __init at91wdt_probe(struct platform_device *pdev) | |||
214 | return 0; | 214 | return 0; |
215 | } | 215 | } |
216 | 216 | ||
217 | static int __exit at91wdt_remove(struct platform_device *pdev) | 217 | static int __devexit at91wdt_remove(struct platform_device *pdev) |
218 | { | 218 | { |
219 | int res; | 219 | int res; |
220 | 220 | ||
@@ -252,7 +252,7 @@ static int at91wdt_resume(struct platform_device *pdev) | |||
252 | 252 | ||
253 | static struct platform_driver at91wdt_driver = { | 253 | static struct platform_driver at91wdt_driver = { |
254 | .probe = at91wdt_probe, | 254 | .probe = at91wdt_probe, |
255 | .remove = __exit_p(at91wdt_remove), | 255 | .remove = __devexit_p(at91wdt_remove), |
256 | .shutdown = at91wdt_shutdown, | 256 | .shutdown = at91wdt_shutdown, |
257 | .suspend = at91wdt_suspend, | 257 | .suspend = at91wdt_suspend, |
258 | .resume = at91wdt_resume, | 258 | .resume = at91wdt_resume, |
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index 2dbe83570d65..7ba0b11ec525 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c | |||
@@ -52,10 +52,10 @@ | |||
52 | #define ESB_LOCK_REG 0x68 /* WDT lock register */ | 52 | #define ESB_LOCK_REG 0x68 /* WDT lock register */ |
53 | 53 | ||
54 | /* Memory mapped registers */ | 54 | /* Memory mapped registers */ |
55 | #define ESB_TIMER1_REG BASEADDR + 0x00 /* Timer1 value after each reset */ | 55 | #define ESB_TIMER1_REG (BASEADDR + 0x00)/* Timer1 value after each reset */ |
56 | #define ESB_TIMER2_REG BASEADDR + 0x04 /* Timer2 value after each reset */ | 56 | #define ESB_TIMER2_REG (BASEADDR + 0x04)/* Timer2 value after each reset */ |
57 | #define ESB_GINTSR_REG BASEADDR + 0x08 /* General Interrupt Status Register */ | 57 | #define ESB_GINTSR_REG (BASEADDR + 0x08)/* General Interrupt Status Register */ |
58 | #define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */ | 58 | #define ESB_RELOAD_REG (BASEADDR + 0x0c)/* Reload register */ |
59 | 59 | ||
60 | /* Lock register bits */ | 60 | /* Lock register bits */ |
61 | #define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */ | 61 | #define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */ |
@@ -68,6 +68,7 @@ | |||
68 | #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ | 68 | #define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ |
69 | 69 | ||
70 | /* Reload register bits */ | 70 | /* Reload register bits */ |
71 | #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ | ||
71 | #define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */ | 72 | #define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */ |
72 | 73 | ||
73 | /* Magic constants */ | 74 | /* Magic constants */ |
@@ -87,7 +88,6 @@ static struct platform_device *esb_platform_device; | |||
87 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ | 88 | /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ |
88 | #define WATCHDOG_HEARTBEAT 30 | 89 | #define WATCHDOG_HEARTBEAT 30 |
89 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ | 90 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ |
90 | |||
91 | module_param(heartbeat, int, 0); | 91 | module_param(heartbeat, int, 0); |
92 | MODULE_PARM_DESC(heartbeat, | 92 | MODULE_PARM_DESC(heartbeat, |
93 | "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" | 93 | "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" |
@@ -123,7 +123,7 @@ static int esb_timer_start(void) | |||
123 | esb_unlock_registers(); | 123 | esb_unlock_registers(); |
124 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); | 124 | writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); |
125 | /* Enable or Enable + Lock? */ | 125 | /* Enable or Enable + Lock? */ |
126 | val = 0x02 | (nowayout ? 0x01 : 0x00); | 126 | val = ESB_WDT_ENABLE | (nowayout ? ESB_WDT_LOCK : 0x00); |
127 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, val); | 127 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, val); |
128 | spin_unlock(&esb_lock); | 128 | spin_unlock(&esb_lock); |
129 | return 0; | 129 | return 0; |
@@ -143,7 +143,7 @@ static int esb_timer_stop(void) | |||
143 | spin_unlock(&esb_lock); | 143 | spin_unlock(&esb_lock); |
144 | 144 | ||
145 | /* Returns 0 if the timer was disabled, non-zero otherwise */ | 145 | /* Returns 0 if the timer was disabled, non-zero otherwise */ |
146 | return (val & 0x01); | 146 | return val & ESB_WDT_ENABLE; |
147 | } | 147 | } |
148 | 148 | ||
149 | static void esb_timer_keepalive(void) | 149 | static void esb_timer_keepalive(void) |
@@ -190,18 +190,6 @@ static int esb_timer_set_heartbeat(int time) | |||
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | 192 | ||
193 | static int esb_timer_read(void) | ||
194 | { | ||
195 | u32 count; | ||
196 | |||
197 | /* This isn't documented, and doesn't take into | ||
198 | * acount which stage is running, but it looks | ||
199 | * like a 20 bit count down, so we might as well report it. | ||
200 | */ | ||
201 | pci_read_config_dword(esb_pci, 0x64, &count); | ||
202 | return (int)count; | ||
203 | } | ||
204 | |||
205 | /* | 193 | /* |
206 | * /dev/watchdog handling | 194 | * /dev/watchdog handling |
207 | */ | 195 | */ |
@@ -282,7 +270,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
282 | sizeof(ident)) ? -EFAULT : 0; | 270 | sizeof(ident)) ? -EFAULT : 0; |
283 | 271 | ||
284 | case WDIOC_GETSTATUS: | 272 | case WDIOC_GETSTATUS: |
285 | return put_user(esb_timer_read(), p); | 273 | return put_user(0, p); |
286 | 274 | ||
287 | case WDIOC_GETBOOTSTATUS: | 275 | case WDIOC_GETBOOTSTATUS: |
288 | return put_user(triggered, p); | 276 | return put_user(triggered, p); |
@@ -362,8 +350,6 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl); | |||
362 | 350 | ||
363 | static unsigned char __devinit esb_getdevice(void) | 351 | static unsigned char __devinit esb_getdevice(void) |
364 | { | 352 | { |
365 | u8 val1; | ||
366 | unsigned short val2; | ||
367 | /* | 353 | /* |
368 | * Find the PCI device | 354 | * Find the PCI device |
369 | */ | 355 | */ |
@@ -371,66 +357,79 @@ static unsigned char __devinit esb_getdevice(void) | |||
371 | esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL, | 357 | esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL, |
372 | PCI_DEVICE_ID_INTEL_ESB_9, NULL); | 358 | PCI_DEVICE_ID_INTEL_ESB_9, NULL); |
373 | 359 | ||
374 | if (esb_pci) { | 360 | if (!esb_pci) |
375 | if (pci_enable_device(esb_pci)) { | 361 | return 0; |
376 | printk(KERN_ERR PFX "failed to enable device\n"); | ||
377 | goto err_devput; | ||
378 | } | ||
379 | 362 | ||
380 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { | 363 | if (pci_enable_device(esb_pci)) { |
381 | printk(KERN_ERR PFX "failed to request region\n"); | 364 | printk(KERN_ERR PFX "failed to enable device\n"); |
382 | goto err_disable; | 365 | goto err_devput; |
383 | } | 366 | } |
384 | 367 | ||
385 | BASEADDR = pci_ioremap_bar(esb_pci, 0); | 368 | if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { |
386 | if (BASEADDR == NULL) { | 369 | printk(KERN_ERR PFX "failed to request region\n"); |
387 | /* Something's wrong here, BASEADDR has to be set */ | 370 | goto err_disable; |
388 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); | 371 | } |
389 | goto err_release; | ||
390 | } | ||
391 | 372 | ||
392 | /* | 373 | BASEADDR = pci_ioremap_bar(esb_pci, 0); |
393 | * The watchdog has two timers, it can be setup so that the | 374 | if (BASEADDR == NULL) { |
394 | * expiry of timer1 results in an interrupt and the expiry of | 375 | /* Something's wrong here, BASEADDR has to be set */ |
395 | * timer2 results in a reboot. We set it to not generate | 376 | printk(KERN_ERR PFX "failed to get BASEADDR\n"); |
396 | * any interrupts as there is not much we can do with it | 377 | goto err_release; |
397 | * right now. | 378 | } |
398 | * | 379 | |
399 | * We also enable reboots and set the timer frequency to | 380 | /* Done */ |
400 | * the PCI clock divided by 2^15 (approx 1KHz). | 381 | return 1; |
401 | */ | ||
402 | pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003); | ||
403 | |||
404 | /* Check that the WDT isn't already locked */ | ||
405 | pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); | ||
406 | if (val1 & ESB_WDT_LOCK) | ||
407 | printk(KERN_WARNING PFX "nowayout already set\n"); | ||
408 | |||
409 | /* Set the timer to watchdog mode and disable it for now */ | ||
410 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); | ||
411 | |||
412 | /* Check if the watchdog was previously triggered */ | ||
413 | esb_unlock_registers(); | ||
414 | val2 = readw(ESB_RELOAD_REG); | ||
415 | triggered = (val2 & (0x01 << 9) >> 9); | ||
416 | |||
417 | /* Reset trigger flag and timers */ | ||
418 | esb_unlock_registers(); | ||
419 | writew((0x11 << 8), ESB_RELOAD_REG); | ||
420 | |||
421 | /* Done */ | ||
422 | return 1; | ||
423 | 382 | ||
424 | err_release: | 383 | err_release: |
425 | pci_release_region(esb_pci, 0); | 384 | pci_release_region(esb_pci, 0); |
426 | err_disable: | 385 | err_disable: |
427 | pci_disable_device(esb_pci); | 386 | pci_disable_device(esb_pci); |
428 | err_devput: | 387 | err_devput: |
429 | pci_dev_put(esb_pci); | 388 | pci_dev_put(esb_pci); |
430 | } | ||
431 | return 0; | 389 | return 0; |
432 | } | 390 | } |
433 | 391 | ||
392 | static void __devinit esb_initdevice(void) | ||
393 | { | ||
394 | u8 val1; | ||
395 | u16 val2; | ||
396 | |||
397 | /* | ||
398 | * Config register: | ||
399 | * Bit 5 : 0 = Enable WDT_OUTPUT | ||
400 | * Bit 2 : 0 = set the timer frequency to the PCI clock | ||
401 | * divided by 2^15 (approx 1KHz). | ||
402 | * Bits 1:0 : 11 = WDT_INT_TYPE Disabled. | ||
403 | * The watchdog has two timers, it can be setup so that the | ||
404 | * expiry of timer1 results in an interrupt and the expiry of | ||
405 | * timer2 results in a reboot. We set it to not generate | ||
406 | * any interrupts as there is not much we can do with it | ||
407 | * right now. | ||
408 | */ | ||
409 | pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003); | ||
410 | |||
411 | /* Check that the WDT isn't already locked */ | ||
412 | pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); | ||
413 | if (val1 & ESB_WDT_LOCK) | ||
414 | printk(KERN_WARNING PFX "nowayout already set\n"); | ||
415 | |||
416 | /* Set the timer to watchdog mode and disable it for now */ | ||
417 | pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); | ||
418 | |||
419 | /* Check if the watchdog was previously triggered */ | ||
420 | esb_unlock_registers(); | ||
421 | val2 = readw(ESB_RELOAD_REG); | ||
422 | if (val2 & ESB_WDT_TIMEOUT) | ||
423 | triggered = WDIOF_CARDRESET; | ||
424 | |||
425 | /* Reset WDT_TIMEOUT flag and timers */ | ||
426 | esb_unlock_registers(); | ||
427 | writew((ESB_WDT_TIMEOUT | ESB_WDT_RELOAD), ESB_RELOAD_REG); | ||
428 | |||
429 | /* And set the correct timeout value */ | ||
430 | esb_timer_set_heartbeat(heartbeat); | ||
431 | } | ||
432 | |||
434 | static int __devinit esb_probe(struct platform_device *dev) | 433 | static int __devinit esb_probe(struct platform_device *dev) |
435 | { | 434 | { |
436 | int ret; | 435 | int ret; |
@@ -441,13 +440,17 @@ static int __devinit esb_probe(struct platform_device *dev) | |||
441 | 440 | ||
442 | /* Check that the heartbeat value is within it's range; | 441 | /* Check that the heartbeat value is within it's range; |
443 | if not reset to the default */ | 442 | if not reset to the default */ |
444 | if (esb_timer_set_heartbeat(heartbeat)) { | 443 | if (heartbeat < 0x1 || heartbeat > 2 * 0x03ff) { |
445 | esb_timer_set_heartbeat(WATCHDOG_HEARTBEAT); | 444 | heartbeat = WATCHDOG_HEARTBEAT; |
446 | printk(KERN_INFO PFX | 445 | printk(KERN_INFO PFX |
447 | "heartbeat value must be 1<heartbeat<2046, using %d\n", | 446 | "heartbeat value must be 1<heartbeat<2046, using %d\n", |
448 | heartbeat); | 447 | heartbeat); |
449 | } | 448 | } |
450 | 449 | ||
450 | /* Initialize the watchdog and make sure it does not run */ | ||
451 | esb_initdevice(); | ||
452 | |||
453 | /* Register the watchdog so that userspace has access to it */ | ||
451 | ret = misc_register(&esb_miscdev); | 454 | ret = misc_register(&esb_miscdev); |
452 | if (ret != 0) { | 455 | if (ret != 0) { |
453 | printk(KERN_ERR PFX | 456 | printk(KERN_ERR PFX |
@@ -455,7 +458,6 @@ static int __devinit esb_probe(struct platform_device *dev) | |||
455 | WATCHDOG_MINOR, ret); | 458 | WATCHDOG_MINOR, ret); |
456 | goto err_unmap; | 459 | goto err_unmap; |
457 | } | 460 | } |
458 | esb_timer_stop(); | ||
459 | printk(KERN_INFO PFX | 461 | printk(KERN_INFO PFX |
460 | "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", | 462 | "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", |
461 | BASEADDR, heartbeat, nowayout); | 463 | BASEADDR, heartbeat, nowayout); |
@@ -463,11 +465,8 @@ static int __devinit esb_probe(struct platform_device *dev) | |||
463 | 465 | ||
464 | err_unmap: | 466 | err_unmap: |
465 | iounmap(BASEADDR); | 467 | iounmap(BASEADDR); |
466 | /* err_release: */ | ||
467 | pci_release_region(esb_pci, 0); | 468 | pci_release_region(esb_pci, 0); |
468 | /* err_disable: */ | ||
469 | pci_disable_device(esb_pci); | 469 | pci_disable_device(esb_pci); |
470 | /* err_devput: */ | ||
471 | pci_dev_put(esb_pci); | 470 | pci_dev_put(esb_pci); |
472 | return ret; | 471 | return ret; |
473 | } | 472 | } |
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index 74c92d384112..ae3832110acb 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c | |||
@@ -221,7 +221,7 @@ static struct miscdevice ks8695wdt_miscdev = { | |||
221 | .fops = &ks8695wdt_fops, | 221 | .fops = &ks8695wdt_fops, |
222 | }; | 222 | }; |
223 | 223 | ||
224 | static int __init ks8695wdt_probe(struct platform_device *pdev) | 224 | static int __devinit ks8695wdt_probe(struct platform_device *pdev) |
225 | { | 225 | { |
226 | int res; | 226 | int res; |
227 | 227 | ||
@@ -238,7 +238,7 @@ static int __init ks8695wdt_probe(struct platform_device *pdev) | |||
238 | return 0; | 238 | return 0; |
239 | } | 239 | } |
240 | 240 | ||
241 | static int __exit ks8695wdt_remove(struct platform_device *pdev) | 241 | static int __devexit ks8695wdt_remove(struct platform_device *pdev) |
242 | { | 242 | { |
243 | int res; | 243 | int res; |
244 | 244 | ||
@@ -276,7 +276,7 @@ static int ks8695wdt_resume(struct platform_device *pdev) | |||
276 | 276 | ||
277 | static struct platform_driver ks8695wdt_driver = { | 277 | static struct platform_driver ks8695wdt_driver = { |
278 | .probe = ks8695wdt_probe, | 278 | .probe = ks8695wdt_probe, |
279 | .remove = __exit_p(ks8695wdt_remove), | 279 | .remove = __devexit_p(ks8695wdt_remove), |
280 | .shutdown = ks8695wdt_shutdown, | 280 | .shutdown = ks8695wdt_shutdown, |
281 | .suspend = ks8695wdt_suspend, | 281 | .suspend = ks8695wdt_suspend, |
282 | .resume = ks8695wdt_resume, | 282 | .resume = ks8695wdt_resume, |
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index aa5ad6e33f02..f2713851aaab 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
@@ -258,7 +258,7 @@ static const struct file_operations omap_wdt_fops = { | |||
258 | .release = omap_wdt_release, | 258 | .release = omap_wdt_release, |
259 | }; | 259 | }; |
260 | 260 | ||
261 | static int __init omap_wdt_probe(struct platform_device *pdev) | 261 | static int __devinit omap_wdt_probe(struct platform_device *pdev) |
262 | { | 262 | { |
263 | struct resource *res, *mem; | 263 | struct resource *res, *mem; |
264 | struct omap_wdt_dev *wdev; | 264 | struct omap_wdt_dev *wdev; |
@@ -367,7 +367,7 @@ static void omap_wdt_shutdown(struct platform_device *pdev) | |||
367 | omap_wdt_disable(wdev); | 367 | omap_wdt_disable(wdev); |
368 | } | 368 | } |
369 | 369 | ||
370 | static int omap_wdt_remove(struct platform_device *pdev) | 370 | static int __devexit omap_wdt_remove(struct platform_device *pdev) |
371 | { | 371 | { |
372 | struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); | 372 | struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); |
373 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 373 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -426,7 +426,7 @@ static int omap_wdt_resume(struct platform_device *pdev) | |||
426 | 426 | ||
427 | static struct platform_driver omap_wdt_driver = { | 427 | static struct platform_driver omap_wdt_driver = { |
428 | .probe = omap_wdt_probe, | 428 | .probe = omap_wdt_probe, |
429 | .remove = omap_wdt_remove, | 429 | .remove = __devexit_p(omap_wdt_remove), |
430 | .shutdown = omap_wdt_shutdown, | 430 | .shutdown = omap_wdt_shutdown, |
431 | .suspend = omap_wdt_suspend, | 431 | .suspend = omap_wdt_suspend, |
432 | .resume = omap_wdt_resume, | 432 | .resume = omap_wdt_resume, |
diff --git a/drivers/watchdog/orion5x_wdt.c b/drivers/watchdog/orion5x_wdt.c index e81441f103dd..2cde568e4fb0 100644 --- a/drivers/watchdog/orion5x_wdt.c +++ b/drivers/watchdog/orion5x_wdt.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/uaccess.h> | 22 | #include <linux/uaccess.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <mach/bridge-regs.h> | ||
25 | #include <plat/orion5x_wdt.h> | 26 | #include <plat/orion5x_wdt.h> |
26 | 27 | ||
27 | /* | 28 | /* |
@@ -42,7 +43,17 @@ static unsigned int wdt_tclk; | |||
42 | static unsigned long wdt_status; | 43 | static unsigned long wdt_status; |
43 | static spinlock_t wdt_lock; | 44 | static spinlock_t wdt_lock; |
44 | 45 | ||
45 | static void wdt_enable(void) | 46 | static void orion5x_wdt_ping(void) |
47 | { | ||
48 | spin_lock(&wdt_lock); | ||
49 | |||
50 | /* Reload watchdog duration */ | ||
51 | writel(wdt_tclk * heartbeat, WDT_VAL); | ||
52 | |||
53 | spin_unlock(&wdt_lock); | ||
54 | } | ||
55 | |||
56 | static void orion5x_wdt_enable(void) | ||
46 | { | 57 | { |
47 | u32 reg; | 58 | u32 reg; |
48 | 59 | ||
@@ -69,7 +80,7 @@ static void wdt_enable(void) | |||
69 | spin_unlock(&wdt_lock); | 80 | spin_unlock(&wdt_lock); |
70 | } | 81 | } |
71 | 82 | ||
72 | static void wdt_disable(void) | 83 | static void orion5x_wdt_disable(void) |
73 | { | 84 | { |
74 | u32 reg; | 85 | u32 reg; |
75 | 86 | ||
@@ -101,7 +112,7 @@ static int orion5x_wdt_open(struct inode *inode, struct file *file) | |||
101 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) | 112 | if (test_and_set_bit(WDT_IN_USE, &wdt_status)) |
102 | return -EBUSY; | 113 | return -EBUSY; |
103 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); | 114 | clear_bit(WDT_OK_TO_CLOSE, &wdt_status); |
104 | wdt_enable(); | 115 | orion5x_wdt_enable(); |
105 | return nonseekable_open(inode, file); | 116 | return nonseekable_open(inode, file); |
106 | } | 117 | } |
107 | 118 | ||
@@ -122,18 +133,28 @@ static ssize_t orion5x_wdt_write(struct file *file, const char *data, | |||
122 | set_bit(WDT_OK_TO_CLOSE, &wdt_status); | 133 | set_bit(WDT_OK_TO_CLOSE, &wdt_status); |
123 | } | 134 | } |
124 | } | 135 | } |
125 | wdt_enable(); | 136 | orion5x_wdt_ping(); |
126 | } | 137 | } |
127 | return len; | 138 | return len; |
128 | } | 139 | } |
129 | 140 | ||
130 | static struct watchdog_info ident = { | 141 | static int orion5x_wdt_settimeout(int new_time) |
142 | { | ||
143 | if ((new_time <= 0) || (new_time > wdt_max_duration)) | ||
144 | return -EINVAL; | ||
145 | |||
146 | /* Set new watchdog time to be used when | ||
147 | * orion5x_wdt_enable() or orion5x_wdt_ping() is called. */ | ||
148 | heartbeat = new_time; | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static const struct watchdog_info ident = { | ||
131 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | | 153 | .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | |
132 | WDIOF_KEEPALIVEPING, | 154 | WDIOF_KEEPALIVEPING, |
133 | .identity = "Orion5x Watchdog", | 155 | .identity = "Orion5x Watchdog", |
134 | }; | 156 | }; |
135 | 157 | ||
136 | |||
137 | static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd, | 158 | static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd, |
138 | unsigned long arg) | 159 | unsigned long arg) |
139 | { | 160 | { |
@@ -152,7 +173,7 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
152 | break; | 173 | break; |
153 | 174 | ||
154 | case WDIOC_KEEPALIVE: | 175 | case WDIOC_KEEPALIVE: |
155 | wdt_enable(); | 176 | orion5x_wdt_ping(); |
156 | ret = 0; | 177 | ret = 0; |
157 | break; | 178 | break; |
158 | 179 | ||
@@ -161,12 +182,11 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
161 | if (ret) | 182 | if (ret) |
162 | break; | 183 | break; |
163 | 184 | ||
164 | if (time <= 0 || time > wdt_max_duration) { | 185 | if (orion5x_wdt_settimeout(time)) { |
165 | ret = -EINVAL; | 186 | ret = -EINVAL; |
166 | break; | 187 | break; |
167 | } | 188 | } |
168 | heartbeat = time; | 189 | orion5x_wdt_ping(); |
169 | wdt_enable(); | ||
170 | /* Fall through */ | 190 | /* Fall through */ |
171 | 191 | ||
172 | case WDIOC_GETTIMEOUT: | 192 | case WDIOC_GETTIMEOUT: |
@@ -187,7 +207,7 @@ static long orion5x_wdt_ioctl(struct file *file, unsigned int cmd, | |||
187 | static int orion5x_wdt_release(struct inode *inode, struct file *file) | 207 | static int orion5x_wdt_release(struct inode *inode, struct file *file) |
188 | { | 208 | { |
189 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) | 209 | if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) |
190 | wdt_disable(); | 210 | orion5x_wdt_disable(); |
191 | else | 211 | else |
192 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " | 212 | printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " |
193 | "timer will not stop\n"); | 213 | "timer will not stop\n"); |
@@ -230,7 +250,7 @@ static int __devinit orion5x_wdt_probe(struct platform_device *pdev) | |||
230 | orion5x_wdt_miscdev.parent = &pdev->dev; | 250 | orion5x_wdt_miscdev.parent = &pdev->dev; |
231 | 251 | ||
232 | wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk; | 252 | wdt_max_duration = WDT_MAX_CYCLE_COUNT / wdt_tclk; |
233 | if (heartbeat <= 0 || heartbeat > wdt_max_duration) | 253 | if (orion5x_wdt_settimeout(heartbeat)) |
234 | heartbeat = wdt_max_duration; | 254 | heartbeat = wdt_max_duration; |
235 | 255 | ||
236 | ret = misc_register(&orion5x_wdt_miscdev); | 256 | ret = misc_register(&orion5x_wdt_miscdev); |
@@ -247,7 +267,7 @@ static int __devexit orion5x_wdt_remove(struct platform_device *pdev) | |||
247 | int ret; | 267 | int ret; |
248 | 268 | ||
249 | if (test_bit(WDT_IN_USE, &wdt_status)) { | 269 | if (test_bit(WDT_IN_USE, &wdt_status)) { |
250 | wdt_disable(); | 270 | orion5x_wdt_disable(); |
251 | clear_bit(WDT_IN_USE, &wdt_status); | 271 | clear_bit(WDT_IN_USE, &wdt_status); |
252 | } | 272 | } |
253 | 273 | ||
@@ -258,9 +278,16 @@ static int __devexit orion5x_wdt_remove(struct platform_device *pdev) | |||
258 | return ret; | 278 | return ret; |
259 | } | 279 | } |
260 | 280 | ||
281 | static void orion5x_wdt_shutdown(struct platform_device *pdev) | ||
282 | { | ||
283 | if (test_bit(WDT_IN_USE, &wdt_status)) | ||
284 | orion5x_wdt_disable(); | ||
285 | } | ||
286 | |||
261 | static struct platform_driver orion5x_wdt_driver = { | 287 | static struct platform_driver orion5x_wdt_driver = { |
262 | .probe = orion5x_wdt_probe, | 288 | .probe = orion5x_wdt_probe, |
263 | .remove = __devexit_p(orion5x_wdt_remove), | 289 | .remove = __devexit_p(orion5x_wdt_remove), |
290 | .shutdown = orion5x_wdt_shutdown, | ||
264 | .driver = { | 291 | .driver = { |
265 | .owner = THIS_MODULE, | 292 | .owner = THIS_MODULE, |
266 | .name = "orion5x_wdt", | 293 | .name = "orion5x_wdt", |
@@ -285,10 +312,11 @@ MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>"); | |||
285 | MODULE_DESCRIPTION("Orion5x Processor Watchdog"); | 312 | MODULE_DESCRIPTION("Orion5x Processor Watchdog"); |
286 | 313 | ||
287 | module_param(heartbeat, int, 0); | 314 | module_param(heartbeat, int, 0); |
288 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds"); | 315 | MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds"); |
289 | 316 | ||
290 | module_param(nowayout, int, 0); | 317 | module_param(nowayout, int, 0); |
291 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | 318 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
319 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
292 | 320 | ||
293 | MODULE_LICENSE("GPL"); | 321 | MODULE_LICENSE("GPL"); |
294 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 322 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c index 5f54c01c1568..bdfd584ad853 100644 --- a/drivers/xen/cpu_hotplug.c +++ b/drivers/xen/cpu_hotplug.c | |||
@@ -21,29 +21,41 @@ static void disable_hotplug_cpu(int cpu) | |||
21 | set_cpu_present(cpu, false); | 21 | set_cpu_present(cpu, false); |
22 | } | 22 | } |
23 | 23 | ||
24 | static void vcpu_hotplug(unsigned int cpu) | 24 | static int vcpu_online(unsigned int cpu) |
25 | { | 25 | { |
26 | int err; | 26 | int err; |
27 | char dir[32], state[32]; | 27 | char dir[32], state[32]; |
28 | 28 | ||
29 | if (!cpu_possible(cpu)) | ||
30 | return; | ||
31 | |||
32 | sprintf(dir, "cpu/%u", cpu); | 29 | sprintf(dir, "cpu/%u", cpu); |
33 | err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state); | 30 | err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state); |
34 | if (err != 1) { | 31 | if (err != 1) { |
35 | printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); | 32 | printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); |
36 | return; | 33 | return err; |
37 | } | 34 | } |
38 | 35 | ||
39 | if (strcmp(state, "online") == 0) { | 36 | if (strcmp(state, "online") == 0) |
37 | return 1; | ||
38 | else if (strcmp(state, "offline") == 0) | ||
39 | return 0; | ||
40 | |||
41 | printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n", state, cpu); | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | static void vcpu_hotplug(unsigned int cpu) | ||
45 | { | ||
46 | if (!cpu_possible(cpu)) | ||
47 | return; | ||
48 | |||
49 | switch (vcpu_online(cpu)) { | ||
50 | case 1: | ||
40 | enable_hotplug_cpu(cpu); | 51 | enable_hotplug_cpu(cpu); |
41 | } else if (strcmp(state, "offline") == 0) { | 52 | break; |
53 | case 0: | ||
42 | (void)cpu_down(cpu); | 54 | (void)cpu_down(cpu); |
43 | disable_hotplug_cpu(cpu); | 55 | disable_hotplug_cpu(cpu); |
44 | } else { | 56 | break; |
45 | printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n", | 57 | default: |
46 | state, cpu); | 58 | break; |
47 | } | 59 | } |
48 | } | 60 | } |
49 | 61 | ||
@@ -64,12 +76,20 @@ static void handle_vcpu_hotplug_event(struct xenbus_watch *watch, | |||
64 | static int setup_cpu_watcher(struct notifier_block *notifier, | 76 | static int setup_cpu_watcher(struct notifier_block *notifier, |
65 | unsigned long event, void *data) | 77 | unsigned long event, void *data) |
66 | { | 78 | { |
79 | int cpu; | ||
67 | static struct xenbus_watch cpu_watch = { | 80 | static struct xenbus_watch cpu_watch = { |
68 | .node = "cpu", | 81 | .node = "cpu", |
69 | .callback = handle_vcpu_hotplug_event}; | 82 | .callback = handle_vcpu_hotplug_event}; |
70 | 83 | ||
71 | (void)register_xenbus_watch(&cpu_watch); | 84 | (void)register_xenbus_watch(&cpu_watch); |
72 | 85 | ||
86 | for_each_possible_cpu(cpu) { | ||
87 | if (vcpu_online(cpu) == 0) { | ||
88 | (void)cpu_down(cpu); | ||
89 | cpu_clear(cpu, cpu_present_map); | ||
90 | } | ||
91 | } | ||
92 | |||
73 | return NOTIFY_DONE; | 93 | return NOTIFY_DONE; |
74 | } | 94 | } |
75 | 95 | ||
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 0d61db1e7b49..4b5b84837ee1 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -62,14 +62,15 @@ static int xen_suspend(void *data) | |||
62 | gnttab_resume(); | 62 | gnttab_resume(); |
63 | xen_mm_unpin_all(); | 63 | xen_mm_unpin_all(); |
64 | 64 | ||
65 | sysdev_resume(); | ||
66 | |||
67 | if (!*cancelled) { | 65 | if (!*cancelled) { |
68 | xen_irq_resume(); | 66 | xen_irq_resume(); |
69 | xen_console_resume(); | 67 | xen_console_resume(); |
70 | xen_timer_resume(); | 68 | xen_timer_resume(); |
71 | } | 69 | } |
72 | 70 | ||
71 | sysdev_resume(); | ||
72 | device_power_up(PMSG_RESUME); | ||
73 | |||
73 | return 0; | 74 | return 0; |
74 | } | 75 | } |
75 | 76 | ||