diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-04-21 04:12:16 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-04-21 04:12:16 -0400 |
commit | 4db25d496c09fdf094d52d11a90ae51f9ee473c6 (patch) | |
tree | 77ab8003db1d6ccbcf3a9acafad26002fba37b63 /drivers | |
parent | b8c193f88ebd8705b3e916532539031cd9fc0b4c (diff) | |
parent | 8c31813f31cd4403b46802866949a95a6e8fa584 (diff) |
Merge branch 'sh/stable-updates' into sh/for-2.6.30
Diffstat (limited to 'drivers')
150 files changed, 2507 insertions, 1306 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 065507c46644..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"); |
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/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..d230ff4b3eec 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1142,6 +1142,9 @@ int device_for_each_child(struct device *parent, void *data, | |||
1142 | struct device *child; | 1142 | struct device *child; |
1143 | int error = 0; | 1143 | int error = 0; |
1144 | 1144 | ||
1145 | if (!parent->p) | ||
1146 | return 0; | ||
1147 | |||
1145 | klist_iter_init(&parent->p->klist_children, &i); | 1148 | klist_iter_init(&parent->p->klist_children, &i); |
1146 | while ((child = next_device(&i)) && !error) | 1149 | while ((child = next_device(&i)) && !error) |
1147 | error = fn(child, data); | 1150 | error = fn(child, data); |
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/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/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/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 d44065d2e662..935a1835de2d 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -1549,7 +1549,6 @@ int input_register_handle(struct input_handle *handle) | |||
1549 | return error; | 1549 | return error; |
1550 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | 1550 | list_add_tail_rcu(&handle->d_node, &dev->h_list); |
1551 | mutex_unlock(&dev->mutex); | 1551 | mutex_unlock(&dev->mutex); |
1552 | synchronize_rcu(); | ||
1553 | 1552 | ||
1554 | /* | 1553 | /* |
1555 | * 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 f999dc60c3b8..444dec07e5d8 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -880,7 +880,7 @@ static unsigned int atkbd_hp_zv6100_forced_release_keys[] = { | |||
880 | }; | 880 | }; |
881 | 881 | ||
882 | /* | 882 | /* |
883 | * Samsung NC10 with Fn+F? key release not working | 883 | * Samsung NC10,NC20 with Fn+F? key release not working |
884 | */ | 884 | */ |
885 | static unsigned int atkbd_samsung_forced_release_keys[] = { | 885 | static unsigned int atkbd_samsung_forced_release_keys[] = { |
886 | 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U | 886 | 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U |
@@ -1534,6 +1534,24 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1534 | .driver_data = atkbd_samsung_forced_release_keys, | 1534 | .driver_data = atkbd_samsung_forced_release_keys, |
1535 | }, | 1535 | }, |
1536 | { | 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 | { | ||
1537 | .ident = "Fujitsu Amilo PA 1510", | 1555 | .ident = "Fujitsu Amilo PA 1510", |
1538 | .matches = { | 1556 | .matches = { |
1539 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1557 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index e94b7d735aca..d427f322e207 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c | |||
@@ -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/misc/Kconfig b/drivers/input/misc/Kconfig index 203abac1e23e..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 |
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index f63995f854ff..3941f97cfa60 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c | |||
@@ -108,7 +108,6 @@ 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 | if (!no_pci_devices()) | 113 | if (!no_pci_devices()) |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 83ed2d56b924..fb8a3cd3ffd0 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -377,6 +377,24 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
377 | { } | 377 | { } |
378 | }; | 378 | }; |
379 | 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 | |||
380 | #ifdef CONFIG_PNP | 398 | #ifdef CONFIG_PNP |
381 | static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | 399 | static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { |
382 | { | 400 | { |
@@ -386,6 +404,13 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { | |||
386 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | 404 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), |
387 | }, | 405 | }, |
388 | }, | 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 | }, | ||
389 | { } | 414 | { } |
390 | }; | 415 | }; |
391 | #endif | 416 | #endif |
@@ -698,6 +723,9 @@ static int __init i8042_platform_init(void) | |||
698 | #endif | 723 | #endif |
699 | 724 | ||
700 | #ifdef CONFIG_X86 | 725 | #ifdef CONFIG_X86 |
726 | if (dmi_check_system(i8042_dmi_reset_table)) | ||
727 | i8042_reset = 1; | ||
728 | |||
701 | if (dmi_check_system(i8042_dmi_noloop_table)) | 729 | if (dmi_check_system(i8042_dmi_noloop_table)) |
702 | i8042_noloop = 1; | 730 | i8042_noloop = 1; |
703 | 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/ad7877.c b/drivers/input/touchscreen/ad7877.c index e4728a28f492..ecaeb7e8e75e 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -736,8 +736,8 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
736 | 736 | ||
737 | /* Request AD7877 /DAV GPIO interrupt */ | 737 | /* Request AD7877 /DAV GPIO interrupt */ |
738 | 738 | ||
739 | err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING | | 739 | err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING, |
740 | IRQF_SAMPLE_RANDOM, spi->dev.driver->name, ts); | 740 | spi->dev.driver->name, ts); |
741 | if (err) { | 741 | if (err) { |
742 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 742 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
743 | goto err_free_mem; | 743 | goto err_free_mem; |
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index ea4c61d68683..5d8a70398807 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -448,8 +448,7 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) | |||
448 | ad7879_setup(ts); | 448 | ad7879_setup(ts); |
449 | 449 | ||
450 | err = request_irq(bus->irq, ad7879_irq, | 450 | err = request_irq(bus->irq, ad7879_irq, |
451 | IRQF_TRIGGER_FALLING | IRQF_SAMPLE_RANDOM, | 451 | IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts); |
452 | bus->dev.driver->name, ts); | ||
453 | 452 | ||
454 | if (err) { | 453 | if (err) { |
455 | dev_err(&bus->dev, "irq %d busy?\n", bus->irq); | 454 | dev_err(&bus->dev, "irq %d busy?\n", bus->irq); |
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 dfa6a84ab50a..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 | ||
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index cec480bffe38..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"); |
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/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/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/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/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/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..ef12931d302a 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,7 @@ 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; | 3837 | bool cleaned = false; |
3838 | unsigned int total_tx_bytes=0, total_tx_packets=0; | 3838 | unsigned int total_tx_bytes=0, total_tx_packets=0; |
3839 | 3839 | ||
3840 | i = tx_ring->next_to_clean; | 3840 | i = tx_ring->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..1693ed116b16 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -621,7 +621,7 @@ 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; | 624 | bool cleaned = false; |
625 | unsigned int total_tx_bytes = 0, total_tx_packets = 0; | 625 | unsigned int total_tx_bytes = 0, total_tx_packets = 0; |
626 | 626 | ||
627 | i = tx_ring->next_to_clean; | 627 | i = tx_ring->next_to_clean; |
@@ -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_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..febde45cf9fa 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, |
@@ -2992,9 +2996,6 @@ try_msi: | |||
2992 | } | 2996 | } |
2993 | 2997 | ||
2994 | out: | 2998 | 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; | 2999 | return err; |
2999 | } | 3000 | } |
3000 | 3001 | ||
@@ -3611,9 +3612,9 @@ static int ixgbe_resume(struct pci_dev *pdev) | |||
3611 | 3612 | ||
3612 | return 0; | 3613 | return 0; |
3613 | } | 3614 | } |
3614 | |||
3615 | #endif /* CONFIG_PM */ | 3615 | #endif /* CONFIG_PM */ |
3616 | static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) | 3616 | |
3617 | static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) | ||
3617 | { | 3618 | { |
3618 | struct net_device *netdev = pci_get_drvdata(pdev); | 3619 | struct net_device *netdev = pci_get_drvdata(pdev); |
3619 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 3620 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
@@ -3672,18 +3673,46 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3672 | pci_enable_wake(pdev, PCI_D3cold, 0); | 3673 | pci_enable_wake(pdev, PCI_D3cold, 0); |
3673 | } | 3674 | } |
3674 | 3675 | ||
3676 | *enable_wake = !!wufc; | ||
3677 | |||
3675 | ixgbe_release_hw_control(adapter); | 3678 | ixgbe_release_hw_control(adapter); |
3676 | 3679 | ||
3677 | pci_disable_device(pdev); | 3680 | pci_disable_device(pdev); |
3678 | 3681 | ||
3679 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 3682 | return 0; |
3683 | } | ||
3684 | |||
3685 | #ifdef CONFIG_PM | ||
3686 | static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) | ||
3687 | { | ||
3688 | int retval; | ||
3689 | bool wake; | ||
3690 | |||
3691 | retval = __ixgbe_shutdown(pdev, &wake); | ||
3692 | if (retval) | ||
3693 | return retval; | ||
3694 | |||
3695 | if (wake) { | ||
3696 | pci_prepare_to_sleep(pdev); | ||
3697 | } else { | ||
3698 | pci_wake_from_d3(pdev, false); | ||
3699 | pci_set_power_state(pdev, PCI_D3hot); | ||
3700 | } | ||
3680 | 3701 | ||
3681 | return 0; | 3702 | return 0; |
3682 | } | 3703 | } |
3704 | #endif /* CONFIG_PM */ | ||
3683 | 3705 | ||
3684 | static void ixgbe_shutdown(struct pci_dev *pdev) | 3706 | static void ixgbe_shutdown(struct pci_dev *pdev) |
3685 | { | 3707 | { |
3686 | ixgbe_suspend(pdev, PMSG_SUSPEND); | 3708 | bool wake; |
3709 | |||
3710 | __ixgbe_shutdown(pdev, &wake); | ||
3711 | |||
3712 | if (system_state == SYSTEM_POWER_OFF) { | ||
3713 | pci_wake_from_d3(pdev, wake); | ||
3714 | pci_set_power_state(pdev, PCI_D3hot); | ||
3715 | } | ||
3687 | } | 3716 | } |
3688 | 3717 | ||
3689 | /** | 3718 | /** |
@@ -4342,7 +4371,7 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
4342 | int count = 0; | 4371 | int count = 0; |
4343 | unsigned int f; | 4372 | unsigned int f; |
4344 | 4373 | ||
4345 | r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping; | 4374 | r_idx = skb->queue_mapping; |
4346 | tx_ring = &adapter->tx_ring[r_idx]; | 4375 | tx_ring = &adapter->tx_ring[r_idx]; |
4347 | 4376 | ||
4348 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { | 4377 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { |
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..46073de290cf 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c | |||
@@ -1100,6 +1100,18 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
1100 | return phy_mii_ioctl(phydev, if_mii(rq), cmd); | 1100 | return phy_mii_ioctl(phydev, if_mii(rq), cmd); |
1101 | } | 1101 | } |
1102 | 1102 | ||
1103 | static const struct net_device_ops macb_netdev_ops = { | ||
1104 | .ndo_open = macb_open, | ||
1105 | .ndo_stop = macb_close, | ||
1106 | .ndo_start_xmit = macb_start_xmit, | ||
1107 | .ndo_set_multicast_list = macb_set_rx_mode, | ||
1108 | .ndo_get_stats = macb_get_stats, | ||
1109 | .ndo_do_ioctl = macb_ioctl, | ||
1110 | .ndo_validate_addr = eth_validate_addr, | ||
1111 | .ndo_change_mtu = eth_change_mtu, | ||
1112 | .ndo_set_mac_address = eth_mac_addr, | ||
1113 | }; | ||
1114 | |||
1103 | static int __init macb_probe(struct platform_device *pdev) | 1115 | static int __init macb_probe(struct platform_device *pdev) |
1104 | { | 1116 | { |
1105 | struct eth_platform_data *pdata; | 1117 | struct eth_platform_data *pdata; |
@@ -1175,12 +1187,7 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1175 | goto err_out_iounmap; | 1187 | goto err_out_iounmap; |
1176 | } | 1188 | } |
1177 | 1189 | ||
1178 | dev->open = macb_open; | 1190 | 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); | 1191 | netif_napi_add(dev, &bp->napi, macb_poll, 64); |
1185 | dev->ethtool_ops = &macb_ethtool_ops; | 1192 | dev->ethtool_ops = &macb_ethtool_ops; |
1186 | 1193 | ||
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/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/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/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..7a837c465960 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -12443,8 +12443,13 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) | |||
12443 | /* Next, try NVRAM. */ | 12443 | /* Next, try NVRAM. */ |
12444 | if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) && | 12444 | if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) && |
12445 | !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) { | 12445 | !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) { |
12446 | memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2); | 12446 | dev->dev_addr[0] = ((hi >> 16) & 0xff); |
12447 | memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo)); | 12447 | dev->dev_addr[1] = ((hi >> 24) & 0xff); |
12448 | dev->dev_addr[2] = ((lo >> 0) & 0xff); | ||
12449 | dev->dev_addr[3] = ((lo >> 8) & 0xff); | ||
12450 | dev->dev_addr[4] = ((lo >> 16) & 0xff); | ||
12451 | dev->dev_addr[5] = ((lo >> 24) & 0xff); | ||
12452 | |||
12448 | } | 12453 | } |
12449 | /* Finally just fetch it out of the MAC control regs. */ | 12454 | /* Finally just fetch it out of the MAC control regs. */ |
12450 | else { | 12455 | else { |
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..16716aef184c 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -518,7 +518,7 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, | |||
518 | int err; | 518 | int err; |
519 | 519 | ||
520 | /* Under a page? Don't bother with paged skb. */ | 520 | /* Under a page? Don't bother with paged skb. */ |
521 | if (prepad + len < PAGE_SIZE) | 521 | if (prepad + len < PAGE_SIZE || !linear) |
522 | linear = len; | 522 | linear = len; |
523 | 523 | ||
524 | skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, | 524 | skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock, |
@@ -565,7 +565,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, | |||
565 | 565 | ||
566 | if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { | 566 | if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { |
567 | align = NET_IP_ALIGN; | 567 | align = NET_IP_ALIGN; |
568 | if (unlikely(len < ETH_HLEN)) | 568 | if (unlikely(len < ETH_HLEN || |
569 | (gso.hdr_len && gso.hdr_len < ETH_HLEN))) | ||
569 | return -EINVAL; | 570 | return -EINVAL; |
570 | } | 571 | } |
571 | 572 | ||
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/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/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/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/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/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index c1688c71f052..c76feea5fe25 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 | ||
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/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..f47c0ce2849a 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c | |||
@@ -268,21 +268,6 @@ int go7007_register_encoder(struct go7007 *go) | |||
268 | init_i2c_module(&go->i2c_adapter, | 268 | init_i2c_module(&go->i2c_adapter, |
269 | go->board_info->i2c_devs[i].id, | 269 | go->board_info->i2c_devs[i].id, |
270 | go->board_info->i2c_devs[i].addr); | 270 | 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) | 271 | if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) |
287 | i2c_clients_command(&go->i2c_adapter, | 272 | i2c_clients_command(&go->i2c_adapter, |
288 | DECODER_SET_CHANNEL, &go->channel_number); | 273 | DECODER_SET_CHANNEL, &go->channel_number); |
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c index 58fddb122372..0a7eeef7c008 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; |
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-wdm.c b/drivers/usb/class/cdc-wdm.c index 3771d6e6d0cc..34e6108e1d42 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -652,7 +652,7 @@ next_desc: | |||
652 | 652 | ||
653 | iface = &intf->altsetting[0]; | 653 | iface = &intf->altsetting[0]; |
654 | ep = &iface->endpoint[0].desc; | 654 | ep = &iface->endpoint[0].desc; |
655 | if (!usb_endpoint_is_int_in(ep)) { | 655 | if (!ep || !usb_endpoint_is_int_in(ep)) { |
656 | rv = -EINVAL; | 656 | rv = -EINVAL; |
657 | goto err; | 657 | goto err; |
658 | } | 658 | } |
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/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/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..0112353ec97d 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -2170,26 +2170,22 @@ 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 | ||
@@ -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/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/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/option.c b/drivers/usb/serial/option.c index d560c0b54e6e..47bd070f24b7 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 | }; |
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/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..96db479d1165 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 |
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); |