summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/atm/he.c9
-rw-r--r--drivers/block/cciss.c10
-rw-r--r--drivers/block/floppy.c12
-rw-r--r--drivers/char/drm/radeon_state.c9
-rw-r--r--drivers/char/hvc_console.c1
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c1
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c9
-rw-r--r--drivers/char/synclink_gt.c14
-rw-r--r--drivers/char/watchdog/sbc8360.c4
-rw-r--r--drivers/ide/ide-proc.c2
-rw-r--r--drivers/ide/pci/aec62xx.c12
-rw-r--r--drivers/ide/pci/alim15x3.c2
-rw-r--r--drivers/ide/pci/serverworks.c10
-rw-r--r--drivers/ide/pci/sgiioc4.c60
-rw-r--r--drivers/ide/pci/siimage.c6
-rw-r--r--drivers/ide/pci/sis5513.c2
-rw-r--r--drivers/ide/pci/via82cxxx.c3
-rw-r--r--drivers/infiniband/core/cma.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_allocator.c15
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c1
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c14
-rw-r--r--drivers/macintosh/via-pmu-backlight.c99
-rw-r--r--drivers/macintosh/via-pmu.c12
-rw-r--r--drivers/md/raid1.c57
-rw-r--r--drivers/media/Kconfig2
-rw-r--r--drivers/media/common/saa7146_video.c2
-rw-r--r--drivers/media/dvb/b2c2/Kconfig1
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig1
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig1
-rw-r--r--drivers/media/dvb/frontends/Kconfig60
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/pluto2/Kconfig1
-rw-r--r--drivers/media/dvb/ttpci/Kconfig5
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig3
-rw-r--r--drivers/media/video/Kconfig8
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c1
-rw-r--r--drivers/media/video/cx88/Kconfig1
-rw-r--r--drivers/media/video/saa7134/Kconfig1
-rw-r--r--drivers/media/video/tuner-types.c10
-rw-r--r--drivers/media/video/zoran.h2
-rw-r--r--drivers/media/video/zoran_driver.c22
-rw-r--r--drivers/mmc/imxmmc.c69
-rw-r--r--drivers/mmc/mmc.c55
-rw-r--r--drivers/mmc/mmc_block.c60
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/dm9000.c4
-rw-r--r--drivers/net/e100.c6
-rw-r--r--drivers/net/e1000/e1000_main.c8
-rw-r--r--drivers/net/mv643xx_eth.c2
-rw-r--r--drivers/net/sunlance.c27
-rw-r--r--drivers/net/wireless/strip.c6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c61
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c43
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h11
-rw-r--r--drivers/pci/quirks.c1
-rw-r--r--drivers/s390/block/dasd.c192
-rw-r--r--drivers/s390/block/dasd_genhd.c10
-rw-r--r--drivers/s390/cio/ccwgroup.c14
-rw-r--r--drivers/s390/cio/chsc.c10
-rw-r--r--drivers/s390/cio/device.c19
-rw-r--r--drivers/s390/cio/device_fsm.c20
-rw-r--r--drivers/s390/cio/device_pgid.c27
-rw-r--r--drivers/s390/net/Kconfig9
-rw-r--r--drivers/s390/net/Makefile1
-rw-r--r--drivers/s390/net/ctcmain.c3
-rw-r--r--drivers/s390/net/iucv.c4
-rw-r--r--drivers/s390/net/lcs.c13
-rw-r--r--drivers/s390/net/netiucv.c80
-rw-r--r--drivers/s390/net/qeth.h73
-rw-r--r--drivers/s390/net/qeth_eddp.c5
-rw-r--r--drivers/s390/net/qeth_main.c517
-rw-r--r--drivers/s390/net/qeth_proc.c23
-rw-r--r--drivers/s390/net/qeth_sys.c64
-rw-r--r--drivers/s390/net/qeth_tso.h2
-rw-r--r--drivers/sbus/char/openprom.c13
-rw-r--r--drivers/scsi/ata_piix.c36
-rw-r--r--drivers/scsi/libata-core.c13
-rw-r--r--drivers/scsi/sata_mv.c3
-rw-r--r--drivers/scsi/sata_via.c1
-rw-r--r--drivers/scsi/scsi_error.c2
-rw-r--r--drivers/serial/8250_pci.c17
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/serial_core.c3
-rw-r--r--drivers/serial/sh-sci.c4
-rw-r--r--drivers/usb/gadget/ether.c45
-rw-r--r--drivers/usb/host/uhci-q.c4
-rw-r--r--drivers/usb/input/hid-core.c149
-rw-r--r--drivers/usb/input/usbtouchscreen.c2
-rw-r--r--drivers/usb/input/yealink.c12
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c2
-rw-r--r--drivers/usb/net/pegasus.h3
-rw-r--r--drivers/usb/net/rtl8150.c1
-rw-r--r--drivers/usb/serial/ftdi_sio.c1
-rw-r--r--drivers/usb/serial/ftdi_sio.h5
-rw-r--r--drivers/usb/serial/usb-serial.c4
-rw-r--r--drivers/usb/storage/unusual_devs.h24
-rw-r--r--drivers/video/aty/aty128fb.c18
-rw-r--r--drivers/video/aty/atyfb_base.c18
-rw-r--r--drivers/video/aty/radeon_backlight.c4
-rw-r--r--drivers/video/nvidia/nv_backlight.c18
-rw-r--r--drivers/video/riva/fbdev.c18
101 files changed, 1415 insertions, 937 deletions
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index d369130f423..dd96123a2b7 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -2282,6 +2282,8 @@ __enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid)
TPDRQ_MASK(he_readl(he_dev, TPDRQ_B_H)));
if (new_tail == he_dev->tpdrq_head) {
+ int slot;
+
hprintk("tpdrq full (cid 0x%x)\n", cid);
/*
* FIXME
@@ -2289,6 +2291,13 @@ __enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid)
* after service_tbrq, service the backlog
* for now, we just drop the pdu
*/
+ for (slot = 0; slot < TPD_MAXIOV; ++slot) {
+ if (tpd->iovec[slot].addr)
+ pci_unmap_single(he_dev->pci_dev,
+ tpd->iovec[slot].addr,
+ tpd->iovec[slot].len & TPD_LEN_MASK,
+ PCI_DMA_TODEVICE);
+ }
if (tpd->skb) {
if (tpd->vcc->pop)
tpd->vcc->pop(tpd->vcc, tpd->skb);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7b0eca703a6..2cd3391ff87 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -48,14 +48,14 @@
#include <linux/completion.h>
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.6.10)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,10)
+#define DRIVER_NAME "HP CISS Driver (v 3.6.10)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,10)
/* Embedded module documentation macros - see modules.h */
MODULE_AUTHOR("Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.10");
+MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.10");
MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
- " SA6i P600 P800 P400 P400i E200 E200i");
+ " SA6i P600 P800 P400 P400i E200 E200i E500");
MODULE_LICENSE("GPL");
#include "cciss_cmd.h"
@@ -82,6 +82,7 @@ static const struct pci_device_id cciss_pci_device_id[] = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3213},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3214},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215},
+ {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3233},
{0,}
};
@@ -110,6 +111,7 @@ static struct board_type products[] = {
{0x3213103C, "Smart Array E200i", &SA5_access},
{0x3214103C, "Smart Array E200i", &SA5_access},
{0x3215103C, "Smart Array E200i", &SA5_access},
+ {0x3233103C, "Smart Array E500", &SA5_access},
};
/* How long to wait (in milliseconds) for board to go into simple mode */
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5109fa37c66..ad1d7065a1b 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4177,6 +4177,11 @@ static int __init floppy_init(void)
int i, unit, drive;
int err, dr;
+#if defined(CONFIG_PPC_MERGE)
+ if (check_legacy_ioport(FDC1))
+ return -ENODEV;
+#endif
+
raw_cmd = NULL;
for (dr = 0; dr < N_DRIVE; dr++) {
@@ -4234,13 +4239,6 @@ static int __init floppy_init(void)
}
use_virtual_dma = can_use_virtual_dma & 1;
-#if defined(CONFIG_PPC_MERGE)
- if (check_legacy_ioport(FDC1)) {
- del_timer(&fd_timeout);
- err = -ENODEV;
- goto out_unreg_region;
- }
-#endif
fdc_state[0].address = FDC1;
if (fdc_state[0].address == -1) {
del_timer(&fd_timeout);
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 5bb2234a909..39a7f685e3f 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -175,6 +175,14 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
}
break;
+ case R200_EMIT_VAP_CTL:{
+ RING_LOCALS;
+ BEGIN_RING(2);
+ OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
+ ADVANCE_RING();
+ }
+ break;
+
case RADEON_EMIT_RB3D_COLORPITCH:
case RADEON_EMIT_RE_LINE_PATTERN:
case RADEON_EMIT_SE_LINE_WIDTH:
@@ -202,7 +210,6 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
case R200_EMIT_TCL_LIGHT_MODEL_CTL_0:
case R200_EMIT_TFACTOR_0:
case R200_EMIT_VTX_FMT_0:
- case R200_EMIT_VAP_CTL:
case R200_EMIT_MATRIX_SELECT_0:
case R200_EMIT_TEX_PROC_CTL_2:
case R200_EMIT_TCL_UCP_VERT_BLEND_CTL:
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index ca2f538e549..613d67f1c7f 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -668,6 +668,7 @@ int khvcd(void *unused)
do {
poll_mask = 0;
hvc_kicked = 0;
+ try_to_freeze();
wmb();
if (cpus_empty(cpus_in_xmon)) {
spin_lock(&hvc_structs_lock);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 0aa5d608fe6..843d34c8627 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -3428,6 +3428,7 @@ struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)
rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC);
if (rv) {
+ rv->user = NULL;
rv->done = free_recv_msg;
atomic_inc(&recv_msg_inuse_count);
}
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index f57eba0bf25..abca98beac1 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -402,10 +402,10 @@ static void handle_flags(struct smi_info *smi_info)
smi_info->curr_msg->data,
smi_info->curr_msg->data_size);
smi_info->si_state = SI_GETTING_EVENTS;
- } else if (smi_info->msg_flags & OEM_DATA_AVAIL) {
- if (smi_info->oem_data_avail_handler)
- if (smi_info->oem_data_avail_handler(smi_info))
- goto retry;
+ } else if (smi_info->msg_flags & OEM_DATA_AVAIL &&
+ smi_info->oem_data_avail_handler) {
+ if (smi_info->oem_data_avail_handler(smi_info))
+ goto retry;
} else {
smi_info->si_state = SI_NORMAL;
}
@@ -2481,6 +2481,7 @@ static __devinit int init_ipmi_si(void)
#ifdef CONFIG_PCI
pci_unregister_driver(&ipmi_pci_driver);
#endif
+ driver_unregister(&ipmi_driver);
printk("ipmi_si: Unable to find any System Interface(s)\n");
return -ENODEV;
} else {
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index b2dbbdb1bf8..2f07b085536 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -391,8 +391,8 @@ static MGSL_PARAMS default_params = {
#define DESC_LIST_SIZE 4096
#define MASK_PARITY BIT1
-#define MASK_FRAMING BIT2
-#define MASK_BREAK BIT3
+#define MASK_FRAMING BIT0
+#define MASK_BREAK BIT14
#define MASK_OVERRUN BIT4
#define GSR 0x00 /* global status */
@@ -1800,17 +1800,17 @@ static void rx_async(struct slgt_info *info)
stat = 0;
- if ((status = *(p+1) & (BIT9 + BIT8))) {
- if (status & BIT9)
+ if ((status = *(p+1) & (BIT1 + BIT0))) {
+ if (status & BIT1)
icount->parity++;
- else if (status & BIT8)
+ else if (status & BIT0)
icount->frame++;
/* discard char if tty control flags say so */
if (status & info->ignore_status_mask)
continue;
- if (status & BIT9)
+ if (status & BIT1)
stat = TTY_PARITY;
- else if (status & BIT8)
+ else if (status & BIT0)
stat = TTY_FRAME;
}
if (tty) {
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c
index 1035be5b501..41fc6f80c49 100644
--- a/drivers/char/watchdog/sbc8360.c
+++ b/drivers/char/watchdog/sbc8360.c
@@ -200,7 +200,7 @@ static int wd_margin = 0xB;
static int wd_multiplier = 2;
static int nowayout = WATCHDOG_NOWAYOUT;
-module_param(timeout, int, 27);
+module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout,
@@ -407,7 +407,7 @@ module_exit(sbc8360_exit);
MODULE_AUTHOR("Ian E. Morgan <imorgan@webcon.ca>");
MODULE_DESCRIPTION("SBC8360 watchdog driver");
MODULE_LICENSE("GPL");
-MODULE_VERSION("1.0");
+MODULE_VERSION("1.01");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
/* end of sbc8360.c */
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index c12f1b71e93..41b74b13a00 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -376,6 +376,8 @@ static int proc_ide_read_media
break;
case ide_floppy:media = "floppy\n";
break;
+ case ide_optical:media = "optical\n";
+ break;
default: media = "UNKNOWN\n";
break;
}
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index a7c725f8bf6..f286079d233 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -425,12 +425,12 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi
return d->init_setup(dev, d);
}
-static const struct pci_device_id aec62xx_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 },
- { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 },
- { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R), 2 },
- { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865), 3 },
- { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R), 4 },
+static struct pci_device_id aec62xx_pci_tbl[] = {
+ { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
+ { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
+ { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
+ { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl);
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 351dab2fcac..d419e4bb54f 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -730,7 +730,7 @@ static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif)
if(m5229_revision <= 0x20)
tmpbyte = (tmpbyte & (~0x02)) | 0x01;
- else if (m5229_revision == 0xc7)
+ else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
tmpbyte |= 0x03;
else
tmpbyte |= 0x01;
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index 03677bff0d7..f063d954236 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -649,11 +649,11 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device
}
static struct pci_device_id svwks_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 1},
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2},
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 3},
- { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 4},
+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+ { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, svwks_pci_tbl);
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index e125032bb40..d8a0d87df73 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -367,12 +367,13 @@ sgiioc4_INB(unsigned long port)
static void __devinit
ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
{
+ void __iomem *virt_dma_base;
int num_ports = sizeof (ioc4_dma_regs_t);
printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name,
dma_base, dma_base + num_ports - 1);
- if (!request_region(dma_base, num_ports, hwif->name)) {
+ if (!request_mem_region(dma_base, num_ports, hwif->name)) {
printk(KERN_ERR
"%s(%s) -- ERROR, Addresses 0x%p to 0x%p "
"ALREADY in use\n",
@@ -381,13 +382,21 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
goto dma_alloc_failure;
}
- hwif->dma_base = dma_base;
+ virt_dma_base = ioremap(dma_base, num_ports);
+ if (virt_dma_base == NULL) {
+ printk(KERN_ERR
+ "%s(%s) -- ERROR, Unable to map addresses 0x%lx to 0x%lx\n",
+ __FUNCTION__, hwif->name, dma_base, dma_base + num_ports - 1);
+ goto dma_remap_failure;
+ }
+ hwif->dma_base = (unsigned long) virt_dma_base;
+
hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
&hwif->dmatable_dma);
if (!hwif->dmatable_cpu)
- goto dma_alloc_failure;
+ goto dma_pci_alloc_failure;
hwif->sg_max_nents = IOC4_PRD_ENTRIES;
@@ -411,6 +420,12 @@ dma_base2alloc_failure:
printk(KERN_INFO
"Changing from DMA to PIO mode for Drive %s\n", hwif->name);
+dma_pci_alloc_failure:
+ iounmap(virt_dma_base);
+
+dma_remap_failure:
+ release_mem_region(dma_base, num_ports);
+
dma_alloc_failure:
/* Disable DMA because we couldnot allocate any DMA maps */
hwif->autodma = 0;
@@ -607,18 +622,15 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
hwif->ide_dma_timeout = &__ide_dma_timeout;
- /*
- * The IOC4 uses MMIO rather than Port IO.
- * It also needs special workarounds for INB.
- */
- default_hwif_mmiops(hwif);
hwif->INB = &sgiioc4_INB;
}
static int __devinit
sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
{
- unsigned long base, ctl, dma_base, irqport;
+ unsigned long cmd_base, dma_base, irqport;
+ unsigned long bar0, cmd_phys_base, ctl;
+ void __iomem *virt_base;
ide_hwif_t *hwif;
int h;
@@ -636,23 +648,32 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
}
/* Get the CmdBlk and CtrlBlk Base Registers */
- base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET;
- ctl = pci_resource_start(dev, 0) + IOC4_CTRL_OFFSET;
- irqport = pci_resource_start(dev, 0) + IOC4_INTR_OFFSET;
+ bar0 = pci_resource_start(dev, 0);
+ virt_base = ioremap(bar0, pci_resource_len(dev, 0));
+ if (virt_base == NULL) {
+ printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n",
+ d->name, bar0);
+ return -ENOMEM;
+ }
+ cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET;
+ ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET;
+ irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET;
dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
- if (!request_region(base, IOC4_CMD_CTL_BLK_SIZE, hwif->name)) {
+ cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
+ if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
+ hwif->name)) {
printk(KERN_ERR
- "%s : %s -- ERROR, Port Addresses "
+ "%s : %s -- ERROR, Addresses "
"0x%p to 0x%p ALREADY in use\n",
- __FUNCTION__, hwif->name, (void *) base,
- (void *) base + IOC4_CMD_CTL_BLK_SIZE);
+ __FUNCTION__, hwif->name, (void *) cmd_phys_base,
+ (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
return -ENOMEM;
}
- if (hwif->io_ports[IDE_DATA_OFFSET] != base) {
+ if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) {
/* Initialize the IO registers */
- sgiioc4_init_hwif_ports(&hwif->hw, base, ctl, irqport);
+ sgiioc4_init_hwif_ports(&hwif->hw, cmd_base, ctl, irqport);
memcpy(hwif->io_ports, hwif->hw.io_ports,
sizeof (hwif->io_ports));
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
@@ -665,6 +686,9 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
hwif->cds = (struct ide_pci_device_s *) d;
hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
+ /* The IOC4 uses MMIO rather than Port IO. */
+ default_hwif_mmiops(hwif);
+
/* Initializing chipset IRQ Registers */
hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4);
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 25ceb4a39ed..20b392948f3 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -1082,10 +1082,10 @@ static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_devi
}
static struct pci_device_id siimage_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), 0},
+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
#ifdef CONFIG_BLK_DEV_IDE_SATA
- { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112), 1},
- { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA), 2},
+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
#endif
{ 0, },
};
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 8a6c23ac8cc..f03196c5db3 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -86,6 +86,8 @@ static const struct {
u8 chipset_family;
u8 flags;
} SiSHostChipInfo[] = {
+ { "SiS968", PCI_DEVICE_ID_SI_968, ATA_133 },
+ { "SiS966", PCI_DEVICE_ID_SI_966, ATA_133 },
{ "SiS965", PCI_DEVICE_ID_SI_965, ATA_133 },
{ "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 },
{ "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 },
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index afdaee3c15c..9b7589e8e93 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -6,7 +6,7 @@
*
* vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
* vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
- * vt8235, vt8237
+ * vt8235, vt8237, vt8237a
*
* Copyright (c) 2000-2002 Vojtech Pavlik
*
@@ -81,6 +81,7 @@ static struct via_isa_bridge {
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+ { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
{ "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 },
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index d6f99d5720f..5d625a81193 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -49,7 +49,7 @@ MODULE_DESCRIPTION("Generic RDMA CM Agent");
MODULE_LICENSE("Dual BSD/GPL");
#define CMA_CM_RESPONSE_TIMEOUT 20
-#define CMA_MAX_CM_RETRIES 3
+#define CMA_MAX_CM_RETRIES 15
static void cma_add_one(struct ib_device *device);
static void cma_remove_one(struct ib_device *device);
diff --git a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c
index 25157f57a6d..f930e55b58f 100644
--- a/drivers/infiniband/hw/mthca/mthca_allocator.c
+++ b/drivers/infiniband/hw/mthca/mthca_allocator.c
@@ -41,9 +41,11 @@
/* Trivial bitmap-based allocator */
u32 mthca_alloc(struct mthca_alloc *alloc)
{
+ unsigned long flags;
u32 obj;
- spin_lock(&alloc->lock);
+ spin_lock_irqsave(&alloc->lock, flags);
+
obj = find_next_zero_bit(alloc->table, alloc->max, alloc->last);
if (obj >= alloc->max) {
alloc->top = (alloc->top + alloc->max) & alloc->mask;
@@ -56,19 +58,24 @@ u32 mthca_alloc(struct mthca_alloc *alloc)
} else
obj = -1;
- spin_unlock(&alloc->lock);
+ spin_unlock_irqrestore(&alloc->lock, flags);
return obj;
}
void mthca_free(struct mthca_alloc *alloc, u32 obj)
{
+ unsigned long flags;
+
obj &= alloc->max - 1;
- spin_lock(&alloc->lock);
+
+ spin_lock_irqsave(&alloc->lock, flags);
+
clear_bit(obj, alloc->table);
alloc->last = min(alloc->last, obj);
alloc->top = (alloc->top + alloc->max) & alloc->mask;
- spin_unlock(&alloc->lock);
+
+ spin_unlock_irqrestore(&alloc->lock, flags);
}
int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index b5e6a7be603..ec356ce7cdc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -326,6 +326,7 @@ ipoib_mcast_sendonly_join_complete(int status,
/* Clear the busy flag so we try again */
clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
+ mcast->query = NULL;
}
complete(&mcast->done);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 8257d5a2c8f..fd8344cdc0d 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -799,13 +799,6 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
}
-static void srp_reconnect_work(void *target_ptr)
-{
- struct srp_target_port *target = target_ptr;
-
- srp_reconnect_target(target);
-}
-
static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc)
{
struct srp_iu *iu;
@@ -858,7 +851,6 @@ static void srp_completion(struct ib_cq *cq, void *target_ptr)
{
struct srp_target_port *target = target_ptr;
struct ib_wc wc;
- unsigned long flags;
ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
while (ib_poll_cq(cq, 1, &wc) > 0) {
@@ -866,10 +858,6 @@ static void srp_completion(struct ib_cq *cq, void *target_ptr)
printk(KERN_ERR PFX "failed %s status %d\n",
wc.wr_id & SRP_OP_RECV ? "receive" : "send",
wc.status);
- spin_lock_irqsave(target->scsi_host->host_lock, flags);
- if (target->state == SRP_TARGET_LIVE)
- schedule_work(&target->work);
- spin_unlock_irqrestore(target->scsi_host->host_lock, flags);
break;
}
@@ -1705,8 +1693,6 @@ static ssize_t srp_create_target(struct class_device *class_dev,
target->scsi_host = target_host;
target->srp_host = host;
- INIT_WORK(&target->work, srp_reconnect_work, target);
-
INIT_LIST_HEAD(&target->free_reqs);
INIT_LIST_HEAD(&target->req_queue);
for (i = 0; i < SRP_SQ_SIZE; ++i) {
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index d3f8d75bcbb..a82f313d9dc 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -18,17 +18,48 @@
static struct backlight_properties pmu_backlight_data;
static spinlock_t pmu_backlight_lock;
static int sleeping;
+static u8 bl_curve[FB_BACKLIGHT_LEVELS];
-static int pmu_backlight_get_level_brightness(struct fb_info *info,
- int level)
+static void pmu_backlight_init_curve(u8 off, u8 min, u8 max)
+{
+ unsigned int i, flat, count, range = (max - min);
+
+ bl_curve[0] = off;
+
+ for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat)
+ bl_curve[flat] = min;
+
+ count = FB_BACKLIGHT_LEVELS * 15 / 16;
+ for (i = 0; i < count; ++i)
+ bl_curve[flat + i] = min + (range * (i + 1) / count);
+}
+
+static int pmu_backlight_curve_lookup(int value)
+{
+ int level = (FB_BACKLIGHT_LEVELS - 1);
+ int i, max = 0;
+
+ /* Look for biggest value */
+ for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
+ max = max((int)bl_curve[i], max);
+
+ /* Look for nearest value */
+ for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
+ int diff = abs(bl_curve[i] - value);
+ if (diff < max) {
+ max = diff;
+ level = i;
+ }
+ }
+ return level;
+}
+
+static int pmu_backlight_get_level_brightness(int level)
{
int pmulevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
- pmulevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL;
- mutex_unlock(&info->bl_mutex);
-
+ pmulevel = bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL;
if (pmulevel < 0)
pmulevel = 0;
else if (pmulevel > MAX_PMU_LEVEL)
@@ -39,7 +70,6 @@ static int pmu_backlight_get_level_brightness(struct fb_info *info,
static int pmu_backlight_update_status(struct backlight_device *bd)
{
- struct fb_info *info = class_get_devdata(&bd->class_dev);
struct adb_request req;
unsigned long flags;
int level = bd->props->brightness;
@@ -55,7 +85,7 @@ static int pmu_backlight_update_status(struct backlight_device *bd)
level = 0;
if (level > 0) {
- int pmulevel = pmu_backlight_get_level_brightness(info, level);
+ int pmulevel = pmu_backlight_get_level_brightness(level);
pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel);
pmu_wait_complete(&req);
@@ -88,35 +118,19 @@ static struct backlight_properties pmu_backlight_data = {
};
#ifdef CONFIG_PM
-static int pmu_backlight_sleep_call(struct pmu_sleep_notifier *self, int when)
+void pmu_backlight_set_sleep(int sleep)
{
unsigned long flags;
spin_lock_irqsave(&pmu_backlight_lock, flags);
-
- switch (when) {
- case PBOOK_SLEEP_REQUEST:
- sleeping = 1;
- break;
- case PBOOK_WAKE:
- sleeping = 0;
- break;
- }
-
+ sleeping = sleep;
spin_unlock_irqrestore(&pmu_backlight_lock, flags);
-
- return PBOOK_SLEEP_OK;
}
-
-static struct pmu_sleep_notifier pmu_backlight_sleep_notif = {
- .notifier_call = pmu_backlight_sleep_call,
-};
-#endif
+#endif /* CONFIG_PM */
void __init pmu_backlight_init()
{
struct backlight_device *bd;
- struct fb_info *info;
char name[10];
int level, autosave;
@@ -131,27 +145,14 @@ void __init pmu_backlight_init()
!machine_is_compatible("PowerBook1,1"))
return;
- /* Actually, this is a hack, but I don't know of a better way
- * to get the first framebuffer device.
- */
- info = registered_fb[0];
- if (!info) {
- printk("pmubl: No framebuffer found\n");
- goto error;
- }
-
- snprintf(name, sizeof(name), "pmubl%d", info->node);
+ snprintf(name, sizeof(name), "pmubl");
- bd = backlight_device_register(name, info, &pmu_backlight_data);
+ bd = backlight_device_register(name, NULL, &pmu_backlight_data);
if (IS_ERR(bd)) {
printk("pmubl: Backlight registration failed\n");
goto error;
}
-
- mutex_lock(&info->bl_mutex);
- info->bl_dev = bd;
- fb_bl_default_curve(info, 0x7F, 0x46, 0x0E);
- mutex_unlock(&info->bl_mutex);
+ pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
level = pmu_backlight_data.max_brightness;
@@ -161,28 +162,22 @@ void __init pmu_backlight_init()
pmu_request(&req, NULL, 2, 0xd9, 0);
pmu_wait_complete(&req);
- mutex_lock(&info->bl_mutex);
- level = pmac_backlight_curve_lookup(info,
+ level = pmu_backlight_curve_lookup(
(req.reply[0] >> 4) *
pmu_backlight_data.max_brightness / 15);
- mutex_unlock(&info->bl_mutex);
}
- up(&bd->sem);
+ down(&bd->sem);
bd->props->brightness = level;
bd->props->power = FB_BLANK_UNBLANK;
bd->props->update_status(bd);
- down(&bd->sem);
+ up(&bd->sem);
mutex_lock(&pmac_backlight_mutex);
if (!pmac_backlight)
pmac_backlight = bd;
mutex_unlock(&pmac_backlight_mutex);
-#ifdef CONFIG_PM
- pmu_register_sleep_notifier(&pmu_backlight_sleep_notif);
-#endif
-
printk("pmubl: Backlight initialized (%s)\n", name);
return;
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index ea386801e21..14610a63f58 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1995,6 +1995,8 @@ restore_via_state(void)
out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
}
+extern void pmu_backlight_set_sleep(int sleep);
+
static int
pmac_suspend_devices(void)
{
@@ -2032,6 +2034,11 @@ pmac_suspend_devices(void)
return -EBUSY;
}
+#ifdef CONFIG_PMAC_BACKLIGHT
+ /* Tell backlight code not to muck around with the chip anymore */
+ pmu_backlight_set_sleep(1);
+#endif
+
/* Call platform functions marked "on sleep" */
pmac_pfunc_i2c_suspend();
pmac_pfunc_base_suspend();
@@ -2090,6 +2097,11 @@ pmac_wakeup_devices(void)
{
mdelay(100);
+#ifdef CONFIG_PMAC_BACKLIGHT
+ /* Tell backlight code it can use the chip again */
+ pmu_backlight_set_sleep(0);
+#endif
+
/* Power back up system devices (including the PIC) */
device_power_up();
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 87bfe9e7d8c..3b4d69c0562 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -930,10 +930,13 @@ static void status(struct seq_file *seq, mddev_t *mddev)
seq_printf(seq, " [%d/%d] [", conf->raid_disks,
conf->working_disks);
- for (i = 0; i < conf->raid_disks; i++)
+ rcu_read_lock();
+ for (i = 0; i < conf->raid_disks; i++) {
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
seq_printf(seq, "%s",
- conf->mirrors[i].rdev &&
- test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
+ rdev && test_bit(In_sync, &rdev->flags) ? "U" : "_");
+ }
+ rcu_read_unlock();
seq_printf(seq, "]");
}
@@ -975,7 +978,6 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
static void print_conf(conf_t *conf)
{
int i;
- mirror_info_t *tmp;
printk("RAID1 conf printout:\n");
if (!conf) {
@@ -985,14 +987,17 @@ static void print_conf(conf_t *conf)
printk(" --- wd:%d rd:%d\n", conf->working_disks,
conf->raid_disks);
+ rcu_read_lock();
for (i = 0; i < conf->raid_disks; i++) {
char b[BDEVNAME_SIZE];
- tmp = conf->mirrors + i;
- if (tmp->rdev)
+ mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
+ if (rdev)
printk(" disk %d, wo:%d, o:%d, dev:%s\n",
- i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags),
- bdevname(tmp->rdev->bdev,b));
+ i, !test_bit(In_sync, &rdev->flags),
+ !test_bit(Faulty, &rdev->flags),
+ bdevname(rdev->bdev,b));
}
+ rcu_read_unlock();
}
static void close_sync(conf_t *conf)
@@ -1008,20 +1013,20 @@ static int raid1_spare_active(mddev_t *mddev)
{
int i;
conf_t *conf = mddev->private;
- mirror_info_t *tmp;
/*
* Find all failed disks within the RAID1 configuration
- * and mark them readable
+ * and mark them readable.
+ * Called under mddev lock, so rcu protection not needed.
*/
for (i = 0; i < conf->raid_disks; i++) {
- tmp = conf->mirrors + i;
- if (tmp->rdev
- && !test_bit(Faulty, &tmp->rdev->flags)
- && !test_bit(In_sync, &tmp->rdev->flags)) {
+ mdk_rdev_t *rdev = conf->mirrors[i].rdev;
+ if (rdev
+ && !test_bit(Faulty, &rdev->flags)
+ && !test_bit(In_sync, &rdev->flags)) {
conf->working_disks++;
mddev->degraded--;
- set_bit(In_sync, &tmp->rdev->flags);
+ set_bit(In_sync, &rdev->flags);
}
}
@@ -1237,7 +1242,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
/* ouch - failed to read all of that.
* Try some synchronous reads of other devices to get
* good data, much like with normal read errors. Only
- * read into the pages we already have so they we don't
+ * read into the pages we already have so we don't
* need to re-issue the read request.
* We don't need to freeze the array, because being in an
* active sync request, there is no normal IO, and
@@ -1257,6 +1262,10 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
s = PAGE_SIZE >> 9;
do {
if (r1_bio->bios[d]->bi_end_io == end_sync_read) {
+ /* No rcu protection needed here devices
+ * can only be removed when no resync is
+ * active, and resync is currently active
+ */
rdev = conf->mirrors[d].rdev;
if (sync_page_io(rdev->bdev,
sect + rdev->data_offset,
@@ -1463,6 +1472,11 @@ static void raid1d(mddev_t *mddev)
s = PAGE_SIZE >> 9;
do {
+ /* Note: no rcu protection needed here
+ * as this is synchronous in the raid1d thread
+ * which is the thread that might remove
+ * a device. If raid1d ever becomes multi-threaded....
+ */
rdev = conf->mirrors[d].rdev;
if (rdev &&
test_bit(In_sync, &rdev->flags) &&
@@ -1486,7 +1500,6 @@ static void raid1d(mddev_t *mddev)
d = conf->raid_disks;
d--;
rdev = conf->mirrors[d].rdev;
- atomic_add(s, &rdev->corrected_errors);
if (rdev &&
test_bit(In_sync, &rdev->flags)) {
if (sync_page_io(rdev->bdev,
@@ -1509,9 +1522,11 @@ static void raid1d(mddev_t *mddev)
s<<9, conf->tmppage, READ) == 0)
/* Well, this device is dead */
md_error(mddev, rdev);
- else
+ else {
+ atomic_add(s, &rdev->corrected_errors);
printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n",
mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b));
+ }
}
}
} else {
@@ -1787,19 +1802,17 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
for (i=0; i<conf->raid_disks; i++) {
bio = r1_bio->bios[i];
if (bio->bi_end_io == end_sync_read) {
- md_sync_acct(conf->mirrors[i].rdev->bdev, nr_sectors);
+ md_sync_acct(bio->bi_bdev, nr_sectors);
generic_make_request(bio);
}
}
} else {
atomic_set(&r1_bio->remaining, 1);
bio = r1_bio->bios[r1_bio->read_disk];
- md_sync_acct(conf->mirrors[r1_bio->read_disk].rdev->bdev,
- nr_sectors);
+ md_sync_acct(bio->bi_bdev, nr_sectors);
generic_make_request(bio);
}
-
return nr_sectors;
}
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index ef52e6da01e..ed4aa4e7912 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -53,7 +53,7 @@ config VIDEO_V4L1_COMPAT
If you are unsure as to whether this is required, answer Y.
config VIDEO_V4L2
- tristate
+ bool
default y
source "drivers/media/video/Kconfig"
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 8393d472d3b..7e0cedc557d 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1190,6 +1190,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
}
return err;
}
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
case VIDIOCGMBUF:
{
struct video_mbuf *mbuf = arg;
@@ -1218,6 +1219,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
mutex_unlock(&q->lock);
return 0;
}
+#endif
default:
return v4l_compat_translate_ioctl(inode,file,cmd,arg,
saa7146_video_do_ioctl);
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index d7f1fd5b7b0..49a06fc54c5 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -1,6 +1,7 @@
config DVB_B2C2_FLEXCOP
tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
depends on DVB_CORE && I2C
+ select DVB_PLL
select DVB_STV0299
select DVB_MT352
select DVB_MT312
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index f394002118f..7d0ee1ab290 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -1,6 +1,7 @@
config DVB_BT8XX
tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && I2C && VIDEO_BT848
+ select DVB_PLL
select DVB_MT352
select DVB_SP887X
select DVB_NXT6000
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 3bc6722a644..75824b77198 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -2,6 +2,7 @@ config DVB_USB
tristate "Support for various USB DVB devices"
depends on DVB_CORE && USB && I2C
select FW_LOADER
+ select DVB_PLL
help
By enabling this you will be able to choose the various supported
USB1.1 and USB2.0 DVB devices.
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 0ef361f0309..db978555b1e 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -6,43 +6,43 @@ comment "DVB-S (satellite) frontends"
config DVB_STV0299
tristate "ST STV0299 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_CX24110
tristate "Conexant CX24110 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_CX24123
tristate "Conexant CX24123 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA8083
tristate "Philips TDA8083 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_MT312
tristate "Zarlink VP310/MT312 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_VES1X93
tristate "VLSI VES1893 or VES1993 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_S5H1420
tristate "Samsung S5H1420 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-S tuner module. Say Y when you want to support this frontend.
@@ -51,7 +51,7 @@ comment "DVB-T (terrestrial) frontends"
config DVB_SP8870
tristate "Spase sp8870 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -63,7 +63,7 @@ config DVB_SP8870
config DVB_SP887X
tristate "Spase sp887x based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -75,25 +75,25 @@ config DVB_SP887X
config DVB_CX22700
tristate "Conexant CX22700 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_CX22702
tristate "Conexant cx22702 demodulator (OFDM)"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_L64781
tristate "LSI L64781"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
select FW_LOADER
help
A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -106,32 +106,32 @@ config DVB_TDA1004X
config DVB_NXT6000
tristate "NxtWave Communications NXT6000 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_MT352
tristate "Zarlink MT352 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_ZL10353
tristate "Zarlink ZL10353 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DIB3000MB
tristate "DiBcom 3000M-B"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
config DVB_DIB3000MC
tristate "DiBcom 3000P/M-C"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
@@ -141,19 +141,19 @@ comment "DVB-C (cable) frontends"
config DVB_VES1820
tristate "VLSI VES1820 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_TDA10021
tristate "Philips TDA10021 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_STV0297
tristate "ST STV0297 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
A DVB-C tuner module. Say Y when you want to support this frontend.
@@ -162,7 +162,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
select FW_LOADER
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -176,7 +176,7 @@ config DVB_NXT200X
config DVB_OR51211
tristate "Oren OR51211 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
select FW_LOADER
help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
@@ -188,7 +188,7 @@ config DVB_OR51211
config DVB_OR51132
tristate "Oren OR51132 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
select FW_LOADER
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -203,7 +203,7 @@ config DVB_OR51132
config DVB_BCM3510
tristate "Broadcom BCM3510"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
select FW_LOADER
help
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
@@ -211,7 +211,7 @@ config DVB_BCM3510
config DVB_LGDT330X
tristate "LG Electronics LGDT3302/LGDT3303 based"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
@@ -220,15 +220,19 @@ config DVB_LGDT330X
comment "Miscellaneous devices"
depends on DVB_CORE
+config DVB_PLL
+ tristate
+ depends on DVB_CORE && I2C
+
config DVB_LNBP21
tristate "LNBP21 SEC controller"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
An SEC control chip.
config DVB_ISL6421
tristate "ISL6421 SEC controller"
- depends on DVB_CORE
+ depends on DVB_CORE && I2C
help
An SEC control chip.
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 5222245c7f5..0e4880b6db1 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -4,7 +4,7 @@
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
-obj-$(CONFIG_DVB_CORE) += dvb-pll.o
+obj-$(CONFIG_DVB_PLL) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
obj-$(CONFIG_DVB_SP8870) += sp8870.o
obj-$(CONFIG_DVB_CX22700) += cx22700.o
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig
index 7d8e6e87bdb..9b84b1bdc31 100644
--- a/drivers/media/dvb/pluto2/Kconfig
+++ b/drivers/media/dvb/pluto2/Kconfig
@@ -2,6 +2,7 @@ config DVB_PLUTO2
tristate "Pluto2 cards"
depends on DVB_CORE && PCI && I2C
select I2C_ALGOBIT
+ select DVB_PLL
select DVB_TDA1004X
help
Support for PCI cards based on the Pluto2 FPGA like the Satelco
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 987881fa988..5fb097595cf 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -3,6 +3,7 @@ config DVB_AV7110
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select FW_LOADER
select VIDEO_SAA7146_VV
+ select DVB_PLL
select DVB_VES1820
select DVB_VES1X93
select DVB_STV0299
@@ -61,6 +62,7 @@ config DVB_BUDGET
tristate "Budget cards"
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146
+ select DVB_PLL
select DVB_STV0299
select DVB_VES1X93
select DVB_VES1820
@@ -83,6 +85,7 @@ config DVB_BUDGET_CI
tristate "Budget cards with onboard CI connector"
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146
+ select DVB_PLL
select DVB_STV0297
select DVB_STV0299
select DVB_TDA1004X
@@ -104,6 +107,7 @@ config DVB_BUDGET_AV
tristate "Budget cards with analog video inputs"
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146_VV
+ select DVB_PLL
select DVB_STV0299
select DVB_TDA1004X
select DVB_TDA10021
@@ -122,6 +126,7 @@ config DVB_BUDGET_PATCH
tristate "AV7110 cards with Budget Patch"
depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1
select DVB_AV7110
+ select DVB_PLL
select DVB_STV0299
select DVB_VES1X93
select DVB_TDA8083
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index 92c7cdcf898..46a6a60d2ab 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -1,6 +1,7 @@
config DVB_TTUSB_BUDGET
tristate "Technotrend/Hauppauge Nova-USB devices"
- depends on DVB_CORE && USB
+ depends on DVB_CORE && USB && I2C
+ select DVB_PLL
select DVB_CX22700
select DVB_TDA1004X
select DVB_VES1820
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 732bf1e7c32..94d078b77ba 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -260,7 +260,7 @@ source "drivers/media/video/saa7134/Kconfig"
config VIDEO_MXB
tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
- depends on PCI && VIDEO_V4L1
+ depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
select VIDEO_TUNER
---help---
@@ -272,7 +272,7 @@ config VIDEO_MXB
config VIDEO_DPC
tristate "Philips-Semiconductors 'dpc7146 demonstration board'"
- depends on PCI && VIDEO_V4L1
+ depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
select VIDEO_V4L2
---help---
@@ -287,7 +287,7 @@ config VIDEO_DPC
config VIDEO_HEXIUM_ORION
tristate "Hexium HV-PCI6 and Orion frame grabber"
- depends on PCI && VIDEO_V4L1
+ depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
select VIDEO_V4L2
---help---
@@ -299,7 +299,7 @@ config VIDEO_HEXIUM_ORION
config VIDEO_HEXIUM_GEMINI
tristate "Hexium Gemini frame grabber"
- depends on PCI && VIDEO_V4L1
+ depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
select VIDEO_V4L2
---help---
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index b41f81d2372..933d6db09ac 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -303,6 +303,7 @@ int bttv_input_init(struct bttv *btv)
ir->mask_keyup = 0x010000;
ir->polling = 50; // ms
break;
+ case BTTV_BOARD_PV_M4900:
case BTTV_BOARD_PV_BT878P_9B:
case BTTV_BOARD_PV_BT878P_PLUS:
ir_codes = ir_codes_pixelview;
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 80e23ee9801..7a94e6a1192 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -51,6 +51,7 @@ config VIDEO_CX88_DVB
tristate "DVB/ATSC Support for cx2388x based TV cards"
depends on VIDEO_CX88 && DVB_CORE
select VIDEO_BUF_DVB
+ select DVB_PLL
---help---
This adds support for DVB/ATSC cards based on the
Conexant 2388x chip.
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index e1c1805df1f..f5543166d19 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -40,6 +40,7 @@ config VIDEO_SAA7134_DVB
depends on VIDEO_SAA7134 && DVB_CORE
select VIDEO_BUF_DVB
select FW_LOADER
+ select DVB_PLL
---help---
This adds support for DVB cards based on the
Philips saa7134 chip.
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c
index d7eadc2c298..8b542599ed4 100644
--- a/drivers/media/video/tuner-types.c
+++ b/drivers/media/video/tuner-types.c
@@ -926,11 +926,17 @@ static struct tuner_params tuner_lg_tdvs_h06xf_params[] = {
/* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */
+static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = {
+ { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
+ { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
+ { 16 * 999.99 , 0x8e, 0x08, },
+};
+
static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = {
{
.type = TUNER_PARAM_TYPE_PAL,
- .ranges = tuner_tena_9533_di_pal_ranges,
- .count = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges),
+ .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges,
+ .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges),
},
};
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h
index ffcda95ed9d..8fb4a3414e0 100644
--- a/drivers/media/video/zoran.h
+++ b/drivers/media/video/zoran.h
@@ -267,7 +267,7 @@ struct zoran_v4l_settings {
};
/* whoops, this one is undeclared if !v4l2 */
-#ifndef HAVE_V4L2
+#ifndef CONFIG_VIDEO_V4L2
struct v4l2_jpegcompression {
int quality;
int APPn;
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index d9a5876eb38..5f90db27892 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -86,7 +86,7 @@
#include "zoran_device.h"
#include "zoran_card.h"
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
/* we declare some card type definitions here, they mean
* the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */
#define ZORAN_V4L2_VID_FLAGS ( \
@@ -103,7 +103,7 @@ const struct zoran_format zoran_formats[] = {
{
.name = "15-bit RGB",
.palette = VIDEO_PALETTE_RGB555,
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
#ifdef __LITTLE_ENDIAN
.fourcc = V4L2_PIX_FMT_RGB555,
#else
@@ -117,7 +117,7 @@ const struct zoran_format zoran_formats[] = {
}, {
.name = "16-bit RGB",
.palette = VIDEO_PALETTE_RGB565,
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
#ifdef __LITTLE_ENDIAN
.fourcc = V4L2_PIX_FMT_RGB565,
#else
@@ -131,7 +131,7 @@ const struct zoran_format zoran_formats[] = {
}, {
.name = "24-bit RGB",
.palette = VIDEO_PALETTE_RGB24,
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
#ifdef __LITTLE_ENDIAN
.fourcc = V4L2_PIX_FMT_BGR24,
#else
@@ -145,7 +145,7 @@ const struct zoran_format zoran_formats[] = {
}, {
.name = "32-bit RGB",
.palette = VIDEO_PALETTE_RGB32,
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
#ifdef __LITTLE_ENDIAN
.fourcc = V4L2_PIX_FMT_BGR32,
#else
@@ -159,7 +159,7 @@ const struct zoran_format zoran_formats[] = {
}, {
.name = "4:2:2, packed, YUYV",
.palette = VIDEO_PALETTE_YUV422,
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
.fourcc = V4L2_PIX_FMT_YUYV,
.colorspace = V4L2_COLORSPACE_SMPTE170M,
#endif
@@ -169,7 +169,7 @@ const struct zoran_format zoran_formats[] = {
}, {
.name = "Hardware-encoded Motion-JPEG",
.palette = -1,
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
.fourcc = V4L2_PIX_FMT_MJPEG,
.colorspace = V4L2_COLORSPACE_SMPTE170M,
#endif
@@ -210,7 +210,7 @@ static int lock_norm = 0; /* 1=Don't change TV standard (norm) */
module_param(lock_norm, int, 0);
MODULE_PARM_DESC(lock_norm, "Users can't change norm");
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
/* small helper function for calculating buffersizes for v4l2
* we calculate the nearest higher power-of-two, which
* will be the recommended buffersize */
@@ -1761,7 +1761,7 @@ setup_overlay (struct file *file,
return wait_grab_pending(zr);
}
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
/* get the status of a buffer in the clients buffer queue */
static int
zoran_v4l2_buffer_status (struct file *file,
@@ -2676,7 +2676,7 @@ zoran_do_ioctl (struct inode *inode,
}
break;
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
/* The new video4linux2 capture interface - much nicer than video4linux1, since
* it allows for integrating the JPEG capturing calls inside standard v4l2
@@ -4689,7 +4689,7 @@ static struct file_operations zoran_fops = {
struct video_device zoran_template __devinitdata = {
.name = ZORAN_NAME,
.type = ZORAN_VID_TYPE,
-#ifdef HAVE_V4L2
+#ifdef CONFIG_VIDEO_V4L2
.type2 = ZORAN_V4L2_VID_FLAGS,
#endif
.hardware = ZORAN_HARDWARE,
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c
index 7ca9e95bdf8..fb6565b98f3 100644
--- a/drivers/mmc/imxmmc.c
+++ b/drivers/mmc/imxmmc.c
@@ -91,6 +91,8 @@ struct imxmci_host {
int dma_allocated;
unsigned char actual_bus_width;
+
+ int prev_cmd_code;
};
#define IMXMCI_PEND_IRQ_b 0
@@ -248,16 +250,14 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
* partial FIFO fills and reads. The length has to be rounded up to burst size multiple.
* This is required for SCR read at least.
*/
- if (datasz < 64) {
+ if (datasz < 512) {
host->dma_size = datasz;
if (data->flags & MMC_DATA_READ) {
host->dma_dir = DMA_FROM_DEVICE;
/* Hack to enable read SCR */
- if(datasz < 16) {
- MMC_NOB = 1;
- MMC_BLK_LEN = 16;
- }
+ MMC_NOB = 1;
+ MMC_BLK_LEN = 512;
} else {
host->dma_dir = DMA_TO_DEVICE;
}
@@ -409,6 +409,9 @@ static void imxmci_finish_request(struct imxmci_host *host, struct mmc_request *
spin_unlock_irqrestore(&host->lock, flags);
+ if(req && req->cmd)
+ host->prev_cmd_code = req->cmd->opcode;
+
host->req = NULL;
host->cmd = NULL;
host->data = NULL;
@@ -553,7 +556,6 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
{
int i;
int burst_len;
- int flush_len;
int trans_done = 0;
unsigned int stat = *pstat;
@@ -566,44 +568,43 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data running STATUS = 0x%x\n",
stat);
+ udelay(20); /* required for clocks < 8MHz*/
+
if(host->dma_dir == DMA_FROM_DEVICE) {
imxmci_busy_wait_for_status(host, &stat,
STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE,
- 20, "imxmci_cpu_driven_data read");
+ 50, "imxmci_cpu_driven_data read");
while((stat & (STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE)) &&
- (host->data_cnt < host->dma_size)) {
- if(burst_len >= host->dma_size - host->data_cnt) {
- flush_len = burst_len;
- burst_len = host->dma_size - host->data_cnt;
- flush_len -= burst_len;
- host->data_cnt = host->dma_size;
- trans_done = 1;
- } else {
- flush_len = 0;
- host->data_cnt += burst_len;
- }
+ (host->data_cnt < 512)) {
+
+ udelay(20); /* required for clocks < 8MHz*/
for(i = burst_len; i>=2 ; i-=2) {
- *(host->data_ptr++) = MMC_BUFFER_ACCESS;
- udelay(20); /* required for clocks < 8MHz*/
+ u16 data;
+ data = MMC_BUFFER_ACCESS;
+ udelay(10); /* required for clocks < 8MHz*/
+ if(host->data_cnt+2 <= host->dma_size) {
+ *(host->data_ptr++) = data;
+ } else {
+ if(host->data_cnt < host->dma_size)
+ *(u8*)(host->data_ptr) = data;
+ }
+ host->data_cnt += 2;
}
- if(i == 1)
- *(u8*)(host->data_ptr) = MMC_BUFFER_ACCESS;
-
stat = MMC_STATUS;
- /* Flush extra bytes from FIFO */
- while(flush_len && !(stat & STATUS_DATA_TRANS_DONE)){
- i = MMC_BUFFER_ACCESS;
- stat = MMC_STATUS;
- stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */
- }
-
- dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read burst %d STATUS = 0x%x\n",
- burst_len, stat);
+ dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read %d burst %d STATUS = 0x%x\n",
+ host->data_cnt, burst_len, stat);
}
+
+ if((stat & STATUS_DATA_TRANS_DONE) && (host->data_cnt >= 512))
+ trans_done = 1;
+
+ if(host->dma_size & 0x1ff)
+ stat &= ~STATUS_CRC_READ_ERR;
+
} else {
imxmci_busy_wait_for_status(host, &stat,
STATUS_APPL_BUFF_FE,
@@ -692,8 +693,8 @@ static void imxmci_tasklet_fnc(unsigned long data)
what, stat, MMC_INT_MASK);
dev_err(mmc_dev(host->mmc), "CMD_DAT_CONT = 0x%04x, MMC_BLK_LEN = 0x%04x, MMC_NOB = 0x%04x, DMA_CCR = 0x%08x\n",
MMC_CMD_DAT_CONT, MMC_BLK_LEN, MMC_NOB, CCR(host->dma));
- dev_err(mmc_dev(host->mmc), "CMD%d, bus %d-bit, dma_size = 0x%x\n",
- host->cmd?host->cmd->opcode:0, 1<<host->actual_bus_width, host->dma_size);
+ dev_err(mmc_dev(host->mmc), "CMD%d, prevCMD%d, bus %d-bit, dma_size = 0x%x\n",
+ host->cmd?host->cmd->opcode:0, host->prev_cmd_code, 1<<host->actual_bus_width, host->dma_size);
}
if(!host->present || timeout)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 33525bdf2ab..74eaaee66de 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -247,6 +247,55 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca,
EXPORT_SYMBOL(mmc_wait_for_app_cmd);
+/**
+ * mmc_set_data_timeout - set the timeout for a data command
+ * @data: data phase for command
+ * @card: the MMC card associated with the data transfer
+ * @write: flag to differentiate reads from writes
+ */
+void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
+ int write)
+{
+ unsigned int mult;
+
+ /*
+ * SD cards use a 100 multiplier rather than 10
+ */
+ mult = mmc_card_sd(card) ? 100 : 10;
+
+ /*
+ * Scale up the multiplier (and therefore the timeout) by
+ * the r2w factor for writes.
+ */
+ if (write)
+ mult <<= card->csd.r2w_factor;
+
+ data->timeout_ns = card->csd.tacc_ns * mult;
+ data->timeout_clks = card->csd.tacc_clks * mult;
+
+ /*
+ * SD cards also have an upper limit on the timeout.
+ */
+ if (mmc_card_sd(card)) {
+ unsigned int timeout_us, limit_us;
+
+ timeout_us = data->timeout_ns / 1000;
+ timeout_us += data->timeout_clks * 1000 /
+ (card->host->ios.clock / 1000);
+
+ if (write)
+ limit_us = 250000;
+ else
+ limit_us = 100000;
+
+ if (timeout_us > limit_us) {
+ data->timeout_ns = limit_us * 1000;
+ data->timeout_clks = 0;
+ }
+ }
+}
+EXPORT_SYMBOL(mmc_set_data_timeout);
+
static int mmc_select_card(struct mmc_host *host, struct mmc_card *card);
/**
@@ -908,11 +957,9 @@ static void mmc_read_scrs(struct mmc_host *host)
{
int err;
struct mmc_card *card;
-
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_data data;
-
struct scatterlist sg;
list_for_each_entry(card, &host->cards, node) {
@@ -947,8 +994,8 @@ static void mmc_read_scrs(struct mmc_host *host)
memset(&data, 0, sizeof(struct mmc_data));
- data.timeout_ns = card->csd.tacc_ns * 10;
- data.timeout_clks = card->csd.tacc_clks * 10;
+ mmc_set_data_timeout(&data, card, 0);
+
data.blksz_bits = 3;
data.blksz = 1 << 3;
data.blocks = 1;
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index 115cc21094b..a0e0dad1b41 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -30,6 +30,7 @@
#include <linux/mutex.h>
#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
#include <linux/mmc/protocol.h>
#include <asm/system.h>
@@ -171,8 +172,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.cmd.arg = req->sector << 9;
brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
- brq.data.timeout_ns = card->csd.tacc_ns * 10;
- brq.data.timeout_clks = card->csd.tacc_clks * 10;
brq.data.blksz_bits = md->block_bits;
brq.data.blksz = 1 << md->block_bits;
brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
@@ -180,6 +179,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.stop.arg = 0;
brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
+ mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
+
if (rq_data_dir(req) == READ) {
brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
brq.data.flags |= MMC_DATA_READ;
@@ -187,12 +188,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.cmd.opcode = MMC_WRITE_BLOCK;
brq.data.flags |= MMC_DATA_WRITE;
brq.data.blocks = 1;
-
- /*
- * Scale up the timeout by the r2w factor
- */
- brq.data.timeout_ns <<= card->csd.r2w_factor;
- brq.data.timeout_clks <<= card->csd.r2w_factor;
}
if (brq.data.blocks > 1) {
@@ -324,52 +319,11 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
md->read_only = mmc_blk_readonly(card);
/*
- * Figure out a workable block size. MMC cards have:
- * - two block sizes, one for read and one for write.
- * - may support partial reads and/or writes
- * (allows block sizes smaller than specified)
- */
- md->block_bits = card->csd.read_blkbits;
- if (card->csd.write_blkbits != card->csd.read_blkbits) {
- if (card->csd.write_blkbits < card->csd.read_blkbits &&
- card->csd.read_partial) {
- /*
- * write block size is smaller than read block
- * size, but we support partial reads, so choose
- * the smaller write block size.
- */
- md->block_bits = card->csd.write_blkbits;
- } else if (card->csd.write_blkbits > card->csd.read_blkbits &&
- card->csd.write_partial) {
- /*
- * read block size is smaller than write block
- * size, but we support partial writes. Use read
- * block size.
- */
- } else {
- /*
- * We don't support this configuration for writes.
- */
- printk(KERN_ERR "%s: unable to select block size for "
- "writing (rb%u wb%u rp%u wp%u)\n",
- mmc_card_id(card),
- 1 << card->csd.read_blkbits,
- 1 << card->csd.write_blkbits,
- card->csd.read_partial,
- card->csd.write_partial);
- md->read_only = 1;
- }
- }
-
- /*
- * Refuse to allow block sizes smaller than 512 bytes.
+ * Both SD and MMC specifications state (although a bit
+ * unclearly in the MMC case) that a block size of 512
+ * bytes must always be supported by the card.
*/
- if (md->block_bits < 9) {
- printk(KERN_ERR "%s: unable to support block size %u\n",
- mmc_card_id(card), 1 << md->block_bits);
- ret = -EINVAL;
- goto err_kfree;
- }
+ md->block_bits = 9;
md->disk = alloc_disk(1 << MMC_SHIFT);
if (md->disk == NULL) {
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 30b3671d833..a2bd8119270 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2393,7 +2393,7 @@ config MYRI10GE
you will need a newer firmware image.
You may get this image or more information, at:
- <http://www.myri.com/Myri-10G/>
+ <http://www.myri.com/scs/download-Myri10GE.html>
To compile this driver as a module, choose M here and read
<file:Documentation/networking/net-modules.txt>. The module
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 3d76fa144c4..a860ebbbf81 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -377,8 +377,8 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db)
kfree(db->data_req);
}
- if (db->addr_res != NULL) {
- release_resource(db->addr_res);
+ if (db->addr_req != NULL) {
+ release_resource(db->addr_req);
kfree(db->addr_req);
}
}
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 91ef5f2fd76..ce850f1078b 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -173,8 +173,11 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
static int debug = 3;
+static int eeprom_bad_csum_allow = 0;
module_param(debug, int, 0);
+module_param(eeprom_bad_csum_allow, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+MODULE_PARM_DESC(eeprom_bad_csum_allow, "Allow bad eeprom checksums");
#define DPRINTK(nlevel, klevel, fmt, args...) \
(void)((NETIF_MSG_##nlevel & nic->msg_enable) && \
printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \
@@ -756,7 +759,8 @@ static int e100_eeprom_load(struct nic *nic)
checksum = le16_to_cpu(0xBABA - checksum);
if(checksum != nic->eeprom[nic->eeprom_wc - 1]) {
DPRINTK(PROBE, ERR, "EEPROM corrupted\n");
- return -EAGAIN;
+ if (!eeprom_bad_csum_allow)
+ return -EAGAIN;
}
return 0;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 726f43d5593..98ef9f85482 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1433,8 +1433,8 @@ e1000_configure_tx(struct e1000_adapter *adapter)
E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
E1000_WRITE_REG(hw, TDT, 0);
E1000_WRITE_REG(hw, TDH, 0);
- adapter->tx_ring[0].tdh = E1000_TDH;
- adapter->tx_ring[0].tdt = E1000_TDT;
+ adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
+ adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
break;
}
@@ -1840,8 +1840,8 @@ e1000_configure_rx(struct e1000_adapter *adapter)
E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
E1000_WRITE_REG(hw, RDT, 0);
E1000_WRITE_REG(hw, RDH, 0);
- adapter->rx_ring[0].rdh = E1000_RDH;
- adapter->rx_ring[0].rdt = E1000_RDT;
+ adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
+ adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
break;
}
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 760c61b9886..eeab1df5bef 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -385,6 +385,8 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget)
struct pkt_info pkt_info;
while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
+ dma_unmap_single(NULL, pkt_info.buf_ptr, RX_SKB_SIZE,
+ DMA_FROM_DEVICE);
mp->rx_desc_count--;
received_packets++;
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 0e3fdf7c6dd..ec0413609f3 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1566,20 +1566,21 @@ static int __exit sunlance_sun4_remove(void)
static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match)
{
struct sbus_dev *sdev = to_sbus_device(&dev->dev);
- struct device_node *dp = dev->node;
int err;
- if (!strcmp(dp->name, "le")) {
- err = sparc_lance_probe_one(sdev, NULL, NULL);
- } else if (!strcmp(dp->name, "ledma")) {
- struct sbus_dma *ledma = find_ledma(sdev);
+ if (sdev->parent) {
+ struct of_device *parent = &sdev->parent->ofdev;
- err = sparc_lance_probe_one(sdev->child, ledma, NULL);
- } else {
- BUG_ON(strcmp(dp->name, "lebuffer"));
+ if (!strcmp(parent->node->name, "ledma")) {
+ struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev));
- err = sparc_lance_probe_one(sdev->child, NULL, sdev);
- }
+ err = sparc_lance_probe_one(sdev, ledma, NULL);
+ } else if (!strcmp(parent->node->name, "lebuffer")) {
+ err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev));
+ } else
+ err = sparc_lance_probe_one(sdev, NULL, NULL);
+ } else
+ err = sparc_lance_probe_one(sdev, NULL, NULL);
return err;
}
@@ -1604,12 +1605,6 @@ static struct of_device_id sunlance_sbus_match[] = {
{
.name = "le",
},
- {
- .name = "ledma",
- },
- {
- .name = "lebuffer",
- },
{},
};
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index fd31885c684..ccaf28e8db0 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -467,6 +467,7 @@ static int arp_query(unsigned char *haddr, u32 paddr,
struct net_device *dev)
{
struct neighbour *neighbor_entry;
+ int ret = 0;
neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev);
@@ -474,10 +475,11 @@ static int arp_query(unsigned char *haddr, u32 paddr,
neighbor_entry->used = jiffies;
if (neighbor_entry->nud_state & NUD_VALID) {
memcpy(haddr, neighbor_entry->ha, dev->addr_len);
- return 1;
+ ret = 1;
}
+ neigh_release(neighbor_entry);
}
- return 0;
+ return ret;
}
static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr,
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index da9d06bdb81..aa792821854 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1430,9 +1430,43 @@ static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
break;
}
+ switch (rate) {
+ case ZD_OFDM_RATE_6M:
+ case ZD_OFDM_RATE_9M:
+ i += 3;
+ break;
+ case ZD_OFDM_RATE_12M:
+ case ZD_OFDM_RATE_18M:
+ i += 5;
+ break;
+ case ZD_OFDM_RATE_24M:
+ case ZD_OFDM_RATE_36M:
+ i += 9;
+ break;
+ case ZD_OFDM_RATE_48M:
+ case ZD_OFDM_RATE_54M:
+ i += 15;
+ break;
+ default:
+ return -EINVAL;
+ }
+
return i;
}
+static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size)
+{
+ int r;
+
+ r = ofdm_qual_db(status_quality, rate, size);
+ ZD_ASSERT(r >= 0);
+ if (r < 0)
+ r = 0;
+
+ r = (r * 100)/29;
+ return r <= 100 ? r : 100;
+}
+
static unsigned int log10times100(unsigned int x)
{
static const u8 log10[] = {
@@ -1476,31 +1510,28 @@ static int cck_snr_db(u8 status_quality)
return r;
}
-static int rx_qual_db(const void *rx_frame, unsigned int size,
- const struct rx_status *status)
+static int cck_qual_percent(u8 status_quality)
{
- return (status->frame_status&ZD_RX_OFDM) ?
- ofdm_qual_db(status->signal_quality_ofdm,
- zd_ofdm_plcp_header_rate(rx_frame),
- size) :
- cck_snr_db(status->signal_quality_cck);
+ int r;
+
+ r = cck_snr_db(status_quality);
+ r = (100*r)/17;
+ return r <= 100 ? r : 100;
}
u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
const struct rx_status *status)
{
- int r = rx_qual_db(rx_frame, size, status);
- if (r < 0)
- r = 0;
- r = (r * 100) / 14;
- if (r > 100)
- r = 100;
- return r;
+ return (status->frame_status&ZD_RX_OFDM) ?
+ ofdm_qual_percent(status->signal_quality_ofdm,
+ zd_ofdm_plcp_header_rate(rx_frame),
+ size) :
+ cck_qual_percent(status->signal_quality_cck);
}
u8 zd_rx_strength_percent(u8 rssi)
{
- int r = (rssi*100) / 30;
+ int r = (rssi*100) / 41;
if (r > 100)
r = 100;
return (u8) r;
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index d6f3e02a0b5..a9bd80a0861 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -816,13 +816,25 @@ static int filter_rx(struct ieee80211_device *ieee,
return -EINVAL;
}
-static void update_qual_rssi(struct zd_mac *mac, u8 qual_percent, u8 rssi)
+static void update_qual_rssi(struct zd_mac *mac,
+ const u8 *buffer, unsigned int length,
+ u8 qual_percent, u8 rssi_percent)
{
unsigned long flags;
+ struct ieee80211_hdr_3addr *hdr;
+ int i;
+
+ hdr = (struct ieee80211_hdr_3addr *)buffer;
+ if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
+ return;
+ if (memcmp(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid, ETH_ALEN) != 0)
+ return;
spin_lock_irqsave(&mac->lock, flags);
- mac->qual_average = (7 * mac->qual_average + qual_percent) / 8;
- mac->rssi_average = (7 * mac->rssi_average + rssi) / 8;
+ i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE;
+ mac->qual_buffer[i] = qual_percent;
+ mac->rssi_buffer[i] = rssi_percent;
+ mac->stats_count++;
spin_unlock_irqrestore(&mac->lock, flags);
}
@@ -853,7 +865,6 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats,
if (stats->rate)
stats->mask |= IEEE80211_STATMASK_RATE;
- update_qual_rssi(mac, stats->signal, stats->rssi);
return 0;
}
@@ -877,6 +888,8 @@ int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length)
sizeof(struct rx_status);
buffer += ZD_PLCP_HEADER_SIZE;
+ update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi);
+
r = filter_rx(ieee, buffer, length, &stats);
if (r <= 0)
return r;
@@ -981,17 +994,31 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
{
struct zd_mac *mac = zd_netdev_mac(ndev);
struct iw_statistics *iw_stats = &mac->iw_stats;
+ unsigned int i, count, qual_total, rssi_total;
memset(iw_stats, 0, sizeof(struct iw_statistics));
/* We are not setting the status, because ieee->state is not updated
* at all and this driver doesn't track authentication state.
*/
spin_lock_irq(&mac->lock);
- iw_stats->qual.qual = mac->qual_average;
- iw_stats->qual.level = mac->rssi_average;
- iw_stats->qual.updated = IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED|
- IW_QUAL_NOISE_INVALID;
+ count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ?
+ mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE;
+ qual_total = rssi_total = 0;
+ for (i = 0; i < count; i++) {
+ qual_total += mac->qual_buffer[i];
+ rssi_total += mac->rssi_buffer[i];
+ }
spin_unlock_irq(&mac->lock);
+ iw_stats->qual.updated = IW_QUAL_NOISE_INVALID;
+ if (count > 0) {
+ iw_stats->qual.qual = qual_total / count;
+ iw_stats->qual.level = rssi_total / count;
+ iw_stats->qual.updated |=
+ IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED;
+ } else {
+ iw_stats->qual.updated |=
+ IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID;
+ }
/* TODO: update counter */
return iw_stats;
}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 71e382c589e..b3ba49b8463 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -1,4 +1,4 @@
-/* zd_mac.c
+/* zd_mac.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -87,9 +87,9 @@ struct rx_length_info {
#define RX_LENGTH_INFO_TAG 0x697e
struct rx_status {
+ u8 signal_quality_cck;
/* rssi */
u8 signal_strength;
- u8 signal_quality_cck;
u8 signal_quality_ofdm;
u8 decryption_type;
u8 frame_status;
@@ -120,14 +120,17 @@ enum mac_flags {
MAC_FIXED_CHANNEL = 0x01,
};
+#define ZD_MAC_STATS_BUFFER_SIZE 16
+
struct zd_mac {
struct net_device *netdev;
struct zd_chip chip;
spinlock_t lock;
/* Unlocked reading possible */
struct iw_statistics iw_stats;
- u8 qual_average;
- u8 rssi_average;
+ unsigned int stats_count;
+ u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
+ u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
u8 regdomain;
u8 default_regdomain;
u8 requested_channel;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 73177429fe7..17e709e7d72 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -667,6 +667,7 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_vi
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq);
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq);
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, quirk_via_irq);
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq);
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq);
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index d8e9b95f0a1..25c1ef6dfd4 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -52,7 +52,7 @@ static void dasd_setup_queue(struct dasd_device * device);
static void dasd_free_queue(struct dasd_device * device);
static void dasd_flush_request_queue(struct dasd_device *);
static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
-static void dasd_flush_ccw_queue(struct dasd_device *, int);
+static int dasd_flush_ccw_queue(struct dasd_device *, int);
static void dasd_tasklet(struct dasd_device *);
static void do_kick_device(void *data);
@@ -60,6 +60,7 @@ static void do_kick_device(void *data);
* SECTION: Operations on the device structure.
*/
static wait_queue_head_t dasd_init_waitq;
+static wait_queue_head_t dasd_flush_wq;
/*
* Allocate memory for a new device structure.
@@ -121,7 +122,7 @@ dasd_free_device(struct dasd_device *device)
/*
* Make a new device known to the system.
*/
-static inline int
+static int
dasd_state_new_to_known(struct dasd_device *device)
{
int rc;
@@ -145,7 +146,7 @@ dasd_state_new_to_known(struct dasd_device *device)
/*
* Let the system forget about a device.
*/
-static inline void
+static int
dasd_state_known_to_new(struct dasd_device * device)
{
/* Disable extended error reporting for this device. */
@@ -163,12 +164,13 @@ dasd_state_known_to_new(struct dasd_device * device)
/* Give up reference we took in dasd_state_new_to_known. */
dasd_put_device(device);
+ return 0;
}
/*
* Request the irq line for the device.
*/
-static inline int
+static int
dasd_state_known_to_basic(struct dasd_device * device)
{
int rc;
@@ -192,17 +194,23 @@ dasd_state_known_to_basic(struct dasd_device * device)
/*
* Release the irq line for the device. Terminate any running i/o.
*/
-static inline void
+static int
dasd_state_basic_to_known(struct dasd_device * device)
{
+ int rc;
+
dasd_gendisk_free(device);
- dasd_flush_ccw_queue(device, 1);
+ rc = dasd_flush_ccw_queue(device, 1);
+ if (rc)
+ return rc;
+
DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device);
if (device->debug_area != NULL) {
debug_unregister(device->debug_area);
device->debug_area = NULL;
}
device->state = DASD_STATE_KNOWN;
+ return 0;
}
/*
@@ -219,7 +227,7 @@ dasd_state_basic_to_known(struct dasd_device * device)
* In case the analysis returns an error, the device setup is stopped
* (a fake disk was already added to allow formatting).
*/
-static inline int
+static int
dasd_state_basic_to_ready(struct dasd_device * device)
{
int rc;
@@ -247,25 +255,31 @@ dasd_state_basic_to_ready(struct dasd_device * device)
* Forget format information. Check if the target level is basic
* and if it is create fake disk for formatting.
*/
-static inline void
+static int
dasd_state_ready_to_basic(struct dasd_device * device)
{
- dasd_flush_ccw_queue(device, 0);
+ int rc;
+
+ rc = dasd_flush_ccw_queue(device, 0);
+ if (rc)
+ return rc;
dasd_destroy_partitions(device);
dasd_flush_request_queue(device);
device->blocks = 0;
device->bp_block = 0;
device->s2b_shift = 0;
device->state = DASD_STATE_BASIC;
+ return 0;
}
/*
* Back to basic.
*/
-static inline void
+static int
dasd_state_unfmt_to_basic(struct dasd_device * device)
{
device->state = DASD_STATE_BASIC;
+ return 0;
}
/*
@@ -273,7 +287,7 @@ dasd_state_unfmt_to_basic(struct dasd_device * device)
* the requeueing of requests from the linux request queue to the
* ccw queue.
*/
-static inline int
+static int
dasd_state_ready_to_online(struct dasd_device * device)
{
device->state = DASD_STATE_ONLINE;
@@ -284,16 +298,17 @@ dasd_state_ready_to_online(struct dasd_device * device)
/*
* Stop the requeueing of requests again.
*/
-static inline void
+static int
dasd_state_online_to_ready(struct dasd_device * device)
{
device->state = DASD_STATE_READY;
+ return 0;
}
/*
* Device startup state changes.
*/
-static inline int
+static int
dasd_increase_state(struct dasd_device *device)
{
int rc;
@@ -329,30 +344,37 @@ dasd_increase_state(struct dasd_device *device)
/*
* Device shutdown state changes.
*/
-static inline int
+static int
dasd_decrease_state(struct dasd_device *device)
{
+ int rc;
+
+ rc = 0;
if (device->state == DASD_STATE_ONLINE &&
device->target <= DASD_STATE_READY)
- dasd_state_online_to_ready(device);
+ rc = dasd_state_online_to_ready(device);
- if (device->state == DASD_STATE_READY &&
+ if (!rc &&
+ device->state == DASD_STATE_READY &&
device->target <= DASD_STATE_BASIC)
- dasd_state_ready_to_basic(device);
+ rc = dasd_state_ready_to_basic(device);
- if (device->state == DASD_STATE_UNFMT &&
+ if (!rc &&
+ device->state == DASD_STATE_UNFMT &&
device->target <= DASD_STATE_BASIC)
- dasd_state_unfmt_to_basic(device);
+ rc = dasd_state_unfmt_to_basic(device);
- if (device->state == DASD_STATE_BASIC &&
+ if (!rc &&
+ device->state == DASD_STATE_BASIC &&
device->target <= DASD_STATE_KNOWN)
- dasd_state_basic_to_known(device);
+ rc = dasd_state_basic_to_known(device);
- if (device->state == DASD_STATE_KNOWN &&
+ if (!rc &&
+ device->state == DASD_STATE_KNOWN &&
device->target <= DASD_STATE_NEW)
- dasd_state_known_to_new(device);
+ rc = dasd_state_known_to_new(device);
- return 0;
+ return rc;
}
/*
@@ -701,6 +723,7 @@ dasd_term_IO(struct dasd_ccw_req * cqr)
cqr->retries--;
cqr->status = DASD_CQR_CLEAR;
cqr->stopclk = get_clock();
+ cqr->starttime = 0;
DBF_DEV_EVENT(DBF_DEBUG, device,
"terminate cqr %p successful",
cqr);
@@ -978,6 +1001,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) {
cqr->status = DASD_CQR_QUEUED;
dasd_clear_timer(device);
+ wake_up(&dasd_flush_wq);
dasd_schedule_bh(device);
return;
}
@@ -1241,6 +1265,10 @@ __dasd_check_expire(struct dasd_device * device)
cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
if (cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) {
if (time_after_eq(jiffies, cqr->expires + cqr->starttime)) {
+ DEV_MESSAGE(KERN_ERR, device,
+ "internal error - timeout (%is) expired "
+ "for cqr %p (%i retries left)",
+ (cqr->expires/HZ), cqr, cqr->retries);
if (device->discipline->term_IO(cqr) != 0)
/* Hmpf, try again in 1/10 sec */
dasd_set_timer(device, 10);
@@ -1285,46 +1313,100 @@ __dasd_start_head(struct dasd_device * device)
dasd_set_timer(device, 50);
}
+static inline int
+_wait_for_clear(struct dasd_ccw_req *cqr)
+{
+ return (cqr->status == DASD_CQR_QUEUED);
+}
+
/*
- * Remove requests from the ccw queue.
+ * Remove all requests from the ccw queue (all = '1') or only block device
+ * requests in case all = '0'.
+ * Take care of the erp-chain (chained via cqr->refers) and remove either
+ * the whole erp-chain or none of the erp-requests.
+ * If a request is currently running, term_IO is called and the request
+ * is re-queued. Prior to removing the terminated request we need to wait
+ * for the clear-interrupt.
+ * In case termination is not possible we stop processing and just finishing
+ * the already moved requests.
*/
-static void
+static int
dasd_flush_ccw_queue(struct dasd_device * device, int all)
{
+ struct dasd_ccw_req *cqr, *orig, *n;
+ int rc, i;
+
struct list_head flush_queue;
- struct list_head *l, *n;
- struct dasd_ccw_req *cqr;
INIT_LIST_HEAD(&flush_queue);
spin_lock_irq(get_ccwdev_lock(device->cdev));
- list_for_each_safe(l, n, &device->ccw_queue) {
- cqr = list_entry(l, struct dasd_ccw_req, list);
+ rc = 0;
+restart:
+ list_for_each_entry_safe(cqr, n, &device->ccw_queue, list) {
+ /* get original request of erp request-chain */
+ for (orig = cqr; orig->refers != NULL; orig = orig->refers);
+
/* Flush all request or only block device requests? */
- if (all == 0 && cqr->callback == dasd_end_request_cb)
+ if (all == 0 && cqr->callback != dasd_end_request_cb &&
+ orig->callback != dasd_end_request_cb) {
continue;
- if (cqr->status == DASD_CQR_IN_IO)
- device->discipline->term_IO(cqr);
- if (cqr->status != DASD_CQR_DONE ||
- cqr->status != DASD_CQR_FAILED) {
- cqr->status = DASD_CQR_FAILED;
+ }
+ /* Check status and move request to flush_queue */
+ switch (cqr->status) {
+ case DASD_CQR_IN_IO:
+ rc = device->discipline->term_IO(cqr);
+ if (rc) {
+ /* unable to terminate requeust */
+ DEV_MESSAGE(KERN_ERR, device,
+ "dasd flush ccw_queue is unable "
+ " to terminate request %p",
+ cqr);
+ /* stop flush processing */
+ goto finished;
+ }
+ break;
+ case DASD_CQR_QUEUED:
+ case DASD_CQR_ERROR:
+ /* set request to FAILED */
cqr->stopclk = get_clock();
+ cqr->status = DASD_CQR_FAILED;
+ break;
+ default: /* do not touch the others */
+ break;
+ }
+ /* Rechain request (including erp chain) */
+ for (i = 0; cqr != NULL; cqr = cqr->refers, i++) {
+ cqr->endclk = get_clock();
+ list_move_tail(&cqr->list, &flush_queue);
+ }
+ if (i > 1)
+ /* moved more than one request - need to restart */
+ goto restart;
+ }
+
+finished:
+ spin_unlock_irq(get_ccwdev_lock(device->cdev));
+ /* Now call the callback function of flushed requests */
+restart_cb:
+ list_for_each_entry_safe(cqr, n, &flush_queue, list) {
+ if (cqr->status == DASD_CQR_CLEAR) {
+ /* wait for clear interrupt! */
+ wait_event(dasd_flush_wq, _wait_for_clear(cqr));
+ cqr->status = DASD_CQR_FAILED;
}
/* Process finished ERP request. */
if (cqr->refers) {
__dasd_process_erp(device, cqr);
- continue;
+ /* restart list_for_xx loop since dasd_process_erp
+ * might remove multiple elements */
+ goto restart_cb;
}
- /* Rechain request on device request queue */
+ /* call the callback function */
cqr->endclk = get_clock();
- list_move_tail(&cqr->list, &flush_queue);
- }
- spin_unlock_irq(get_ccwdev_lock(device->cdev));
- /* Now call the callback function of flushed requests */
- list_for_each_safe(l, n, &flush_queue) {
- cqr = list_entry(l, struct dasd_ccw_req, list);
if (cqr->callback != NULL)
(cqr->callback)(cqr, cqr->callback_data);
}
+ return rc;
}
/*
@@ -1510,10 +1592,8 @@ dasd_sleep_on_interruptible(struct dasd_ccw_req * cqr)
if (device->discipline->term_IO) {
cqr->retries = -1;
device->discipline->term_IO(cqr);
- /*nished =
- * wait (non-interruptible) for final status
- * because signal ist still pending
- */
+ /* wait (non-interruptible) for final status
+ * because signal ist still pending */
spin_unlock_irq(get_ccwdev_lock(device->cdev));
wait_event(wait_q, _wait_for_wakeup(cqr));
spin_lock_irq(get_ccwdev_lock(device->cdev));
@@ -1546,19 +1626,11 @@ static inline int
_dasd_term_running_cqr(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
- int rc;
if (list_empty(&device->ccw_queue))
return 0;
cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
- rc = device->discipline->term_IO(cqr);
- if (rc == 0) {
- /* termination successful */
- cqr->status = DASD_CQR_QUEUED;
- cqr->startclk = cqr->stopclk = 0;
- cqr->starttime = 0;
- }
- return rc;
+ return device->discipline->term_IO(cqr);
}
int
@@ -1726,10 +1798,7 @@ dasd_flush_request_queue(struct dasd_device * device)
return;
spin_lock_irq(&device->request_queue_lock);
- while (!list_empty(&device->request_queue->queue_head)) {
- req = elv_next_request(device->request_queue);
- if (req == NULL)
- break;
+ while ((req = elv_next_request(device->request_queue))) {
blkdev_dequeue_request(req);
dasd_end_request(req, 0);
}
@@ -2091,6 +2160,7 @@ dasd_init(void)
int rc;
init_waitqueue_head(&dasd_init_waitq);
+ init_waitqueue_head(&dasd_flush_wq);
/* register 'common' DASD debug area, used for all DBF_XXX calls */
dasd_debug_area = debug_register("dasd", 1, 2, 8 * sizeof (long));
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 4c272b70f41..d163632101d 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -83,10 +83,12 @@ dasd_gendisk_alloc(struct dasd_device *device)
void
dasd_gendisk_free(struct dasd_device *device)
{
- del_gendisk(device->gdp);
- device->gdp->queue = NULL;
- put_disk(device->gdp);
- device->gdp = NULL;
+ if (device->gdp) {
+ del_gendisk(device->gdp);
+ device->gdp->queue = NULL;
+ put_disk(device->gdp);
+ device->gdp = NULL;
+ }
}
/*
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 3cba6c9fab1..38954f5cd14 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -183,11 +183,9 @@ ccwgroup_create(struct device *root,
gdev->creator_id = creator_id;
gdev->count = argc;
- gdev->dev = (struct device ) {
- .bus = &ccwgroup_bus_type,
- .parent = root,
- .release = ccwgroup_release,
- };
+ gdev->dev.bus = &ccwgroup_bus_type;
+ gdev->dev.parent = root;
+ gdev->dev.release = ccwgroup_release;
snprintf (gdev->dev.bus_id, BUS_ID_SIZE, "%s",
gdev->cdev[0]->dev.bus_id);
@@ -391,10 +389,8 @@ int
ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
{
/* register our new driver with the core */
- cdriver->driver = (struct device_driver) {
- .bus = &ccwgroup_bus_type,
- .name = cdriver->name,
- };
+ cdriver->driver.bus = &ccwgroup_bus_type;
+ cdriver->driver.name = cdriver->name;
return driver_register(&cdriver->driver);
}
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 61ce3f1d522..c28444af091 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -238,8 +238,6 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
/* Check for single path devices. */
if (sch->schib.pmcw.pim == 0x80)
goto out_unreg;
- if (sch->vpm == mask)
- goto out_unreg;
if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) &&
(sch->schib.scsw.actl & SCSW_ACTL_SCHACT) &&
@@ -258,6 +256,8 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
/* trigger path verification. */
if (sch->driver && sch->driver->verify)
sch->driver->verify(&sch->dev);
+ else if (sch->vpm == mask)
+ goto out_unreg;
out_unlock:
spin_unlock_irq(&sch->lock);
return 0;
@@ -1391,10 +1391,8 @@ new_channel_path(int chpid)
/* fill in status, etc. */
chp->id = chpid;
chp->state = 1;
- chp->dev = (struct device) {
- .parent = &css[0]->device,
- .release = chp_release,
- };
+ chp->dev.parent = &css[0]->device;
+ chp->dev.release = chp_release;
snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid);
/* Obtain channel path description and fill it in. */
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 585fa04233c..646da564040 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -556,12 +556,11 @@ get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid,
struct ccw_device *sibling)
{
struct device *dev;
- struct match_data data = {
- .devno = devno,
- .ssid = ssid,
- .sibling = sibling,
- };
+ struct match_data data;
+ data.devno = devno;
+ data.ssid = ssid;
+ data.sibling = sibling;
dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);
return dev ? to_ccwdev(dev) : NULL;
@@ -835,10 +834,8 @@ io_subchannel_probe (struct subchannel *sch)
return -ENOMEM;
}
atomic_set(&cdev->private->onoff, 0);
- cdev->dev = (struct device) {
- .parent = &sch->dev,
- .release = ccw_device_release,
- };
+ cdev->dev.parent = &sch->dev;
+ cdev->dev.release = ccw_device_release;
INIT_LIST_HEAD(&cdev->private->kick_work.entry);
/* Do first half of device_register. */
device_initialize(&cdev->dev);
@@ -977,9 +974,7 @@ ccw_device_console_enable (struct ccw_device *cdev, struct subchannel *sch)
int rc;
/* Initialize the ccw_device structure. */
- cdev->dev = (struct device) {
- .parent = &sch->dev,
- };
+ cdev->dev.parent= &sch->dev;
rc = io_subchannel_recog(cdev, sch);
if (rc)
return rc;
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 6d91c2eb205..35e162ba6d5 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -267,12 +267,10 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
notify = 1;
}
/* fill out sense information */
- cdev->id = (struct ccw_device_id) {
- .cu_type = cdev->private->senseid.cu_type,
- .cu_model = cdev->private->senseid.cu_model,
- .dev_type = cdev->private->senseid.dev_type,
- .dev_model = cdev->private->senseid.dev_model,
- };
+ cdev->id.cu_type = cdev->private->senseid.cu_type;
+ cdev->id.cu_model = cdev->private->senseid.cu_model;
+ cdev->id.dev_type = cdev->private->senseid.dev_type;
+ cdev->id.dev_model = cdev->private->senseid.dev_model;
if (notify) {
cdev->private->state = DEV_STATE_OFFLINE;
if (same_dev) {
@@ -566,12 +564,10 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
/* Deliver fake irb to device driver, if needed. */
if (cdev->private->flags.fake_irb) {
memset(&cdev->private->irb, 0, sizeof(struct irb));
- cdev->private->irb.scsw = (struct scsw) {
- .cc = 1,
- .fctl = SCSW_FCTL_START_FUNC,
- .actl = SCSW_ACTL_START_PEND,
- .stctl = SCSW_STCTL_STATUS_PEND,
- };
+ cdev->private->irb.scsw.cc = 1;
+ cdev->private->irb.scsw.fctl = SCSW_FCTL_START_FUNC;
+ cdev->private->irb.scsw.actl = SCSW_ACTL_START_PEND;
+ cdev->private->irb.scsw.stctl = SCSW_STCTL_STATUS_PEND;
cdev->private->flags.fake_irb = 0;
if (cdev->handler)
cdev->handler(cdev, cdev->private->intparm,
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 32610fd8868..1693a102dcf 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -24,6 +24,21 @@
#include "ioasm.h"
/*
+ * Helper function called from interrupt context to decide whether an
+ * operation should be tried again.
+ */
+static int __ccw_device_should_retry(struct scsw *scsw)
+{
+ /* CC is only valid if start function bit is set. */
+ if ((scsw->fctl & SCSW_FCTL_START_FUNC) && scsw->cc == 1)
+ return 1;
+ /* No more activity. For sense and set PGID we stubbornly try again. */
+ if (!scsw->actl)
+ return 1;
+ return 0;
+}
+
+/*
* Start Sense Path Group ID helper function. Used in ccw_device_recog
* and ccw_device_sense_pgid.
*/
@@ -155,10 +170,10 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event)
int ret;
irb = (struct irb *) __LC_IRB;
- /* Retry sense pgid for cc=1. */
+
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
- if (irb->scsw.cc == 1) {
+ if (__ccw_device_should_retry(&irb->scsw)) {
ret = __ccw_device_sense_pgid_start(cdev);
if (ret && ret != -EBUSY)
ccw_device_sense_pgid_done(cdev, ret);
@@ -391,10 +406,10 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event)
int ret;
irb = (struct irb *) __LC_IRB;
- /* Retry set pgid for cc=1. */
+
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
- if (irb->scsw.cc == 1)
+ if (__ccw_device_should_retry(&irb->scsw))
__ccw_device_verify_start(cdev);
return;
}
@@ -494,10 +509,10 @@ ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event)
int ret;
irb = (struct irb *) __LC_IRB;
- /* Retry set pgid for cc=1. */
+
if (irb->scsw.stctl ==
(SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
- if (irb->scsw.cc == 1)
+ if (__ccw_device_should_retry(&irb->scsw))
__ccw_device_disband_start(cdev);
return;
}
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index 54885475492..1a93fa684e9 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -92,15 +92,6 @@ config QETH_VLAN
If CONFIG_QETH is switched on, this option will include IEEE
802.1q VLAN support in the qeth device driver.
-config QETH_PERF_STATS
- bool "Performance statistics in /proc"
- depends on QETH
- help
- When switched on, this option will add a file in the proc-fs
- (/proc/qeth_perf_stats) containing performance statistics. It
- may slightly impact performance, so this is only recommended for
- internal tuning of the device driver.
-
config CCWGROUP
tristate
default (LCS || CTC || QETH)
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 6775a837d64..4777e36a922 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -10,7 +10,6 @@ obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
obj-$(CONFIG_LCS) += lcs.o cu3088.o
obj-$(CONFIG_CLAW) += claw.o cu3088.o
-obj-$(CONFIG_MPC) += ctcmpc.o fsm.o cu3088.o
qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o
qeth-$(CONFIG_PROC_FS) += qeth_proc.o
obj-$(CONFIG_QETH) += qeth.o
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 8a4b5812014..3257c22dd79 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -1714,6 +1714,9 @@ add_channel(struct ccw_device *cdev, enum channel_types type)
kfree(ch);
return 0;
}
+
+ spin_lock_init(&ch->collect_lock);
+
fsm_settimer(ch->fsm, &ch->timer);
skb_queue_head_init(&ch->io_queue);
skb_queue_head_init(&ch->collect_queue);
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index 0e863df4027..821dde86e24 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -335,8 +335,8 @@ do { \
#else
-#define iucv_debug(lvl, fmt, args...)
-#define iucv_dumpit(title, buf, len)
+#define iucv_debug(lvl, fmt, args...) do { } while (0)
+#define iucv_dumpit(title, buf, len) do { } while (0)
#endif
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 2eded55ae88..16ac68c27a2 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -670,9 +670,8 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
int index, rc;
LCS_DBF_TEXT(5, trace, "rdybuff");
- if (buffer->state != BUF_STATE_LOCKED &&
- buffer->state != BUF_STATE_PROCESSED)
- BUG();
+ BUG_ON(buffer->state != BUF_STATE_LOCKED &&
+ buffer->state != BUF_STATE_PROCESSED);
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
buffer->state = BUF_STATE_READY;
index = buffer - channel->iob;
@@ -696,8 +695,7 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
int index, prev, next;
LCS_DBF_TEXT(5, trace, "prcsbuff");
- if (buffer->state != BUF_STATE_READY)
- BUG();
+ BUG_ON(buffer->state != BUF_STATE_READY);
buffer->state = BUF_STATE_PROCESSED;
index = buffer - channel->iob;
prev = (index - 1) & (LCS_NUM_BUFFS - 1);
@@ -729,9 +727,8 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
unsigned long flags;
LCS_DBF_TEXT(5, trace, "relbuff");
- if (buffer->state != BUF_STATE_LOCKED &&
- buffer->state != BUF_STATE_PROCESSED)
- BUG();
+ BUG_ON(buffer->state != BUF_STATE_LOCKED &&
+ buffer->state != BUF_STATE_PROCESSED);
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
buffer->state = BUF_STATE_EMPTY;
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 5d6e6cbfa36..d7d1cc0a5c8 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -112,7 +112,12 @@ struct iucv_connection {
/**
* Linked list of all connection structs.
*/
-static struct iucv_connection *iucv_connections;
+struct iucv_connection_struct {
+ struct iucv_connection *iucv_connections;
+ rwlock_t iucv_rwlock;
+};
+
+static struct iucv_connection_struct iucv_conns;
/**
* Representation of event-data for the
@@ -1368,8 +1373,10 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf,
struct net_device *ndev = priv->conn->netdev;
char *p;
char *tmp;
- char username[10];
+ char username[9];
int i;
+ struct iucv_connection **clist = &iucv_conns.iucv_connections;
+ unsigned long flags;
IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
if (count>9) {
@@ -1382,7 +1389,7 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf,
tmp = strsep((char **) &buf, "\n");
for (i=0, p=tmp; i<8 && *p; i++, p++) {
if (isalnum(*p) || (*p == '$'))
- username[i]= *p;
+ username[i]= toupper(*p);
else if (*p == '\n') {
/* trailing lf, grr */
break;
@@ -1395,11 +1402,11 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf,
return -EINVAL;
}
}
- while (i<9)
+ while (i<8)
username[i++] = ' ';
- username[9] = '\0';
+ username[8] = '\0';
- if (memcmp(username, priv->conn->userid, 8)) {
+ if (memcmp(username, priv->conn->userid, 9)) {
/* username changed */
if (ndev->flags & (IFF_UP | IFF_RUNNING)) {
PRINT_WARN(
@@ -1410,6 +1417,19 @@ user_write (struct device *dev, struct device_attribute *attr, const char *buf,
return -EBUSY;
}
}
+ read_lock_irqsave(&iucv_conns.iucv_rwlock, flags);
+ while (*clist) {
+ if (!strncmp(username, (*clist)->userid, 9) ||
+ ((*clist)->netdev != ndev))
+ break;
+ clist = &((*clist)->next);
+ }
+ read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
+ if (*clist) {
+ PRINT_WARN("netiucv: Connection to %s already exists\n",
+ username);
+ return -EEXIST;
+ }
memcpy(priv->conn->userid, username, 9);
return count;
@@ -1781,13 +1801,15 @@ netiucv_unregister_device(struct device *dev)
static struct iucv_connection *
netiucv_new_connection(struct net_device *dev, char *username)
{
- struct iucv_connection **clist = &iucv_connections;
+ unsigned long flags;
+ struct iucv_connection **clist = &iucv_conns.iucv_connections;
struct iucv_connection *conn =
kzalloc(sizeof(struct iucv_connection), GFP_KERNEL);
if (conn) {
skb_queue_head_init(&conn->collect_queue);
skb_queue_head_init(&conn->commit_queue);
+ spin_lock_init(&conn->collect_lock);
conn->max_buffsize = NETIUCV_BUFSIZE_DEFAULT;
conn->netdev = dev;
@@ -1822,8 +1844,10 @@ netiucv_new_connection(struct net_device *dev, char *username)
fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
}
+ write_lock_irqsave(&iucv_conns.iucv_rwlock, flags);
conn->next = *clist;
*clist = conn;
+ write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
}
return conn;
}
@@ -1835,14 +1859,17 @@ netiucv_new_connection(struct net_device *dev, char *username)
static void
netiucv_remove_connection(struct iucv_connection *conn)
{
- struct iucv_connection **clist = &iucv_connections;
+ struct iucv_connection **clist = &iucv_conns.iucv_connections;
+ unsigned long flags;
IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
if (conn == NULL)
return;
+ write_lock_irqsave(&iucv_conns.iucv_rwlock, flags);
while (*clist) {
if (*clist == conn) {
*clist = conn->next;
+ write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
if (conn->handle) {
iucv_unregister_program(conn->handle);
conn->handle = NULL;
@@ -1855,6 +1882,7 @@ netiucv_remove_connection(struct iucv_connection *conn)
}
clist = &((*clist)->next);
}
+ write_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
}
/**
@@ -1947,9 +1975,11 @@ static ssize_t
conn_write(struct device_driver *drv, const char *buf, size_t count)
{
char *p;
- char username[10];
+ char username[9];
int i, ret;
struct net_device *dev;
+ struct iucv_connection **clist = &iucv_conns.iucv_connections;
+ unsigned long flags;
IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
if (count>9) {
@@ -1960,7 +1990,7 @@ conn_write(struct device_driver *drv, const char *buf, size_t count)
for (i=0, p=(char *)buf; i<8 && *p; i++, p++) {
if (isalnum(*p) || (*p == '$'))
- username[i]= *p;
+ username[i]= toupper(*p);
else if (*p == '\n') {
/* trailing lf, grr */
break;
@@ -1971,9 +2001,22 @@ conn_write(struct device_driver *drv, const char *buf, size_t count)
return -EINVAL;
}
}
- while (i<9)
+ while (i<8)
username[i++] = ' ';
- username[9] = '\0';
+ username[8] = '\0';
+
+ read_lock_irqsave(&iucv_conns.iucv_rwlock, flags);
+ while (*clist) {
+ if (!strncmp(username, (*clist)->userid, 9))
+ break;
+ clist = &((*clist)->next);
+ }
+ read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
+ if (*clist) {
+ PRINT_WARN("netiucv: Connection to %s already exists\n",
+ username);
+ return -EEXIST;
+ }
dev = netiucv_init_netdevice(username);
if (!dev) {
PRINT_WARN(
@@ -2015,7 +2058,8 @@ DRIVER_ATTR(connection, 0200, NULL, conn_write);
static ssize_t
remove_write (struct device_driver *drv, const char *buf, size_t count)
{
- struct iucv_connection **clist = &iucv_connections;
+ struct iucv_connection **clist = &iucv_conns.iucv_connections;
+ unsigned long flags;
struct net_device *ndev;
struct netiucv_priv *priv;
struct device *dev;
@@ -2026,7 +2070,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count)
IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
if (count >= IFNAMSIZ)
- count = IFNAMSIZ-1;
+ count = IFNAMSIZ - 1;;
for (i=0, p=(char *)buf; i<count && *p; i++, p++) {
if ((*p == '\n') || (*p == ' ')) {
@@ -2038,6 +2082,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count)
}
name[i] = '\0';
+ read_lock_irqsave(&iucv_conns.iucv_rwlock, flags);
while (*clist) {
ndev = (*clist)->netdev;
priv = (struct netiucv_priv*)ndev->priv;
@@ -2047,6 +2092,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count)
clist = &((*clist)->next);
continue;
}
+ read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
if (ndev->flags & (IFF_UP | IFF_RUNNING)) {
PRINT_WARN(
"netiucv: net device %s active with peer %s\n",
@@ -2060,6 +2106,7 @@ remove_write (struct device_driver *drv, const char *buf, size_t count)
netiucv_unregister_device(dev);
return count;
}
+ read_unlock_irqrestore(&iucv_conns.iucv_rwlock, flags);
PRINT_WARN("netiucv: net device %s unknown\n", name);
IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n");
return -EINVAL;
@@ -2077,8 +2124,8 @@ static void __exit
netiucv_exit(void)
{
IUCV_DBF_TEXT(trace, 3, __FUNCTION__);
- while (iucv_connections) {
- struct net_device *ndev = iucv_connections->netdev;
+ while (iucv_conns.iucv_connections) {
+ struct net_device *ndev = iucv_conns.iucv_connections->netdev;
struct netiucv_priv *priv = (struct netiucv_priv*)ndev->priv;
struct device *dev = priv->dev;
@@ -2120,6 +2167,7 @@ netiucv_init(void)
if (!ret) {
ret = driver_create_file(&netiucv_driver, &driver_attr_remove);
netiucv_banner();
+ rwlock_init(&iucv_conns.iucv_rwlock);
} else {
PRINT_ERR("NETIUCV: failed to add driver attribute.\n");
IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_create_file\n", ret);
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 619f4a0c716..821383d8cbe 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -176,7 +176,6 @@ extern struct ccwgroup_driver qeth_ccwgroup_driver;
/**
* card stuff
*/
-#ifdef CONFIG_QETH_PERF_STATS
struct qeth_perf_stats {
unsigned int bufs_rec;
unsigned int bufs_sent;
@@ -211,8 +210,10 @@ struct qeth_perf_stats {
unsigned int large_send_cnt;
unsigned int sg_skbs_sent;
unsigned int sg_frags_sent;
+ /* initial values when measuring starts */
+ unsigned long initial_rx_packets;
+ unsigned long initial_tx_packets;
};
-#endif /* CONFIG_QETH_PERF_STATS */
/* Routing stuff */
struct qeth_routing_info {
@@ -462,6 +463,7 @@ enum qeth_qdio_info_states {
QETH_QDIO_UNINITIALIZED,
QETH_QDIO_ALLOCATED,
QETH_QDIO_ESTABLISHED,
+ QETH_QDIO_CLEANING
};
struct qeth_buffer_pool_entry {
@@ -536,7 +538,7 @@ struct qeth_qdio_out_q {
} __attribute__ ((aligned(256)));
struct qeth_qdio_info {
- volatile enum qeth_qdio_info_states state;
+ atomic_t state;
/* input */
struct qeth_qdio_q *in_q;
struct qeth_qdio_buffer_pool in_buf_pool;
@@ -767,6 +769,7 @@ struct qeth_card_options {
int fake_ll;
int layer2;
enum qeth_large_send_types large_send;
+ int performance_stats;
};
/*
@@ -819,9 +822,7 @@ struct qeth_card {
struct list_head cmd_waiter_list;
/* QDIO buffer handling */
struct qeth_qdio_info qdio;
-#ifdef CONFIG_QETH_PERF_STATS
struct qeth_perf_stats perf_stats;
-#endif /* CONFIG_QETH_PERF_STATS */
int use_hard_stop;
int (*orig_hard_header)(struct sk_buff *,struct net_device *,
unsigned short,void *,void *,unsigned);
@@ -859,23 +860,18 @@ qeth_get_ipa_adp_type(enum qeth_link_types link_type)
}
}
-static inline int
-qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size)
+static inline struct sk_buff *
+qeth_realloc_headroom(struct qeth_card *card, struct sk_buff *skb, int size)
{
- struct sk_buff *new_skb = NULL;
-
- if (skb_headroom(*skb) < size){
- new_skb = skb_realloc_headroom(*skb, size);
- if (!new_skb) {
- PRINT_ERR("qeth_prepare_skb: could "
- "not realloc headroom for qeth_hdr "
- "on interface %s", QETH_CARD_IFNAME(card));
- return -ENOMEM;
- }
- kfree_skb(*skb);
- *skb = new_skb;
- }
- return 0;
+ struct sk_buff *new_skb = skb;
+
+ if (skb_headroom(skb) >= size)
+ return skb;
+ new_skb = skb_realloc_headroom(skb, size);
+ if (!new_skb)
+ PRINT_ERR("Could not realloc headroom for qeth_hdr "
+ "on interface %s", QETH_CARD_IFNAME(card));
+ return new_skb;
}
static inline struct sk_buff *
@@ -885,16 +881,15 @@ qeth_pskb_unshare(struct sk_buff *skb, int pri)
if (!skb_cloned(skb))
return skb;
nskb = skb_copy(skb, pri);
- kfree_skb(skb); /* free our shared copy */
return nskb;
}
static inline void *
-qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size)
+qeth_push_skb(struct qeth_card *card, struct sk_buff *skb, int size)
{
void *hdr;
- hdr = (void *) skb_push(*skb, size);
+ hdr = (void *) skb_push(skb, size);
/*
* sanity check, the Linux memory allocation scheme should
* never present us cases like this one (the qdio header size plus
@@ -903,8 +898,7 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size)
if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) !=
(((unsigned long) hdr + size +
QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) {
- PRINT_ERR("qeth_prepare_skb: misaligned "
- "packet on interface %s. Discarded.",
+ PRINT_ERR("Misaligned packet on interface %s. Discarded.",
QETH_CARD_IFNAME(card));
return NULL;
}
@@ -1056,13 +1050,11 @@ qeth_get_arphdr_type(int cardtype, int linktype)
}
}
-#ifdef CONFIG_QETH_PERF_STATS
static inline int
qeth_get_micros(void)
{
return (int) (get_clock() >> 12);
}
-#endif
static inline int
qeth_get_qdio_q_format(struct qeth_card *card)
@@ -1096,10 +1088,11 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr)
{
int count = 0, rc = 0;
int in[4];
+ char c;
- rc = sscanf(buf, "%d.%d.%d.%d%n",
- &in[0], &in[1], &in[2], &in[3], &count);
- if (rc != 4 || count<=0)
+ rc = sscanf(buf, "%u.%u.%u.%u%c",
+ &in[0], &in[1], &in[2], &in[3], &c);
+ if (rc != 4 && (rc != 5 || c != '\n'))
return -EINVAL;
for (count = 0; count < 4; count++) {
if (in[count] > 255)
@@ -1123,24 +1116,28 @@ qeth_ipaddr6_to_string(const __u8 *addr, char *buf)
static inline int
qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
{
- char *end, *start;
+ const char *end, *end_tmp, *start;
__u16 *in;
char num[5];
int num2, cnt, out, found, save_cnt;
unsigned short in_tmp[8] = {0, };
cnt = out = found = save_cnt = num2 = 0;
- end = start = (char *) buf;
+ end = start = buf;
in = (__u16 *) addr;
memset(in, 0, 16);
- while (end) {
- end = strchr(end,':');
+ while (*end) {
+ end = strchr(start,':');
if (end == NULL) {
- end = (char *)buf + (strlen(buf));
- out = 1;
+ end = buf + strlen(buf);
+ if ((end_tmp = strchr(start, '\n')) != NULL)
+ end = end_tmp;
+ out = 1;
}
if ((end - start)) {
memset(num, 0, 5);
+ if ((end - start) > 4)
+ return -EINVAL;
memcpy(num, start, end - start);
if (!qeth_isxdigit(num))
return -EINVAL;
@@ -1158,6 +1155,8 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
}
start = ++end;
}
+ if (cnt + save_cnt > 8)
+ return -EINVAL;
cnt = 7;
while (save_cnt)
in[cnt--] = in_tmp[--save_cnt];
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index 8491598f914..a363721cf28 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -179,9 +179,8 @@ out_check:
flush_cnt++;
}
} else {
-#ifdef CONFIG_QETH_PERF_STATS
- queue->card->perf_stats.skbs_sent_pack++;
-#endif
+ if (queue->card->options.performance_stats)
+ queue->card->perf_stats.skbs_sent_pack++;
QETH_DBF_TEXT(trace, 6, "fillbfpa");
if (buf->next_element_to_fill >=
QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index e1327b8fce0..5613b4564fa 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1073,6 +1073,7 @@ qeth_set_intial_options(struct qeth_card *card)
card->options.layer2 = 1;
else
card->options.layer2 = 0;
+ card->options.performance_stats = 1;
}
/**
@@ -1708,6 +1709,7 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
"IP address reset.\n",
QETH_CARD_IFNAME(card),
card->info.chpid);
+ netif_carrier_on(card->dev);
qeth_schedule_recovery(card);
return NULL;
case IPA_CMD_MODCCID:
@@ -2464,24 +2466,6 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
qeth_rebuild_skb_fake_ll_eth(card, skb, hdr);
}
-static inline void
-qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb,
- struct qeth_hdr *hdr)
-{
-#ifdef CONFIG_QETH_VLAN
- u16 *vlan_tag;
-
- if (hdr->hdr.l3.ext_flags &
- (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
- vlan_tag = (u16 *) skb_push(skb, VLAN_HLEN);
- *vlan_tag = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)?
- hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
- *(vlan_tag + 1) = skb->protocol;
- skb->protocol = __constant_htons(ETH_P_8021Q);
- }
-#endif /* CONFIG_QETH_VLAN */
-}
-
static inline __u16
qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr)
@@ -2510,15 +2494,16 @@ qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
return vlan_id;
}
-static inline void
+static inline __u16
qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr)
{
+ unsigned short vlan_id = 0;
#ifdef CONFIG_QETH_IPV6
if (hdr->hdr.l3.flags & QETH_HDR_PASSTHRU) {
skb->pkt_type = PACKET_HOST;
skb->protocol = qeth_type_trans(skb, card->dev);
- return;
+ return 0;
}
#endif /* CONFIG_QETH_IPV6 */
skb->protocol = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 :
@@ -2540,7 +2525,13 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
default:
skb->pkt_type = PACKET_HOST;
}
- qeth_rebuild_skb_vlan(card, skb, hdr);
+
+ if (hdr->hdr.l3.ext_flags &
+ (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
+ vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)?
+ hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
+ }
+
if (card->options.fake_ll)
qeth_rebuild_skb_fake_ll(card, skb, hdr);
else
@@ -2556,6 +2547,7 @@ qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
else
skb->ip_summed = SW_CHECKSUMMING;
}
+ return vlan_id;
}
static inline void
@@ -2568,20 +2560,20 @@ qeth_process_inbound_buffer(struct qeth_card *card,
int offset;
int rxrc;
__u16 vlan_tag = 0;
+ __u16 *vlan_addr;
/* get first element of current buffer */
element = (struct qdio_buffer_element *)&buf->buffer->element[0];
offset = 0;
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.bufs_rec++;
-#endif
+ if (card->options.performance_stats)
+ card->perf_stats.bufs_rec++;
while((skb = qeth_get_next_skb(card, buf->buffer, &element,
&offset, &hdr))) {
skb->dev = card->dev;
if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr);
else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
- qeth_rebuild_skb(card, skb, hdr);
+ vlan_tag = qeth_rebuild_skb(card, skb, hdr);
else { /*in case of OSN*/
skb_push(skb, sizeof(struct qeth_hdr));
memcpy(skb->data, hdr, sizeof(struct qeth_hdr));
@@ -2591,14 +2583,19 @@ qeth_process_inbound_buffer(struct qeth_card *card,
dev_kfree_skb_any(skb);
continue;
}
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ rxrc = card->osn_info.data_cb(skb);
+ else
#ifdef CONFIG_QETH_VLAN
if (vlan_tag)
- vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
+ if (card->vlangrp)
+ vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
+ else {
+ dev_kfree_skb_any(skb);
+ continue;
+ }
else
#endif
- if (card->info.type == QETH_CARD_TYPE_OSN)
- rxrc = card->osn_info.data_cb(skb);
- else
rxrc = netif_rx(skb);
card->dev->last_rx = jiffies;
card->stats.rx_packets++;
@@ -2626,7 +2623,7 @@ qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
{
struct qeth_buffer_pool_entry *pool_entry;
int i;
-
+
pool_entry = qeth_get_buffer_pool_entry(card);
/*
* since the buffer is accessed only from the input_tasklet
@@ -2700,17 +2697,18 @@ qeth_queue_input_buffer(struct qeth_card *card, int index)
* 'index') un-requeued -> this buffer is the first buffer that
* will be requeued the next time
*/
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.inbound_do_qdio_cnt++;
- card->perf_stats.inbound_do_qdio_start_time = qeth_get_micros();
-#endif
+ if (card->options.performance_stats) {
+ card->perf_stats.inbound_do_qdio_cnt++;
+ card->perf_stats.inbound_do_qdio_start_time =
+ qeth_get_micros();
+ }
rc = do_QDIO(CARD_DDEV(card),
QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT,
0, queue->next_buf_to_init, count, NULL);
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.inbound_do_qdio_time += qeth_get_micros() -
- card->perf_stats.inbound_do_qdio_start_time;
-#endif
+ if (card->options.performance_stats)
+ card->perf_stats.inbound_do_qdio_time +=
+ qeth_get_micros() -
+ card->perf_stats.inbound_do_qdio_start_time;
if (rc){
PRINT_WARN("qeth_queue_input_buffer's do_QDIO "
"return %i (device %s).\n",
@@ -2746,10 +2744,10 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
QETH_DBF_TEXT(trace, 6, "qdinput");
card = (struct qeth_card *) card_ptr;
net_dev = card->dev;
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.inbound_cnt++;
- card->perf_stats.inbound_start_time = qeth_get_micros();
-#endif
+ if (card->options.performance_stats) {
+ card->perf_stats.inbound_cnt++;
+ card->perf_stats.inbound_start_time = qeth_get_micros();
+ }
if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
QETH_DBF_TEXT(trace, 1,"qdinchk");
@@ -2771,10 +2769,9 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
qeth_put_buffer_pool_entry(card, buffer->pool_entry);
qeth_queue_input_buffer(card, index);
}
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.inbound_time += qeth_get_micros() -
- card->perf_stats.inbound_start_time;
-#endif
+ if (card->options.performance_stats)
+ card->perf_stats.inbound_time += qeth_get_micros() -
+ card->perf_stats.inbound_start_time;
}
static inline int
@@ -2864,10 +2861,11 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
}
queue->card->dev->trans_start = jiffies;
-#ifdef CONFIG_QETH_PERF_STATS
- queue->card->perf_stats.outbound_do_qdio_cnt++;
- queue->card->perf_stats.outbound_do_qdio_start_time = qeth_get_micros();
-#endif
+ if (queue->card->options.performance_stats) {
+ queue->card->perf_stats.outbound_do_qdio_cnt++;
+ queue->card->perf_stats.outbound_do_qdio_start_time =
+ qeth_get_micros();
+ }
if (under_int)
rc = do_QDIO(CARD_DDEV(queue->card),
QDIO_FLAG_SYNC_OUTPUT | QDIO_FLAG_UNDER_INTERRUPT,
@@ -2875,10 +2873,10 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
else
rc = do_QDIO(CARD_DDEV(queue->card), QDIO_FLAG_SYNC_OUTPUT,
queue->queue_no, index, count, NULL);
-#ifdef CONFIG_QETH_PERF_STATS
- queue->card->perf_stats.outbound_do_qdio_time += qeth_get_micros() -
- queue->card->perf_stats.outbound_do_qdio_start_time;
-#endif
+ if (queue->card->options.performance_stats)
+ queue->card->perf_stats.outbound_do_qdio_time +=
+ qeth_get_micros() -
+ queue->card->perf_stats.outbound_do_qdio_start_time;
if (rc){
QETH_DBF_TEXT(trace, 2, "flushbuf");
QETH_DBF_TEXT_(trace, 2, " err%d", rc);
@@ -2890,9 +2888,8 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
return;
}
atomic_add(count, &queue->used_buffers);
-#ifdef CONFIG_QETH_PERF_STATS
- queue->card->perf_stats.bufs_sent += count;
-#endif
+ if (queue->card->options.performance_stats)
+ queue->card->perf_stats.bufs_sent += count;
}
/*
@@ -2907,9 +2904,8 @@ qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
>= QETH_HIGH_WATERMARK_PACK){
/* switch non-PACKING -> PACKING */
QETH_DBF_TEXT(trace, 6, "np->pack");
-#ifdef CONFIG_QETH_PERF_STATS
- queue->card->perf_stats.sc_dp_p++;
-#endif
+ if (queue->card->options.performance_stats)
+ queue->card->perf_stats.sc_dp_p++;
queue->do_pack = 1;
}
}
@@ -2932,9 +2928,8 @@ qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
<= QETH_LOW_WATERMARK_PACK) {
/* switch PACKING -> non-PACKING */
QETH_DBF_TEXT(trace, 6, "pack->np");
-#ifdef CONFIG_QETH_PERF_STATS
- queue->card->perf_stats.sc_p_dp++;
-#endif
+ if (queue->card->options.performance_stats)
+ queue->card->perf_stats.sc_p_dp++;
queue->do_pack = 0;
/* flush packing buffers */
buffer = &queue->bufs[queue->next_buf_to_fill];
@@ -2946,7 +2941,7 @@ qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
queue->next_buf_to_fill =
(queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
- }
+ }
}
}
return flush_count;
@@ -3002,11 +2997,10 @@ qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
!atomic_read(&queue->set_pci_flags_count))
flush_cnt +=
qeth_flush_buffers_on_no_pci(queue);
-#ifdef CONFIG_QETH_PERF_STATS
- if (q_was_packing)
+ if (queue->card->options.performance_stats &&
+ q_was_packing)
queue->card->perf_stats.bufs_sent_pack +=
flush_cnt;
-#endif
if (flush_cnt)
qeth_flush_buffers(queue, 1, index, flush_cnt);
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
@@ -3036,10 +3030,11 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
return;
}
}
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.outbound_handler_cnt++;
- card->perf_stats.outbound_handler_start_time = qeth_get_micros();
-#endif
+ if (card->options.performance_stats) {
+ card->perf_stats.outbound_handler_cnt++;
+ card->perf_stats.outbound_handler_start_time =
+ qeth_get_micros();
+ }
for(i = first_element; i < (first_element + count); ++i){
buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
/*we only handle the KICK_IT error by doing a recovery */
@@ -3058,10 +3053,9 @@ qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
qeth_check_outbound_queue(queue);
netif_wake_queue(queue->card->dev);
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.outbound_handler_time += qeth_get_micros() -
- card->perf_stats.outbound_handler_start_time;
-#endif
+ if (card->options.performance_stats)
+ card->perf_stats.outbound_handler_time += qeth_get_micros() -
+ card->perf_stats.outbound_handler_start_time;
}
static void
@@ -3185,13 +3179,14 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
QETH_DBF_TEXT(setup, 2, "allcqdbf");
- if (card->qdio.state == QETH_QDIO_ALLOCATED)
+ if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED,
+ QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
return 0;
card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
GFP_KERNEL|GFP_DMA);
if (!card->qdio.in_q)
- return - ENOMEM;
+ goto out_nomem;
QETH_DBF_TEXT(setup, 2, "inq");
QETH_DBF_HEX(setup, 2, &card->qdio.in_q, sizeof(void *));
memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q));
@@ -3200,27 +3195,19 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
card->qdio.in_q->bufs[i].buffer =
&card->qdio.in_q->qdio_bufs[i];
/* inbound buffer pool */
- if (qeth_alloc_buffer_pool(card)){
- kfree(card->qdio.in_q);
- return -ENOMEM;
- }
+ if (qeth_alloc_buffer_pool(card))
+ goto out_freeinq;
/* outbound */
card->qdio.out_qs =
kmalloc(card->qdio.no_out_queues *
sizeof(struct qeth_qdio_out_q *), GFP_KERNEL);
- if (!card->qdio.out_qs){
- qeth_free_buffer_pool(card);
- return -ENOMEM;
- }
- for (i = 0; i < card->qdio.no_out_queues; ++i){
+ if (!card->qdio.out_qs)
+ goto out_freepool;
+ for (i = 0; i < card->qdio.no_out_queues; ++i) {
card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
GFP_KERNEL|GFP_DMA);
- if (!card->qdio.out_qs[i]){
- while (i > 0)
- kfree(card->qdio.out_qs[--i]);
- kfree(card->qdio.out_qs);
- return -ENOMEM;
- }
+ if (!card->qdio.out_qs[i])
+ goto out_freeoutq;
QETH_DBF_TEXT_(setup, 2, "outq %i", i);
QETH_DBF_HEX(setup, 2, &card->qdio.out_qs[i], sizeof(void *));
memset(card->qdio.out_qs[i], 0, sizeof(struct qeth_qdio_out_q));
@@ -3237,8 +3224,19 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list);
}
}
- card->qdio.state = QETH_QDIO_ALLOCATED;
return 0;
+
+out_freeoutq:
+ while (i > 0)
+ kfree(card->qdio.out_qs[--i]);
+ kfree(card->qdio.out_qs);
+out_freepool:
+ qeth_free_buffer_pool(card);
+out_freeinq:
+ kfree(card->qdio.in_q);
+out_nomem:
+ atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
+ return -ENOMEM;
}
static void
@@ -3247,7 +3245,8 @@ qeth_free_qdio_buffers(struct qeth_card *card)
int i, j;
QETH_DBF_TEXT(trace, 2, "freeqdbf");
- if (card->qdio.state == QETH_QDIO_UNINITIALIZED)
+ if (atomic_swap(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
+ QETH_QDIO_UNINITIALIZED)
return;
kfree(card->qdio.in_q);
/* inbound buffer pool */
@@ -3260,7 +3259,6 @@ qeth_free_qdio_buffers(struct qeth_card *card)
kfree(card->qdio.out_qs[i]);
}
kfree(card->qdio.out_qs);
- card->qdio.state = QETH_QDIO_UNINITIALIZED;
}
static void
@@ -3282,7 +3280,7 @@ static void
qeth_init_qdio_info(struct qeth_card *card)
{
QETH_DBF_TEXT(setup, 4, "intqdinf");
- card->qdio.state = QETH_QDIO_UNINITIALIZED;
+ atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
/* inbound */
card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT;
@@ -3345,7 +3343,7 @@ qeth_qdio_establish(struct qeth_card *card)
struct qdio_buffer **in_sbal_ptrs;
struct qdio_buffer **out_sbal_ptrs;
int i, j, k;
- int rc;
+ int rc = 0;
QETH_DBF_TEXT(setup, 2, "qdioest");
@@ -3404,8 +3402,10 @@ qeth_qdio_establish(struct qeth_card *card)
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
- if (!(rc = qdio_initialize(&init_data)))
- card->qdio.state = QETH_QDIO_ESTABLISHED;
+ if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
+ QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED)
+ if ((rc = qdio_initialize(&init_data)))
+ atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
kfree(out_sbal_ptrs);
kfree(in_sbal_ptrs);
@@ -3521,13 +3521,20 @@ qeth_qdio_clear_card(struct qeth_card *card, int use_halt)
int rc = 0;
QETH_DBF_TEXT(trace,3,"qdioclr");
- if (card->qdio.state == QETH_QDIO_ESTABLISHED){
+ switch (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ESTABLISHED,
+ QETH_QDIO_CLEANING)) {
+ case QETH_QDIO_ESTABLISHED:
if ((rc = qdio_cleanup(CARD_DDEV(card),
- (card->info.type == QETH_CARD_TYPE_IQD) ?
- QDIO_FLAG_CLEANUP_USING_HALT :
- QDIO_FLAG_CLEANUP_USING_CLEAR)))
+ (card->info.type == QETH_CARD_TYPE_IQD) ?
+ QDIO_FLAG_CLEANUP_USING_HALT :
+ QDIO_FLAG_CLEANUP_USING_CLEAR)))
QETH_DBF_TEXT_(trace, 3, "1err%d", rc);
- card->qdio.state = QETH_QDIO_ALLOCATED;
+ atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
+ break;
+ case QETH_QDIO_CLEANING:
+ return rc;
+ default:
+ break;
}
if ((rc = qeth_clear_halt_card(card, use_halt)))
QETH_DBF_TEXT_(trace, 3, "2err%d", rc);
@@ -3687,10 +3694,10 @@ qeth_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* return OK; otherwise ksoftirqd goes to 100% */
return NETDEV_TX_OK;
}
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.outbound_cnt++;
- card->perf_stats.outbound_start_time = qeth_get_micros();
-#endif
+ if (card->options.performance_stats) {
+ card->perf_stats.outbound_cnt++;
+ card->perf_stats.outbound_start_time = qeth_get_micros();
+ }
netif_stop_queue(dev);
if ((rc = qeth_send_packet(card, skb))) {
if (rc == -EBUSY) {
@@ -3704,10 +3711,9 @@ qeth_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
netif_wake_queue(dev);
-#ifdef CONFIG_QETH_PERF_STATS
- card->perf_stats.outbound_time += qeth_get_micros() -
- card->perf_stats.outbound_start_time;
-#endif
+ if (card->options.performance_stats)
+ card->perf_stats.outbound_time += qeth_get_micros() -
+ card->perf_stats.outbound_start_time;
return rc;
}
@@ -3922,49 +3928,59 @@ qeth_get_ip_version(struct sk_buff *skb)
}
}
-static inline int
-qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
- struct qeth_hdr **hdr, int ipv)
+static inline struct qeth_hdr *
+__qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
{
- int rc = 0;
#ifdef CONFIG_QETH_VLAN
u16 *tag;
-#endif
-
- QETH_DBF_TEXT(trace, 6, "prepskb");
- if (card->info.type == QETH_CARD_TYPE_OSN) {
- *hdr = (struct qeth_hdr *)(*skb)->data;
- return rc;
- }
- rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
- if (rc)
- return rc;
-#ifdef CONFIG_QETH_VLAN
- if (card->vlangrp && vlan_tx_tag_present(*skb) &&
+ if (card->vlangrp && vlan_tx_tag_present(skb) &&
((ipv == 6) || card->options.layer2) ) {
/*
* Move the mac addresses (6 bytes src, 6 bytes dest)
* to the beginning of the new header. We are using three
* memcpys instead of one memmove to save cycles.
*/
- skb_push(*skb, VLAN_HLEN);
- memcpy((*skb)->data, (*skb)->data + 4, 4);
- memcpy((*skb)->data + 4, (*skb)->data + 8, 4);
- memcpy((*skb)->data + 8, (*skb)->data + 12, 4);
- tag = (u16 *)((*skb)->data + 12);
+ skb_push(skb, VLAN_HLEN);
+ memcpy(skb->data, skb->data + 4, 4);
+ memcpy(skb->data + 4, skb->data + 8, 4);
+ memcpy(skb->data + 8, skb->data + 12, 4);
+ tag = (u16 *)(skb->data + 12);
/*
* first two bytes = ETH_P_8021Q (0x8100)
* second two bytes = VLANID
*/
*tag = __constant_htons(ETH_P_8021Q);
- *(tag + 1) = htons(vlan_tx_tag_get(*skb));
+ *(tag + 1) = htons(vlan_tx_tag_get(skb));
}
#endif
- *hdr = (struct qeth_hdr *)
- qeth_push_skb(card, skb, sizeof(struct qeth_hdr));
- if (*hdr == NULL)
- return -EINVAL;
- return 0;
+ return ((struct qeth_hdr *)
+ qeth_push_skb(card, skb, sizeof(struct qeth_hdr)));
+}
+
+static inline void
+__qeth_free_new_skb(struct sk_buff *orig_skb, struct sk_buff *new_skb)
+{
+ if (orig_skb != new_skb)
+ dev_kfree_skb_any(new_skb);
+}
+
+static inline struct sk_buff *
+qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb,
+ struct qeth_hdr **hdr, int ipv)
+{
+ struct sk_buff *new_skb;
+
+ QETH_DBF_TEXT(trace, 6, "prepskb");
+
+ new_skb = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
+ if (new_skb == NULL)
+ return NULL;
+ *hdr = __qeth_prepare_skb(card, new_skb, ipv);
+ if (*hdr == NULL) {
+ __qeth_free_new_skb(skb, new_skb);
+ return NULL;
+ }
+ return new_skb;
}
static inline u8
@@ -4206,9 +4222,8 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue,
flush_cnt = 1;
} else {
QETH_DBF_TEXT(trace, 6, "fillbfpa");
-#ifdef CONFIG_QETH_PERF_STATS
- queue->card->perf_stats.skbs_sent_pack++;
-#endif
+ if (queue->card->options.performance_stats)
+ queue->card->perf_stats.skbs_sent_pack++;
if (buf->next_element_to_fill >=
QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
/*
@@ -4245,21 +4260,15 @@ qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
* check if buffer is empty to make sure that we do not 'overtake'
* ourselves and try to fill a buffer that is already primed
*/
- if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
- card->stats.tx_dropped++;
- atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
- return -EBUSY;
- }
+ if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
+ goto out;
if (ctx == NULL)
queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
else {
buffers_needed = qeth_eddp_check_buffers_for_context(queue,ctx);
- if (buffers_needed < 0) {
- card->stats.tx_dropped++;
- atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
- return -EBUSY;
- }
+ if (buffers_needed < 0)
+ goto out;
queue->next_buf_to_fill =
(queue->next_buf_to_fill + buffers_needed) %
QDIO_MAX_BUFFERS_PER_Q;
@@ -4274,6 +4283,9 @@ qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
qeth_flush_buffers(queue, 0, index, flush_cnt);
}
return 0;
+out:
+ atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
+ return -EBUSY;
}
static inline int
@@ -4299,8 +4311,7 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
* check if buffer is empty to make sure that we do not 'overtake'
* ourselves and try to fill a buffer that is already primed
*/
- if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){
- card->stats.tx_dropped++;
+ if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
return -EBUSY;
}
@@ -4323,7 +4334,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
* again */
if (atomic_read(&buffer->state) !=
QETH_QDIO_BUF_EMPTY){
- card->stats.tx_dropped++;
qeth_flush_buffers(queue, 0, start_index, flush_count);
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
return -EBUSY;
@@ -4334,7 +4344,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
* free buffers) to handle eddp context */
if (qeth_eddp_check_buffers_for_context(queue,ctx) < 0){
printk("eddp tx_dropped 1\n");
- card->stats.tx_dropped++;
rc = -EBUSY;
goto out;
}
@@ -4346,7 +4355,6 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
tmp = qeth_eddp_fill_buffer(queue,ctx,queue->next_buf_to_fill);
if (tmp < 0) {
printk("eddp tx_dropped 2\n");
- card->stats.tx_dropped++;
rc = - EBUSY;
goto out;
}
@@ -4380,10 +4388,8 @@ out:
qeth_flush_buffers(queue, 0, start_index, flush_count);
}
/* at this point the queue is UNLOCKED again */
-#ifdef CONFIG_QETH_PERF_STATS
- if (do_pack)
+ if (queue->card->options.performance_stats && do_pack)
queue->card->perf_stats.bufs_sent_pack += flush_count;
-#endif /* CONFIG_QETH_PERF_STATS */
return rc;
}
@@ -4394,21 +4400,21 @@ qeth_get_elements_no(struct qeth_card *card, void *hdr,
{
int elements_needed = 0;
- if (skb_shinfo(skb)->nr_frags > 0) {
+ if (skb_shinfo(skb)->nr_frags > 0)
elements_needed = (skb_shinfo(skb)->nr_frags + 1);
- }
- if (elements_needed == 0 )
+ if (elements_needed == 0)
elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
+ skb->len) >> PAGE_SHIFT);
if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){
- PRINT_ERR("qeth_do_send_packet: invalid size of "
- "IP packet (Number=%d / Length=%d). Discarded.\n",
+ PRINT_ERR("Invalid size of IP packet "
+ "(Number=%d / Length=%d). Discarded.\n",
(elements_needed+elems), skb->len);
return 0;
}
return elements_needed;
}
+
static inline int
qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
{
@@ -4420,112 +4426,112 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
struct qeth_eddp_context *ctx = NULL;
int tx_bytes = skb->len;
-#ifdef CONFIG_QETH_PERF_STATS
unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
unsigned short tso_size = skb_shinfo(skb)->gso_size;
-#endif
+ struct sk_buff *new_skb, *new_skb2;
int rc;
QETH_DBF_TEXT(trace, 6, "sendpkt");
+ new_skb = skb;
+ if ((card->info.type == QETH_CARD_TYPE_OSN) &&
+ (skb->protocol == htons(ETH_P_IPV6)))
+ return -EPERM;
+ cast_type = qeth_get_cast_type(card, skb);
+ if ((cast_type == RTN_BROADCAST) &&
+ (card->info.broadcast_capable == 0))
+ return -EPERM;
+ queue = card->qdio.out_qs
+ [qeth_get_priority_queue(card, skb, ipv, cast_type)];
if (!card->options.layer2) {
ipv = qeth_get_ip_version(skb);
if ((card->dev->hard_header == qeth_fake_header) && ipv) {
- if ((skb = qeth_pskb_unshare(skb,GFP_ATOMIC)) == NULL) {
- card->stats.tx_dropped++;
- dev_kfree_skb_irq(skb);
- return 0;
- }
+ new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC);
+ if (!new_skb)
+ return -ENOMEM;
if(card->dev->type == ARPHRD_IEEE802_TR){
- skb_pull(skb, QETH_FAKE_LL_LEN_TR);
+ skb_pull(new_skb, QETH_FAKE_LL_LEN_TR);
} else {
- skb_pull(skb, QETH_FAKE_LL_LEN_ETH);
+ skb_pull(new_skb, QETH_FAKE_LL_LEN_ETH);
}
}
}
- if ((card->info.type == QETH_CARD_TYPE_OSN) &&
- (skb->protocol == htons(ETH_P_IPV6))) {
- dev_kfree_skb_any(skb);
- return 0;
- }
- cast_type = qeth_get_cast_type(card, skb);
- if ((cast_type == RTN_BROADCAST) &&
- (card->info.broadcast_capable == 0)){
- card->stats.tx_dropped++;
- card->stats.tx_errors++;
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
- queue = card->qdio.out_qs
- [qeth_get_priority_queue(card, skb, ipv, cast_type)];
-
if (skb_is_gso(skb))
large_send = card->options.large_send;
-
- /*are we able to do TSO ? If so ,prepare and send it from here */
+ /* check on OSN device*/
+ if (card->info.type == QETH_CARD_TYPE_OSN)
+ hdr = (struct qeth_hdr *)new_skb->data;
+ /*are we able to do TSO ? */
if ((large_send == QETH_LARGE_SEND_TSO) &&
(cast_type == RTN_UNSPEC)) {
- rc = qeth_tso_prepare_packet(card, skb, ipv, cast_type);
+ rc = qeth_tso_prepare_packet(card, new_skb, ipv, cast_type);
if (rc) {
- card->stats.tx_dropped++;
- card->stats.tx_errors++;
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
+ __qeth_free_new_skb(skb, new_skb);
+ return rc;
}
elements_needed++;
- } else {
- if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) {
- QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc);
- return rc;
+ } else if (card->info.type != QETH_CARD_TYPE_OSN) {
+ new_skb2 = qeth_prepare_skb(card, new_skb, &hdr, ipv);
+ if (!new_skb2) {
+ __qeth_free_new_skb(skb, new_skb);
+ return -EINVAL;
}
- if (card->info.type != QETH_CARD_TYPE_OSN)
- qeth_fill_header(card, hdr, skb, ipv, cast_type);
+ if (new_skb != skb)
+ __qeth_free_new_skb(new_skb2, new_skb);
+ new_skb = new_skb2;
+ qeth_fill_header(card, hdr, new_skb, ipv, cast_type);
}
-
if (large_send == QETH_LARGE_SEND_EDDP) {
- ctx = qeth_eddp_create_context(card, skb, hdr);
+ ctx = qeth_eddp_create_context(card, new_skb, hdr);
if (ctx == NULL) {
+ __qeth_free_new_skb(skb, new_skb);
PRINT_WARN("could not create eddp context\n");
return -EINVAL;
}
} else {
- int elems = qeth_get_elements_no(card,(void*) hdr, skb,
+ int elems = qeth_get_elements_no(card,(void*) hdr, new_skb,
elements_needed);
- if (!elems)
+ if (!elems) {
+ __qeth_free_new_skb(skb, new_skb);
return -EINVAL;
+ }
elements_needed += elems;
}
if (card->info.type != QETH_CARD_TYPE_IQD)
- rc = qeth_do_send_packet(card, queue, skb, hdr,
+ rc = qeth_do_send_packet(card, queue, new_skb, hdr,
elements_needed, ctx);
else
- rc = qeth_do_send_packet_fast(card, queue, skb, hdr,
+ rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
elements_needed, ctx);
- if (!rc){
+ if (!rc) {
card->stats.tx_packets++;
card->stats.tx_bytes += tx_bytes;
-#ifdef CONFIG_QETH_PERF_STATS
- if (tso_size &&
- !(large_send == QETH_LARGE_SEND_NO)) {
- card->perf_stats.large_send_bytes += tx_bytes;
- card->perf_stats.large_send_cnt++;
- }
- if (nr_frags > 0){
- card->perf_stats.sg_skbs_sent++;
- /* nr_frags + skb->data */
- card->perf_stats.sg_frags_sent +=
- nr_frags + 1;
+ if (new_skb != skb)
+ dev_kfree_skb_any(skb);
+ if (card->options.performance_stats) {
+ if (tso_size &&
+ !(large_send == QETH_LARGE_SEND_NO)) {
+ card->perf_stats.large_send_bytes += tx_bytes;
+ card->perf_stats.large_send_cnt++;
+ }
+ if (nr_frags > 0) {
+ card->perf_stats.sg_skbs_sent++;
+ /* nr_frags + skb->data */
+ card->perf_stats.sg_frags_sent +=
+ nr_frags + 1;
+ }
}
-#endif /* CONFIG_QETH_PERF_STATS */
+ } else {
+ card->stats.tx_dropped++;
+ __qeth_free_new_skb(skb, new_skb);
}
if (ctx != NULL) {
/* drop creator's reference */
qeth_eddp_put_context(ctx);
/* free skb; it's not referenced by a buffer */
- if (rc == 0)
- dev_kfree_skb_any(skb);
-
+ if (!rc)
+ dev_kfree_skb_any(new_skb);
}
return rc;
}
@@ -7338,6 +7344,8 @@ qeth_setrouting_v6(struct qeth_card *card)
QETH_DBF_TEXT(trace,3,"setrtg6");
#ifdef CONFIG_QETH_IPV6
+ if (!qeth_is_supported(card, IPA_IPV6))
+ return 0;
qeth_correct_routing_type(card, &card->options.route6.type,
QETH_PROT_IPV6);
@@ -7876,12 +7884,12 @@ __qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
goto out_remove;
}
- card->state = CARD_STATE_SOFTSETUP;
if ((rc = qeth_init_qdio_queues(card))){
QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
goto out_remove;
}
+ card->state = CARD_STATE_SOFTSETUP;
netif_carrier_on(card->dev);
qeth_set_allowed_threads(card, 0xffffffff, 0);
@@ -8538,34 +8546,44 @@ qeth_ipv6_uninit(void)
static void
qeth_sysfs_unregister(void)
{
+ s390_root_dev_unregister(qeth_root_dev);
qeth_remove_driver_attributes();
ccw_driver_unregister(&qeth_ccw_driver);
ccwgroup_driver_unregister(&qeth_ccwgroup_driver);
- s390_root_dev_unregister(qeth_root_dev);
}
+
/**
* register qeth at sysfs
*/
static int
qeth_sysfs_register(void)
{
- int rc=0;
+ int rc;
rc = ccwgroup_driver_register(&qeth_ccwgroup_driver);
if (rc)
- return rc;
+ goto out;
+
rc = ccw_driver_register(&qeth_ccw_driver);
if (rc)
- return rc;
+ goto out_ccw_driver;
+
rc = qeth_create_driver_attributes();
if (rc)
- return rc;
+ goto out_qeth_attr;
+
qeth_root_dev = s390_root_dev_register("qeth");
- if (IS_ERR(qeth_root_dev)) {
- rc = PTR_ERR(qeth_root_dev);
- return rc;
- }
- return 0;
+ rc = IS_ERR(qeth_root_dev) ? PTR_ERR(qeth_root_dev) : 0;
+ if (!rc)
+ goto out;
+
+ qeth_remove_driver_attributes();
+out_qeth_attr:
+ ccw_driver_unregister(&qeth_ccw_driver);
+out_ccw_driver:
+ ccwgroup_driver_unregister(&qeth_ccwgroup_driver);
+out:
+ return rc;
}
/***
@@ -8574,7 +8592,7 @@ qeth_sysfs_register(void)
static int __init
qeth_init(void)
{
- int rc=0;
+ int rc;
PRINT_INFO("loading %s\n", version);
@@ -8583,20 +8601,26 @@ qeth_init(void)
spin_lock_init(&qeth_notify_lock);
rwlock_init(&qeth_card_list.rwlock);
- if (qeth_register_dbf_views())
+ rc = qeth_register_dbf_views();
+ if (rc)
goto out_err;
- if (qeth_sysfs_register())
- goto out_sysfs;
+
+ rc = qeth_sysfs_register();
+ if (rc)
+ goto out_dbf;
#ifdef CONFIG_QETH_IPV6
- if (qeth_ipv6_init()) {
- PRINT_ERR("Out of memory during ipv6 init.\n");
+ rc = qeth_ipv6_init();
+ if (rc) {
+ PRINT_ERR("Out of memory during ipv6 init code = %d\n", rc);
goto out_sysfs;
}
#endif /* QETH_IPV6 */
- if (qeth_register_notifiers())
+ rc = qeth_register_notifiers();
+ if (rc)
goto out_ipv6;
- if (qeth_create_procfs_entries())
+ rc = qeth_create_procfs_entries();
+ if (rc)
goto out_notifiers;
return rc;
@@ -8606,12 +8630,13 @@ out_notifiers:
out_ipv6:
#ifdef CONFIG_QETH_IPV6
qeth_ipv6_uninit();
-#endif /* QETH_IPV6 */
out_sysfs:
+#endif /* QETH_IPV6 */
qeth_sysfs_unregister();
+out_dbf:
qeth_unregister_dbf_views();
out_err:
- PRINT_ERR("Initialization failed");
+ PRINT_ERR("Initialization failed with code %d\n", rc);
return rc;
}
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 66f2da14e6e..faa768e5925 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -173,7 +173,6 @@ static struct file_operations qeth_procfile_fops = {
#define QETH_PERF_PROCFILE_NAME "qeth_perf"
static struct proc_dir_entry *qeth_perf_procfile;
-#ifdef CONFIG_QETH_PERF_STATS
static int
qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
{
@@ -192,14 +191,21 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
CARD_DDEV_ID(card),
QETH_CARD_IFNAME(card)
);
+ if (!card->options.performance_stats)
+ seq_printf(s, "Performance statistics are deactivated.\n");
seq_printf(s, " Skb's/buffers received : %lu/%u\n"
" Skb's/buffers sent : %lu/%u\n\n",
- card->stats.rx_packets, card->perf_stats.bufs_rec,
- card->stats.tx_packets, card->perf_stats.bufs_sent
+ card->stats.rx_packets -
+ card->perf_stats.initial_rx_packets,
+ card->perf_stats.bufs_rec,
+ card->stats.tx_packets -
+ card->perf_stats.initial_tx_packets,
+ card->perf_stats.bufs_sent
);
seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n"
" Skb's/buffers sent with packing : %u/%u\n\n",
- card->stats.tx_packets - card->perf_stats.skbs_sent_pack,
+ card->stats.tx_packets - card->perf_stats.initial_tx_packets
+ - card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent_pack
@@ -275,11 +281,6 @@ static struct file_operations qeth_perf_procfile_fops = {
.release = seq_release,
};
-#define qeth_perf_procfile_created qeth_perf_procfile
-#else
-#define qeth_perf_procfile_created 1
-#endif /* CONFIG_QETH_PERF_STATS */
-
int __init
qeth_create_procfs_entries(void)
{
@@ -288,15 +289,13 @@ qeth_create_procfs_entries(void)
if (qeth_procfile)
qeth_procfile->proc_fops = &qeth_procfile_fops;
-#ifdef CONFIG_QETH_PERF_STATS
qeth_perf_procfile = create_proc_entry(QETH_PERF_PROCFILE_NAME,
S_IFREG | 0444, NULL);
if (qeth_perf_procfile)
qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops;
-#endif /* CONFIG_QETH_PERF_STATS */
if (qeth_procfile &&
- qeth_perf_procfile_created)
+ qeth_perf_procfile)
return 0;
else
return -ENOMEM;
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index 001497bbea1..5836737ac58 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -743,6 +743,47 @@ static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
qeth_dev_layer2_store);
static ssize_t
+qeth_dev_performance_stats_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct qeth_card *card = dev->driver_data;
+
+ if (!card)
+ return -EINVAL;
+
+ return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
+}
+
+static ssize_t
+qeth_dev_performance_stats_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct qeth_card *card = dev->driver_data;
+ char *tmp;
+ int i;
+
+ if (!card)
+ return -EINVAL;
+
+ i = simple_strtoul(buf, &tmp, 16);
+ if ((i == 0) || (i == 1)) {
+ if (i == card->options.performance_stats)
+ return count;
+ card->options.performance_stats = i;
+ if (i == 0)
+ memset(&card->perf_stats, 0,
+ sizeof(struct qeth_perf_stats));
+ card->perf_stats.initial_rx_packets = card->stats.rx_packets;
+ card->perf_stats.initial_tx_packets = card->stats.tx_packets;
+ } else {
+ PRINT_WARN("performance_stats: write 0 or 1 to this file!\n");
+ return -EINVAL;
+ }
+ return count;
+}
+
+static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
+ qeth_dev_performance_stats_store);
+
+static ssize_t
qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct qeth_card *card = dev->driver_data;
@@ -928,6 +969,7 @@ static struct device_attribute * qeth_device_attrs[] = {
&dev_attr_canonical_macaddr,
&dev_attr_layer2,
&dev_attr_large_send,
+ &dev_attr_performance_stats,
NULL,
};
@@ -1110,12 +1152,12 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
{
const char *start, *end;
char *tmp;
- char buffer[49] = {0, };
+ char buffer[40] = {0, };
start = buf;
/* get address string */
end = strchr(start, '/');
- if (!end || (end-start >= 49)){
+ if (!end || (end - start >= 40)){
PRINT_WARN("Invalid format for ipato_addx/delx. "
"Use <ip addr>/<mask bits>\n");
return -EINVAL;
@@ -1127,7 +1169,12 @@ qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
}
start = end + 1;
*mask_bits = simple_strtoul(start, &tmp, 10);
-
+ if (!strlen(start) ||
+ (tmp == start) ||
+ (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
+ PRINT_WARN("Invalid mask bits for ipato_addx/delx !\n");
+ return -EINVAL;
+ }
return 0;
}
@@ -1698,11 +1745,16 @@ qeth_create_device_attributes(struct device *dev)
sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
+ return ret;
}
- if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group)))
+ if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group))){
+ sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
+ sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
+ sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
+ sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
return ret;
-
- return ret;
+ }
+ return 0;
}
void
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index 593f298142c..14504afb044 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -24,7 +24,7 @@ static inline struct qeth_hdr_tso *
qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
{
QETH_DBF_TEXT(trace, 5, "tsoprsk");
- return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_tso));
+ return qeth_push_skb(card, *skb, sizeof(struct qeth_hdr_tso));
}
/**
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 293bb2fdb1d..2f698763ba5 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -145,8 +145,9 @@ static int opromgetprop(void __user *argp, struct device_node *dp, struct openpr
void *pval;
int len;
- pval = of_get_property(dp, op->oprom_array, &len);
- if (!pval || len <= 0 || len > bufsize)
+ if (!dp ||
+ !(pval = of_get_property(dp, op->oprom_array, &len)) ||
+ len <= 0 || len > bufsize)
return copyout(argp, op, sizeof(int));
memcpy(op->oprom_array, pval, len);
@@ -161,6 +162,8 @@ static int opromnxtprop(void __user *argp, struct device_node *dp, struct openpr
struct property *prop;
int len;
+ if (!dp)
+ return copyout(argp, op, sizeof(int));
if (op->oprom_array[0] == '\0') {
prop = dp->properties;
if (!prop)
@@ -266,9 +269,13 @@ static int oprompci2node(void __user *argp, struct device_node *dp, struct openp
static int oprompath2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data)
{
+ phandle ph = 0;
+
dp = of_find_node_by_path(op->oprom_array);
+ if (dp)
+ ph = dp->node;
data->current_node = dp;
- *((int *)op->oprom_array) = dp->node;
+ *((int *)op->oprom_array) = ph;
op->oprom_size = sizeof(int);
return copyout(argp, op, bufsize + sizeof(int));
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 2d20caf377f..a9bb3cb7e89 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -123,7 +123,8 @@ enum {
ich6_sata = 4,
ich6_sata_ahci = 5,
ich6m_sata_ahci = 6,
- ich8_sata_ahci = 7,
+ ich7m_sata_ahci = 7,
+ ich8_sata_ahci = 8,
/* constants for mapping table */
P0 = 0, /* port 0 */
@@ -188,7 +189,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* 82801GB/GR/GH (ICH7, identical to ICH6) */
{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
- { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
+ { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7m_sata_ahci },
/* Enterprise Southbridge 2 (where's the datasheet?) */
{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
/* SATA Controller 1 IDE (ICH8, no datasheet yet) */
@@ -336,6 +337,24 @@ static const struct piix_map_db ich6m_map_db = {
},
};
+static const struct piix_map_db ich7m_map_db = {
+ .mask = 0x3,
+ .port_enable = 0x5,
+ .present_shift = 4,
+
+ /* Map 01b isn't specified in the doc but some notebooks use
+ * it anyway. ATM, the only case spotted carries subsystem ID
+ * 1025:0107. This is the only difference from ich6m.
+ */
+ .map = {
+ /* PM PS SM SS MAP */
+ { P0, P2, RV, RV }, /* 00b */
+ { IDE, IDE, P1, P3 }, /* 01b */
+ { P0, P2, IDE, IDE }, /* 10b */
+ { RV, RV, RV, RV },
+ },
+};
+
static const struct piix_map_db ich8_map_db = {
.mask = 0x3,
.port_enable = 0x3,
@@ -355,6 +374,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
[ich6_sata] = &ich6_map_db,
[ich6_sata_ahci] = &ich6_map_db,
[ich6m_sata_ahci] = &ich6m_map_db,
+ [ich7m_sata_ahci] = &ich7m_map_db,
[ich8_sata_ahci] = &ich8_map_db,
};
@@ -444,6 +464,18 @@ static struct ata_port_info piix_port_info[] = {
.port_ops = &piix_sata_ops,
},
+ /* ich7m_sata_ahci */
+ {
+ .sht = &piix_sht,
+ .host_flags = ATA_FLAG_SATA |
+ PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
+ PIIX_FLAG_AHCI,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &piix_sata_ops,
+ },
+
/* ich8_sata_ahci */
{
.sht = &piix_sht,
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 73dd6c8deed..427b73a3886 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1256,10 +1256,15 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
swap_buf_le16(id, ATA_ID_WORDS);
/* sanity check */
- if ((class == ATA_DEV_ATA) != (ata_id_is_ata(id) | ata_id_is_cfa(id))) {
- rc = -EINVAL;
- reason = "device reports illegal type";
- goto err_out;
+ rc = -EINVAL;
+ reason = "device reports illegal type";
+
+ if (class == ATA_DEV_ATA) {
+ if (!ata_id_is_ata(id) && !ata_id_is_cfa(id))
+ goto err_out;
+ } else {
+ if (ata_id_is_ata(id))
+ goto err_out;
}
if (post_reset && class == ATA_DEV_ATA) {
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 1053c7c76b7..fa38a413d16 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -1961,8 +1961,7 @@ comreset_retry:
timeout = jiffies + msecs_to_jiffies(200);
do {
sata_scr_read(ap, SCR_STATUS, &sstatus);
- sstatus &= 0x3;
- if ((sstatus == 3) || (sstatus == 0))
+ if (((sstatus & 0x3) == 3) || ((sstatus & 0x3) == 0))
break;
__msleep(1, can_sleep);
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 01d40369a8a..a3727af8b9c 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -77,6 +77,7 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static void vt6420_error_handler(struct ata_port *ap);
static const struct pci_device_id svia_pci_tbl[] = {
+ { 0x1106, 0x0591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
{ 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 },
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index a8ed5a22009..3d355d05461 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -466,7 +466,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
struct scsi_device *sdev = scmd->device;
struct Scsi_Host *shost = sdev->host;
int old_result = scmd->result;
- DECLARE_COMPLETION(done);
+ DECLARE_COMPLETION_ONSTACK(done);
unsigned long timeleft;
unsigned long flags;
unsigned char old_cmnd[MAX_COMMAND_SIZE];
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index cd1979daf2b..851e4839d6d 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -458,11 +458,11 @@ static int pci_siig_setup(struct serial_private *priv,
* growing *huge*, we use this function to collapse some 70 entries
* in the PCI table into one, for sanity's and compactness's sake.
*/
-static unsigned short timedia_single_port[] = {
+static const unsigned short timedia_single_port[] = {
0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0
};
-static unsigned short timedia_dual_port[] = {
+static const unsigned short timedia_dual_port[] = {
0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
@@ -470,35 +470,34 @@ static unsigned short timedia_dual_port[] = {
0xD079, 0
};
-static unsigned short timedia_quad_port[] = {
+static const unsigned short timedia_quad_port[] = {
0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
0xB157, 0
};
-static unsigned short timedia_eight_port[] = {
+static const unsigned short timedia_eight_port[] = {
0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
};
static const struct timedia_struct {
int num;
- unsigned short *ids;
+ const unsigned short *ids;
} timedia_data[] = {
{ 1, timedia_single_port },
{ 2, timedia_dual_port },
{ 4, timedia_quad_port },
- { 8, timedia_eight_port },
- { 0, NULL }
+ { 8, timedia_eight_port }
};
static int pci_timedia_init(struct pci_dev *dev)
{
- unsigned short *ids;
+ const unsigned short *ids;
int i, j;
- for (i = 0; timedia_data[i].num; i++) {
+ for (i = 0; i < ARRAY_SIZE(timedia_data); i++) {
ids = timedia_data[i].ids;
for (j = 0; ids[j]; j++)
if (dev->subsystem_device == ids[j])
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 392bffcf96e..95738a19cde 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1621,7 +1621,7 @@ static struct s3c24xx_uart_info s3c2412_uart_inf = {
static int s3c2412_serial_probe(struct platform_device *dev)
{
dbg("s3c2440_serial_probe: dev=%p\n", dev);
- return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
+ return s3c24xx_serial_probe(dev, &s3c2412_uart_inf);
}
static struct platform_driver s3c2412_serial_drv = {
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 80ef7d48275..372e47f7d59 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -2377,6 +2377,9 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2)
return (port1->iobase == port2->iobase) &&
(port1->hub6 == port2->hub6);
case UPIO_MEM:
+ case UPIO_MEM32:
+ case UPIO_AU:
+ case UPIO_TSI:
return (port1->mapbase == port2->mapbase);
}
return 0;
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 301573373c3..cbede06cac2 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -1579,7 +1579,7 @@ static int __init serial_console_setup(struct console *co, char *options)
h8300_sci_enable(port, sci_enable);
#endif
#elif defined(CONFIG_SUPERH64)
- port->uartclk = current_cpu_info.module_clock * 16;
+ port->uartclk = current_cpu_data.module_clock * 16;
#else
{
struct clk *clk = clk_get("module_clk");
@@ -1720,7 +1720,7 @@ static int __init sci_init(void)
#if defined(__H8300H__) || defined(__H8300S__)
sciport->port.uartclk = CONFIG_CPU_CLOCK;
#elif defined(CONFIG_SUPERH64)
- sciport->port.uartclk = current_cpu_info.module_clock * 16;
+ sciport->port.uartclk = current_cpu_data.module_clock * 16;
#else
struct clk *clk = clk_get("module_clk");
sciport->port.uartclk = clk_get_rate(clk) * 16;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 4fe1bec1c25..30299c620d9 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -117,6 +117,8 @@ struct eth_dev {
struct usb_ep *in_ep, *out_ep, *status_ep;
const struct usb_endpoint_descriptor
*in, *out, *status;
+
+ spinlock_t req_lock;
struct list_head tx_reqs, rx_reqs;
struct net_device *net;
@@ -1066,21 +1068,31 @@ static void eth_reset_config (struct eth_dev *dev)
*/
if (dev->in) {
usb_ep_disable (dev->in_ep);
+ spin_lock(&dev->req_lock);
while (likely (!list_empty (&dev->tx_reqs))) {
req = container_of (dev->tx_reqs.next,
struct usb_request, list);
list_del (&req->list);
+
+ spin_unlock(&dev->req_lock);
usb_ep_free_request (dev->in_ep, req);
+ spin_lock(&dev->req_lock);
}
+ spin_unlock(&dev->req_lock);
}
if (dev->out) {
usb_ep_disable (dev->out_ep);
+ spin_lock(&dev->req_lock);
while (likely (!list_empty (&dev->rx_reqs))) {
req = container_of (dev->rx_reqs.next,
struct usb_request, list);
list_del (&req->list);
+
+ spin_unlock(&dev->req_lock);
usb_ep_free_request (dev->out_ep, req);
+ spin_lock(&dev->req_lock);
}
+ spin_unlock(&dev->req_lock);
}
if (dev->status) {
@@ -1659,9 +1671,9 @@ enomem:
if (retval) {
DEBUG (dev, "rx submit --> %d\n", retval);
dev_kfree_skb_any (skb);
- spin_lock (&dev->lock);
+ spin_lock(&dev->req_lock);
list_add (&req->list, &dev->rx_reqs);
- spin_unlock (&dev->lock);
+ spin_unlock(&dev->req_lock);
}
return retval;
}
@@ -1730,8 +1742,9 @@ quiesce:
dev_kfree_skb_any (skb);
if (!netif_running (dev->net)) {
clean:
- /* nobody reading rx_reqs, so no dev->lock */
+ spin_lock(&dev->req_lock);
list_add (&req->list, &dev->rx_reqs);
+ spin_unlock(&dev->req_lock);
req = NULL;
}
if (req)
@@ -1782,15 +1795,18 @@ static int alloc_requests (struct eth_dev *dev, unsigned n, gfp_t gfp_flags)
{
int status;
+ spin_lock(&dev->req_lock);
status = prealloc (&dev->tx_reqs, dev->in_ep, n, gfp_flags);
if (status < 0)
goto fail;
status = prealloc (&dev->rx_reqs, dev->out_ep, n, gfp_flags);
if (status < 0)
goto fail;
- return 0;
+ goto done;
fail:
DEBUG (dev, "can't alloc requests\n");
+done:
+ spin_unlock(&dev->req_lock);
return status;
}
@@ -1800,21 +1816,21 @@ static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags)
unsigned long flags;
/* fill unused rxq slots with some skb */
- spin_lock_irqsave (&dev->lock, flags);
+ spin_lock_irqsave(&dev->req_lock, flags);
while (!list_empty (&dev->rx_reqs)) {
req = container_of (dev->rx_reqs.next,
struct usb_request, list);
list_del_init (&req->list);
- spin_unlock_irqrestore (&dev->lock, flags);
+ spin_unlock_irqrestore(&dev->req_lock, flags);
if (rx_submit (dev, req, gfp_flags) < 0) {
defer_kevent (dev, WORK_RX_MEMORY);
return;
}
- spin_lock_irqsave (&dev->lock, flags);
+ spin_lock_irqsave(&dev->req_lock, flags);
}
- spin_unlock_irqrestore (&dev->lock, flags);
+ spin_unlock_irqrestore(&dev->req_lock, flags);
}
static void eth_work (void *_dev)
@@ -1848,9 +1864,9 @@ static void tx_complete (struct usb_ep *ep, struct usb_request *req)
}
dev->stats.tx_packets++;
- spin_lock (&dev->lock);
+ spin_lock(&dev->req_lock);
list_add (&req->list, &dev->tx_reqs);
- spin_unlock (&dev->lock);
+ spin_unlock(&dev->req_lock);
dev_kfree_skb_any (skb);
atomic_dec (&dev->tx_qlen);
@@ -1896,12 +1912,12 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
/* ignores USB_CDC_PACKET_TYPE_DIRECTED */
}
- spin_lock_irqsave (&dev->lock, flags);
+ spin_lock_irqsave(&dev->req_lock, flags);
req = container_of (dev->tx_reqs.next, struct usb_request, list);
list_del (&req->list);
if (list_empty (&dev->tx_reqs))
netif_stop_queue (net);
- spin_unlock_irqrestore (&dev->lock, flags);
+ spin_unlock_irqrestore(&dev->req_lock, flags);
/* no buffer copies needed, unless the network stack did it
* or the hardware can't use skb buffers.
@@ -1955,11 +1971,11 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
drop:
dev->stats.tx_dropped++;
dev_kfree_skb_any (skb);
- spin_lock_irqsave (&dev->lock, flags);
+ spin_lock_irqsave(&dev->req_lock, flags);
if (list_empty (&dev->tx_reqs))
netif_start_queue (net);
list_add (&req->list, &dev->tx_reqs);
- spin_unlock_irqrestore (&dev->lock, flags);
+ spin_unlock_irqrestore(&dev->req_lock, flags);
}
return 0;
}
@@ -2378,6 +2394,7 @@ autoconf_fail:
return status;
dev = netdev_priv(net);
spin_lock_init (&dev->lock);
+ spin_lock_init (&dev->req_lock);
INIT_WORK (&dev->work, eth_work, dev);
INIT_LIST_HEAD (&dev->tx_reqs);
INIT_LIST_HEAD (&dev->rx_reqs);
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 66c3f61bc9d..431e8f31f1a 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -372,7 +372,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first)
* need to change any toggles in this URB */
td = list_entry(urbp->td_list.next, struct uhci_td, list);
if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) {
- td = list_entry(urbp->td_list.next, struct uhci_td,
+ td = list_entry(urbp->td_list.prev, struct uhci_td,
list);
toggle = uhci_toggle(td_token(td)) ^ 1;
@@ -1348,7 +1348,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
}
uhci_giveback_urb(uhci, qh, urb, regs);
- if (status < 0)
+ if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC)
break;
}
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 8ea9c915fbf..a2c56b2de58 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1411,17 +1411,54 @@ void hid_init_reports(struct hid_device *hid)
warn("timeout initializing reports");
}
+#define USB_VENDOR_ID_GTCO 0x078c
+#define USB_DEVICE_ID_GTCO_90 0x0090
+#define USB_DEVICE_ID_GTCO_100 0x0100
+#define USB_DEVICE_ID_GTCO_101 0x0101
+#define USB_DEVICE_ID_GTCO_103 0x0103
+#define USB_DEVICE_ID_GTCO_104 0x0104
+#define USB_DEVICE_ID_GTCO_105 0x0105
+#define USB_DEVICE_ID_GTCO_106 0x0106
+#define USB_DEVICE_ID_GTCO_107 0x0107
+#define USB_DEVICE_ID_GTCO_108 0x0108
+#define USB_DEVICE_ID_GTCO_200 0x0200
+#define USB_DEVICE_ID_GTCO_201 0x0201
+#define USB_DEVICE_ID_GTCO_202 0x0202
+#define USB_DEVICE_ID_GTCO_203 0x0203
+#define USB_DEVICE_ID_GTCO_204 0x0204
+#define USB_DEVICE_ID_GTCO_205 0x0205
+#define USB_DEVICE_ID_GTCO_206 0x0206
+#define USB_DEVICE_ID_GTCO_207 0x0207
+#define USB_DEVICE_ID_GTCO_300 0x0300
+#define USB_DEVICE_ID_GTCO_301 0x0301
+#define USB_DEVICE_ID_GTCO_302 0x0302
+#define USB_DEVICE_ID_GTCO_303 0x0303
+#define USB_DEVICE_ID_GTCO_304 0x0304
+#define USB_DEVICE_ID_GTCO_305 0x0305
+#define USB_DEVICE_ID_GTCO_306 0x0306
+#define USB_DEVICE_ID_GTCO_307 0x0307
+#define USB_DEVICE_ID_GTCO_308 0x0308
+#define USB_DEVICE_ID_GTCO_309 0x0309
+#define USB_DEVICE_ID_GTCO_400 0x0400
+#define USB_DEVICE_ID_GTCO_401 0x0401
+#define USB_DEVICE_ID_GTCO_402 0x0402
+#define USB_DEVICE_ID_GTCO_403 0x0403
+#define USB_DEVICE_ID_GTCO_404 0x0404
+#define USB_DEVICE_ID_GTCO_405 0x0405
+#define USB_DEVICE_ID_GTCO_500 0x0500
+#define USB_DEVICE_ID_GTCO_501 0x0501
+#define USB_DEVICE_ID_GTCO_502 0x0502
+#define USB_DEVICE_ID_GTCO_503 0x0503
+#define USB_DEVICE_ID_GTCO_504 0x0504
+#define USB_DEVICE_ID_GTCO_1000 0x1000
+#define USB_DEVICE_ID_GTCO_1001 0x1001
+#define USB_DEVICE_ID_GTCO_1002 0x1002
+#define USB_DEVICE_ID_GTCO_1003 0x1003
+#define USB_DEVICE_ID_GTCO_1004 0x1004
+#define USB_DEVICE_ID_GTCO_1005 0x1005
+#define USB_DEVICE_ID_GTCO_1006 0x1006
+
#define USB_VENDOR_ID_WACOM 0x056a
-#define USB_DEVICE_ID_WACOM_PENPARTNER 0x0000
-#define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010
-#define USB_DEVICE_ID_WACOM_INTUOS 0x0020
-#define USB_DEVICE_ID_WACOM_PL 0x0030
-#define USB_DEVICE_ID_WACOM_INTUOS2 0x0040
-#define USB_DEVICE_ID_WACOM_VOLITO 0x0060
-#define USB_DEVICE_ID_WACOM_PTU 0x0003
-#define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0
-#define USB_DEVICE_ID_WACOM_CINTIQ 0x003F
-#define USB_DEVICE_ID_WACOM_DTF 0x00C0
#define USB_VENDOR_ID_ACECAD 0x0460
#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
@@ -1588,6 +1625,51 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE },
@@ -1617,49 +1699,6 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 7, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 8, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 9, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 5, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 6, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 5, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_DTF + 3, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE },
@@ -1778,6 +1817,10 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
char *rdesc;
int n, len, insize = 0;
+ /* Ignore all Wacom devices */
+ if (dev->descriptor.idVendor == USB_VENDOR_ID_WACOM)
+ return NULL;
+
for (n = 0; hid_blacklist[n].idVendor; n++)
if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
(hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct)))
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c
index 3b175aa482c..a338bf4c2d7 100644
--- a/drivers/usb/input/usbtouchscreen.c
+++ b/drivers/usb/input/usbtouchscreen.c
@@ -286,7 +286,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
{
*x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F);
- *x = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F);
+ *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F);
*press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F);
*touch = ~pkt[7] & 0x20;
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index 575a4e672e9..7b45fd3de91 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -810,12 +810,9 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
if (yld == NULL)
return err;
- if (yld->urb_irq) {
- usb_kill_urb(yld->urb_irq);
- usb_free_urb(yld->urb_irq);
- }
- if (yld->urb_ctl)
- usb_free_urb(yld->urb_ctl);
+ usb_kill_urb(yld->urb_irq); /* parameter validation in core/urb */
+ usb_kill_urb(yld->urb_ctl); /* parameter validation in core/urb */
+
if (yld->idev) {
if (err)
input_free_device(yld->idev);
@@ -831,6 +828,9 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
if (yld->irq_data)
usb_buffer_free(yld->udev, USB_PKT_LEN,
yld->irq_data, yld->irq_dma);
+
+ usb_free_urb(yld->urb_irq); /* parameter validation in core/urb */
+ usb_free_urb(yld->urb_ctl); /* parameter validation in core/urb */
kfree(yld);
return err;
}
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 738bd7c7451..e16582f3733 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -3435,6 +3435,8 @@ static void sisusb_disconnect(struct usb_interface *intf)
static struct usb_device_id sisusb_table [] = {
{ USB_DEVICE(0x0711, 0x0900) },
+ { USB_DEVICE(0x0711, 0x0901) },
+ { USB_DEVICE(0x0711, 0x0902) },
{ USB_DEVICE(0x182d, 0x021c) },
{ USB_DEVICE(0x182d, 0x0269) },
{ }
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
index a54752ce149..006438069b6 100644
--- a/drivers/usb/net/pegasus.h
+++ b/drivers/usb/net/pegasus.h
@@ -131,6 +131,7 @@ struct usb_eth_dev {
#define VENDOR_COREGA 0x07aa
#define VENDOR_DLINK 0x2001
#define VENDOR_ELCON 0x0db7
+#define VENDOR_ELECOM 0x056e
#define VENDOR_ELSA 0x05cc
#define VENDOR_GIGABYTE 0x1044
#define VENDOR_HAWKING 0x0e66
@@ -233,6 +234,8 @@ PEGASUS_DEV( "D-Link DSB-650", VENDOR_DLINK, 0xabc1,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "GOLDPFEIL USB Adapter", VENDOR_ELCON, 0x0002,
DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
+PEGASUS_DEV( "ELECOM USB Ethernet LD-USB20", VENDOR_ELECOM, 0x4010,
+ DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "EasiDock Ethernet", VENDOR_MOBILITY, 0x0304,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index bd09232ce13..a72685b9606 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -972,6 +972,7 @@ static void rtl8150_disconnect(struct usb_interface *intf)
if (dev) {
set_bit(RTL8150_UNPLUG, &dev->flags);
tasklet_disable(&dev->tl);
+ tasklet_kill(&dev->tl);
unregister_netdev(dev->netdev);
unlink_all_urbs(dev);
free_all_urbs(dev);
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 15945e806f0..c6115aa1b44 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -506,6 +506,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
{ USB_DEVICE(TESTO_VID, TESTO_USB_INTERFACE_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_GAMMA_SCOUT_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 8888cd80a49..77299996f7e 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -467,6 +467,11 @@
#define TESTO_VID 0x128D
#define TESTO_USB_INTERFACE_PID 0x0001
+/*
+ * Gamma Scout (http://gamma-scout.com/). Submitted by rsc@runtux.com.
+ */
+#define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 12c1694d322..e06a41bd0f3 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -464,8 +464,10 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int
length += sprintf (page+length, " path:%s", tmp);
length += sprintf (page+length, "\n");
- if ((length + begin) > (off + count))
+ if ((length + begin) > (off + count)) {
+ usb_serial_put(serial);
goto done;
+ }
if ((length + begin) < off) {
begin += length;
length = 0;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 4a803d69fa3..b130e170b4a 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -241,16 +241,6 @@ UNUSUAL_DEV( 0x0482, 0x0103, 0x0100, 0x0100,
"Finecam S5",
US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY),
-/* Patch for Kyocera Finecam L3
- * Submitted by Michael Krauth <michael.krauth@web.de>
- * and Alessandro Fracchetti <al.fracchetti@tin.it>
- */
-UNUSUAL_DEV( 0x0482, 0x0105, 0x0100, 0x0100,
- "Kyocera",
- "Finecam L3",
- US_SC_SCSI, US_PR_BULK, NULL,
- US_FL_FIX_INQUIRY),
-
/* Reported by Paul Stewart <stewart@wetlogic.net>
* This entry is needed because the device reports Sub=ff */
UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001,
@@ -599,6 +589,13 @@ UNUSUAL_DEV( 0x054c, 0x0099, 0x0000, 0x9999,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
+/* floppy reports multiple luns */
+UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210,
+ "SAMSUNG",
+ "SFD-321U [FW 0C]",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_SINGLE_LUN ),
+
UNUSUAL_DEV( 0x057b, 0x0000, 0x0000, 0x0299,
"Y-E Data",
@@ -1257,6 +1254,13 @@ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_NO_WP_DETECT ),
+/* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */
+UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000,
+ "Sony Ericsson",
+ "M600i",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
/* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
* Tested on hardware version 1.10.
* Entry is needed only for the initializer function override.
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 3e827e04a2a..276a21530b9 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1801,10 +1801,14 @@ static struct backlight_properties aty128_bl_data = {
static void aty128_bl_set_power(struct fb_info *info, int power)
{
mutex_lock(&info->bl_mutex);
- up(&info->bl_dev->sem);
- info->bl_dev->props->power = power;
- __aty128_bl_update_status(info->bl_dev);
- down(&info->bl_dev->sem);
+
+ if (info->bl_dev) {
+ down(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __aty128_bl_update_status(info->bl_dev);
+ up(&info->bl_dev->sem);
+ }
+
mutex_unlock(&info->bl_mutex);
}
@@ -1828,7 +1832,7 @@ static void aty128_bl_init(struct aty128fb_par *par)
bd = backlight_device_register(name, par, &aty128_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
- printk("aty128: Backlight registration failed\n");
+ printk(KERN_WARNING "aty128: Backlight registration failed\n");
goto error;
}
@@ -1839,11 +1843,11 @@ static void aty128_bl_init(struct aty128fb_par *par)
219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
mutex_unlock(&info->bl_mutex);
- up(&bd->sem);
+ down(&bd->sem);
bd->props->brightness = aty128_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK;
bd->props->update_status(bd);
- down(&bd->sem);
+ up(&bd->sem);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex);
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 053ff63365b..19a71f04578 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2200,10 +2200,14 @@ static struct backlight_properties aty_bl_data = {
static void aty_bl_set_power(struct fb_info *info, int power)
{
mutex_lock(&info->bl_mutex);
- up(&info->bl_dev->sem);
- info->bl_dev->props->power = power;
- __aty_bl_update_status(info->bl_dev);
- down(&info->bl_dev->sem);
+
+ if (info->bl_dev) {
+ down(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __aty_bl_update_status(info->bl_dev);
+ up(&info->bl_dev->sem);
+ }
+
mutex_unlock(&info->bl_mutex);
}
@@ -2223,7 +2227,7 @@ static void aty_bl_init(struct atyfb_par *par)
bd = backlight_device_register(name, par, &aty_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
- printk("aty: Backlight registration failed\n");
+ printk(KERN_WARNING "aty: Backlight registration failed\n");
goto error;
}
@@ -2234,11 +2238,11 @@ static void aty_bl_init(struct atyfb_par *par)
0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
mutex_unlock(&info->bl_mutex);
- up(&bd->sem);
+ down(&bd->sem);
bd->props->brightness = aty_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK;
bd->props->update_status(bd);
- down(&bd->sem);
+ up(&bd->sem);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex);
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 1755dddf189..585eb7b9e63 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -195,11 +195,11 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
mutex_unlock(&rinfo->info->bl_mutex);
- up(&bd->sem);
+ down(&bd->sem);
bd->props->brightness = radeon_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK;
bd->props->update_status(bd);
- down(&bd->sem);
+ up(&bd->sem);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex);
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index b45f577094a..5b75ae4e945 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -113,10 +113,14 @@ static struct backlight_properties nvidia_bl_data = {
void nvidia_bl_set_power(struct fb_info *info, int power)
{
mutex_lock(&info->bl_mutex);
- up(&info->bl_dev->sem);
- info->bl_dev->props->power = power;
- __nvidia_bl_update_status(info->bl_dev);
- down(&info->bl_dev->sem);
+
+ if (info->bl_dev) {
+ down(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __nvidia_bl_update_status(info->bl_dev);
+ up(&info->bl_dev->sem);
+ }
+
mutex_unlock(&info->bl_mutex);
}
@@ -140,7 +144,7 @@ void nvidia_bl_init(struct nvidia_par *par)
bd = backlight_device_register(name, par, &nvidia_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
- printk("nvidia: Backlight registration failed\n");
+ printk(KERN_WARNING "nvidia: Backlight registration failed\n");
goto error;
}
@@ -151,11 +155,11 @@ void nvidia_bl_init(struct nvidia_par *par)
0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
mutex_unlock(&info->bl_mutex);
- up(&bd->sem);
+ down(&bd->sem);
bd->props->brightness = nvidia_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK;
bd->props->update_status(bd);
- down(&bd->sem);
+ up(&bd->sem);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex);
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 76fc9d355eb..8ddb47a56b0 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -355,10 +355,14 @@ static struct backlight_properties riva_bl_data = {
static void riva_bl_set_power(struct fb_info *info, int power)
{
mutex_lock(&info->bl_mutex);
- up(&info->bl_dev->sem);
- info->bl_dev->props->power = power;
- __riva_bl_update_status(info->bl_dev);
- down(&info->bl_dev->sem);
+
+ if (info->bl_dev) {
+ down(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __riva_bl_update_status(info->bl_dev);
+ up(&info->bl_dev->sem);
+ }
+
mutex_unlock(&info->bl_mutex);
}
@@ -382,7 +386,7 @@ static void riva_bl_init(struct riva_par *par)
bd = backlight_device_register(name, par, &riva_bl_data);
if (IS_ERR(bd)) {
info->bl_dev = NULL;
- printk("riva: Backlight registration failed\n");
+ printk(KERN_WARNING "riva: Backlight registration failed\n");
goto error;
}
@@ -393,11 +397,11 @@ static void riva_bl_init(struct riva_par *par)
0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
mutex_unlock(&info->bl_mutex);
- up(&bd->sem);
+ down(&bd->sem);
bd->props->brightness = riva_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK;
bd->props->update_status(bd);
- down(&bd->sem);
+ up(&bd->sem);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex);