aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/pktcdvd.c35
-rw-r--r--drivers/char/tty_io.c7
-rw-r--r--drivers/char/tty_ioctl.c6
-rw-r--r--drivers/gpu/drm/drm_irq.c20
-rw-r--r--drivers/gpu/drm/drm_lock.c33
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c196
-rw-r--r--drivers/gpu/drm/radeon/r300_reg.h5
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c38
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h19
-rw-r--r--drivers/i2c/i2c-core.c18
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c2
-rw-r--r--drivers/input/keyboard/bf54x-keys.c2
-rw-r--r--drivers/net/Kconfig6
-rw-r--r--drivers/net/atl1e/atl1e_main.c3
-rw-r--r--drivers/net/atlx/atl1.c1
-rw-r--r--drivers/net/e100.c4
-rw-r--r--drivers/net/e1000/e1000_param.c81
-rw-r--r--drivers/net/forcedeth.c4
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c8
-rw-r--r--drivers/net/fs_enet/mac-scc.c8
-rw-r--r--drivers/net/gianfar.c22
-rw-r--r--drivers/net/gianfar.h1
-rw-r--r--drivers/net/ibm_newemac/core.c6
-rw-r--r--drivers/net/ibmveth.c5
-rw-r--r--drivers/net/igb/e1000_82575.c1
-rw-r--r--drivers/net/igb/e1000_hw.h1
-rw-r--r--drivers/net/igb/igb_ethtool.c17
-rw-r--r--drivers/net/igb/igb_main.c25
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c8
-rw-r--r--drivers/net/mv643xx_eth.c35
-rw-r--r--drivers/net/myri10ge/myri10ge.c2
-rw-r--r--drivers/net/r8169.c2
-rw-r--r--drivers/net/skfp/ess.c6
-rw-r--r--drivers/net/smc91x.c2
-rw-r--r--drivers/net/usb/hso.c3
-rw-r--r--drivers/net/usb/mcs7830.c47
-rw-r--r--drivers/net/wan/sbni.c8
-rw-r--r--drivers/net/wd.c2
-rw-r--r--drivers/net/wireless/ath5k/base.c23
-rw-r--r--drivers/net/wireless/ath5k/base.h1
-rw-r--r--drivers/net/wireless/atmel.c51
-rw-r--r--drivers/oprofile/cpu_buffer.c4
-rw-r--r--drivers/oprofile/event_buffer.c2
-rw-r--r--drivers/s390/block/dcssblk.c5
-rw-r--r--drivers/s390/net/claw.c79
-rw-r--r--drivers/s390/net/ctcm_fsms.c56
-rw-r--r--drivers/s390/net/ctcm_main.c24
-rw-r--r--drivers/s390/net/ctcm_main.h9
-rw-r--r--drivers/s390/net/ctcm_mpc.c46
-rw-r--r--drivers/s390/net/lcs.c3
-rw-r--r--drivers/s390/net/qeth_core.h1
-rw-r--r--drivers/s390/net/qeth_core_main.c2
-rw-r--r--drivers/s390/net/qeth_l2_main.c27
-rw-r--r--drivers/s390/net/qeth_l3_sys.c2
-rw-r--r--drivers/scsi/sg.c17
-rw-r--r--drivers/serial/bfin_5xx.c2
-rw-r--r--drivers/video/bf54x-lq043fb.c2
-rw-r--r--drivers/watchdog/Kconfig24
-rw-r--r--drivers/watchdog/Makefile3
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c2
-rw-r--r--drivers/watchdog/hpwdt.c93
-rw-r--r--drivers/watchdog/mpc8xx_wdt.c170
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c11
-rw-r--r--drivers/watchdog/pc87413_wdt.c1
-rw-r--r--drivers/watchdog/rc32434_wdt.c344
-rw-r--r--drivers/watchdog/rdc321x_wdt.c285
-rw-r--r--drivers/watchdog/s3c2410_wdt.c16
67 files changed, 1372 insertions, 622 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 158eed4d516..29b7a648cc6 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -49,7 +49,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/file.h>
@@ -2798,14 +2797,9 @@ out_mem:
return ret;
}
-static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
- struct inode *inode = file->f_path.dentry->d_inode;
- struct pktcdvd_device *pd;
- long ret;
-
- lock_kernel();
- pd = inode->i_bdev->bd_disk->private_data;
+ struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode));
@@ -2818,8 +2812,7 @@ static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case CDROM_LAST_WRITTEN:
case CDROM_SEND_PACKET:
case SCSI_IOCTL_SEND_COMMAND:
- ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
- break;
+ return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
case CDROMEJECT:
/*
@@ -2828,15 +2821,14 @@ static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
*/
if (pd->refcnt == 1)
pkt_lock_door(pd, 0);
- ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
- break;
+ return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
default:
VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd);
- ret = -ENOTTY;
+ return -ENOTTY;
}
- unlock_kernel();
- return ret;
+
+ return 0;
}
static int pkt_media_changed(struct gendisk *disk)
@@ -2858,7 +2850,7 @@ static struct block_device_operations pktcdvd_ops = {
.owner = THIS_MODULE,
.open = pkt_open,
.release = pkt_close,
- .unlocked_ioctl = pkt_ioctl,
+ .ioctl = pkt_ioctl,
.media_changed = pkt_media_changed,
};
@@ -3023,8 +3015,7 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
mutex_unlock(&ctl_mutex);
}
-static long pkt_ctl_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
struct pkt_ctrl_command ctrl_cmd;
@@ -3041,22 +3032,16 @@ static long pkt_ctl_ioctl(struct file *file, unsigned int cmd,
case PKT_CTRL_CMD_SETUP:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- lock_kernel();
ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev);
ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev);
- unlock_kernel();
break;
case PKT_CTRL_CMD_TEARDOWN:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- lock_kernel();
ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev));
- unlock_kernel();
break;
case PKT_CTRL_CMD_STATUS:
- lock_kernel();
pkt_get_status(&ctrl_cmd);
- unlock_kernel();
break;
default:
return -ENOTTY;
@@ -3069,7 +3054,7 @@ static long pkt_ctl_ioctl(struct file *file, unsigned int cmd,
static const struct file_operations pkt_ctl_fops = {
- .unlocked_ioctl = pkt_ctl_ioctl,
+ .ioctl = pkt_ctl_ioctl,
.owner = THIS_MODULE,
};
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index a27160ba21d..daeb8f76697 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2498,7 +2498,7 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
/**
* tty_do_resize - resize event
* @tty: tty being resized
- * @real_tty: real tty (if using a pty/tty pair)
+ * @real_tty: real tty (not the same as tty if using a pty/tty pair)
* @rows: rows (character)
* @cols: cols (character)
*
@@ -2512,7 +2512,8 @@ int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
struct pid *pgrp, *rpgrp;
unsigned long flags;
- mutex_lock(&tty->termios_mutex);
+ /* For a PTY we need to lock the tty side */
+ mutex_lock(&real_tty->termios_mutex);
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
goto done;
/* Get the PID values and reference them so we can
@@ -2533,7 +2534,7 @@ int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
tty->winsize = *ws;
real_tty->winsize = *ws;
done:
- mutex_unlock(&tty->termios_mutex);
+ mutex_unlock(&real_tty->termios_mutex);
return 0;
}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index ea9fc5d03b9..bf34e459742 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -937,12 +937,14 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
return 0;
#endif
case TIOCGSOFTCAR:
- return put_user(C_CLOCAL(tty) ? 1 : 0,
+ /* FIXME: for correctness we may need to take the termios
+ lock here - review */
+ return put_user(C_CLOCAL(real_tty) ? 1 : 0,
(int __user *)arg);
case TIOCSSOFTCAR:
if (get_user(arg, (unsigned int __user *) arg))
return -EFAULT;
- return tty_change_softcar(tty, arg);
+ return tty_change_softcar(real_tty, arg);
default:
return -ENOIOCTLCMD;
}
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 089c015c01d..53f0e5af1cc 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -400,27 +400,31 @@ static void drm_locked_tasklet_func(unsigned long data)
{
struct drm_device *dev = (struct drm_device *)data;
unsigned long irqflags;
-
+ void (*tasklet_func)(struct drm_device *);
+
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
+ tasklet_func = dev->locked_tasklet_func;
+ spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
- if (!dev->locked_tasklet_func ||
+ if (!tasklet_func ||
!drm_lock_take(&dev->lock,
DRM_KERNEL_CONTEXT)) {
- spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
return;
}
dev->lock.lock_time = jiffies;
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
- dev->locked_tasklet_func(dev);
+ spin_lock_irqsave(&dev->tasklet_lock, irqflags);
+ tasklet_func = dev->locked_tasklet_func;
+ dev->locked_tasklet_func = NULL;
+ spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
+
+ if (tasklet_func != NULL)
+ tasklet_func(dev);
drm_lock_free(&dev->lock,
DRM_KERNEL_CONTEXT);
-
- dev->locked_tasklet_func = NULL;
-
- spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
}
/**
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index 0998723cde7..a4caf95485d 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -105,14 +105,19 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
ret ? "interrupted" : "has lock");
if (ret) return ret;
- sigemptyset(&dev->sigmask);
- sigaddset(&dev->sigmask, SIGSTOP);
- sigaddset(&dev->sigmask, SIGTSTP);
- sigaddset(&dev->sigmask, SIGTTIN);
- sigaddset(&dev->sigmask, SIGTTOU);
- dev->sigdata.context = lock->context;
- dev->sigdata.lock = dev->lock.hw_lock;
- block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
+ /* don't set the block all signals on the master process for now
+ * really probably not the correct answer but lets us debug xkb
+ * xserver for now */
+ if (!file_priv->master) {
+ sigemptyset(&dev->sigmask);
+ sigaddset(&dev->sigmask, SIGSTOP);
+ sigaddset(&dev->sigmask, SIGTSTP);
+ sigaddset(&dev->sigmask, SIGTTIN);
+ sigaddset(&dev->sigmask, SIGTTOU);
+ dev->sigdata.context = lock->context;
+ dev->sigdata.lock = dev->lock.hw_lock;
+ block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
+ }
if (dev->driver->dma_ready && (lock->flags & _DRM_LOCK_READY))
dev->driver->dma_ready(dev);
@@ -150,6 +155,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
struct drm_lock *lock = data;
unsigned long irqflags;
+ void (*tasklet_func)(struct drm_device *);
if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
@@ -158,14 +164,11 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
}
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
-
- if (dev->locked_tasklet_func) {
- dev->locked_tasklet_func(dev);
-
- dev->locked_tasklet_func = NULL;
- }
-
+ tasklet_func = dev->locked_tasklet_func;
+ dev->locked_tasklet_func = NULL;
spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
+ if (tasklet_func != NULL)
+ tasklet_func(dev);
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
index 702df45320f..4b27d9abb7b 100644
--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -77,6 +77,9 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
return -EFAULT;
}
+ box.x2--; /* Hardware expects inclusive bottom-right corner */
+ box.y2--;
+
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
box.x1 = (box.x1) &
R300_CLIPRECT_MASK;
@@ -95,8 +98,8 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
R300_CLIPRECT_MASK;
box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) &
R300_CLIPRECT_MASK;
-
}
+
OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
(box.y1 << R300_CLIPRECT_Y_SHIFT));
OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
@@ -136,6 +139,18 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
ADVANCE_RING();
}
+ /* flus cache and wait idle clean after cliprect change */
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(R300_RB3D_DC_FLUSH);
+ ADVANCE_RING();
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
+ ADVANCE_RING();
+ /* set flush flag */
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED;
+
return 0;
}
@@ -166,13 +181,13 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(0x21DC, 1);
ADD_RANGE(R300_VAP_UNKNOWN_221C, 1);
ADD_RANGE(R300_VAP_CLIP_X_0, 4);
- ADD_RANGE(R300_VAP_PVS_WAITIDLE, 1);
+ ADD_RANGE(R300_VAP_PVS_STATE_FLUSH_REG, 1);
ADD_RANGE(R300_VAP_UNKNOWN_2288, 1);
ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2);
ADD_RANGE(R300_VAP_PVS_CNTL_1, 3);
ADD_RANGE(R300_GB_ENABLE, 1);
ADD_RANGE(R300_GB_MSPOS0, 5);
- ADD_RANGE(R300_TX_CNTL, 1);
+ ADD_RANGE(R300_TX_INVALTAGS, 1);
ADD_RANGE(R300_TX_ENABLE, 1);
ADD_RANGE(0x4200, 4);
ADD_RANGE(0x4214, 1);
@@ -388,15 +403,28 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
if (sz * 16 > cmdbuf->bufsz)
return -EINVAL;
- BEGIN_RING(5 + sz * 4);
- /* Wait for VAP to come to senses.. */
- /* there is no need to emit it multiple times, (only once before VAP is programmed,
- but this optimization is for later */
- OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0);
+ /* VAP is very sensitive so we purge cache before we program it
+ * and we also flush its state before & after */
+ BEGIN_RING(6);
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(R300_RB3D_DC_FLUSH);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
+ OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0));
+ OUT_RING(0);
+ ADVANCE_RING();
+ /* set flush flag */
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED;
+
+ BEGIN_RING(3 + sz * 4);
OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
+ ADVANCE_RING();
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0));
+ OUT_RING(0);
ADVANCE_RING();
cmdbuf->buf += sz * 16;
@@ -424,6 +452,15 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
OUT_RING_TABLE((int *)cmdbuf->buf, 8);
ADVANCE_RING();
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(R300_RB3D_DC_FLUSH);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
+ ADVANCE_RING();
+ /* set flush flag */
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED;
+
cmdbuf->buf += 8 * 4;
cmdbuf->bufsz -= 8 * 4;
@@ -543,22 +580,23 @@ static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
return 0;
}
-static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
- drm_radeon_kcmd_buffer_t *cmdbuf)
+static __inline__ int r300_emit_draw_indx_2(drm_radeon_private_t *dev_priv,
+ drm_radeon_kcmd_buffer_t *cmdbuf)
{
- u32 *cmd = (u32 *) cmdbuf->buf;
- int count, ret;
+ u32 *cmd;
+ int count;
+ int expected_count;
RING_LOCALS;
- count=(cmd[0]>>16) & 0x3fff;
+ cmd = (u32 *) cmdbuf->buf;
+ count = (cmd[0]>>16) & 0x3fff;
+ expected_count = cmd[1] >> 16;
+ if (!(cmd[1] & R300_VAP_VF_CNTL__INDEX_SIZE_32bit))
+ expected_count = (expected_count+1)/2;
- if ((cmd[1] & 0x8000ffff) != 0x80000810) {
- DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
- return -EINVAL;
- }
- ret = !radeon_check_offset(dev_priv, cmd[2]);
- if (ret) {
- DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+ if (count && count != expected_count) {
+ DRM_ERROR("3D_DRAW_INDX_2: packet size %i, expected %i\n",
+ count, expected_count);
return -EINVAL;
}
@@ -570,6 +608,50 @@ static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
cmdbuf->buf += (count+2)*4;
cmdbuf->bufsz -= (count+2)*4;
+ if (!count) {
+ drm_r300_cmd_header_t header;
+
+ if (cmdbuf->bufsz < 4*4 + sizeof(header)) {
+ DRM_ERROR("3D_DRAW_INDX_2: expect subsequent INDX_BUFFER, but stream is too short.\n");
+ return -EINVAL;
+ }
+
+ header.u = *(unsigned int *)cmdbuf->buf;
+
+ cmdbuf->buf += sizeof(header);
+ cmdbuf->bufsz -= sizeof(header);
+ cmd = (u32 *) cmdbuf->buf;
+
+ if (header.header.cmd_type != R300_CMD_PACKET3 ||
+ header.packet3.packet != R300_CMD_PACKET3_RAW ||
+ cmd[0] != CP_PACKET3(RADEON_CP_INDX_BUFFER, 2)) {
+ DRM_ERROR("3D_DRAW_INDX_2: expect subsequent INDX_BUFFER.\n");
+ return -EINVAL;
+ }
+
+ if ((cmd[1] & 0x8000ffff) != 0x80000810) {
+ DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
+ return -EINVAL;
+ }
+ if (!radeon_check_offset(dev_priv, cmd[2])) {
+ DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
+ return -EINVAL;
+ }
+ if (cmd[3] != expected_count) {
+ DRM_ERROR("INDX_BUFFER: buffer size %i, expected %i\n",
+ cmd[3], expected_count);
+ return -EINVAL;
+ }
+
+ BEGIN_RING(4);
+ OUT_RING(cmd[0]);
+ OUT_RING_TABLE((int *)(cmdbuf->buf + 4), 3);
+ ADVANCE_RING();
+
+ cmdbuf->buf += 4*4;
+ cmdbuf->bufsz -= 4*4;
+ }
+
return 0;
}
@@ -613,11 +695,22 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
case RADEON_CNTL_BITBLT_MULTI:
return r300_emit_bitblt_multi(dev_priv, cmdbuf);
- case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
- return r300_emit_indx_buffer(dev_priv, cmdbuf);
- case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
- case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
- case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
+ case RADEON_CP_INDX_BUFFER:
+ DRM_ERROR("packet3 INDX_BUFFER without preceding 3D_DRAW_INDX_2 is illegal.\n");
+ return -EINVAL;
+ case RADEON_CP_3D_DRAW_IMMD_2:
+ /* triggers drawing using in-packet vertex data */
+ case RADEON_CP_3D_DRAW_VBUF_2:
+ /* triggers drawing of vertex buffers setup elsewhere */
+ dev_priv->track_flush &= ~(RADEON_FLUSH_EMITED |
+ RADEON_PURGE_EMITED);
+ break;
+ case RADEON_CP_3D_DRAW_INDX_2:
+ /* triggers drawing using indices to vertex buffer */
+ /* whenever we send vertex we clear flush & purge */
+ dev_priv->track_flush &= ~(RADEON_FLUSH_EMITED |
+ RADEON_PURGE_EMITED);
+ return r300_emit_draw_indx_2(dev_priv, cmdbuf);
case RADEON_WAIT_FOR_IDLE:
case RADEON_CP_NOP:
/* these packets are safe */
@@ -713,17 +806,53 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
*/
static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
{
+ uint32_t cache_z, cache_3d, cache_2d;
RING_LOCALS;
- BEGIN_RING(6);
- OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
- OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A);
+ cache_z = R300_ZC_FLUSH;
+ cache_2d = R300_RB2D_DC_FLUSH;
+ cache_3d = R300_RB3D_DC_FLUSH;
+ if (!(dev_priv->track_flush & RADEON_PURGE_EMITED)) {
+ /* we can purge, primitive where draw since last purge */
+ cache_z |= R300_ZC_FREE;
+ cache_2d |= R300_RB2D_DC_FREE;
+ cache_3d |= R300_RB3D_DC_FREE;
+ }
+
+ /* flush & purge zbuffer */
+ BEGIN_RING(2);
OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0));
- OUT_RING(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE|
- R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
- OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
- OUT_RING(0x0);
+ OUT_RING(cache_z);
+ ADVANCE_RING();
+ /* flush & purge 3d */
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(cache_3d);
+ ADVANCE_RING();
+ /* flush & purge texture */
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_TX_INVALTAGS, 0));
+ OUT_RING(0);
+ ADVANCE_RING();
+ /* FIXME: is this one really needed ? */
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(R300_RB3D_AARESOLVE_CTL, 0));
+ OUT_RING(0);
+ ADVANCE_RING();
+ BEGIN_RING(2);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
+ ADVANCE_RING();
+ /* flush & purge 2d through E2 as RB2D will trigger lockup */
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET0(R300_DSTCACHE_CTLSTAT, 0));
+ OUT_RING(cache_2d);
+ OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+ OUT_RING(RADEON_WAIT_2D_IDLECLEAN |
+ RADEON_WAIT_HOST_IDLECLEAN);
ADVANCE_RING();
+ /* set flush & purge flags */
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED;
}
/**
@@ -905,8 +1034,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
DRM_DEBUG("\n");
- /* See the comment above r300_emit_begin3d for why this call must be here,
- * and what the cleanup gotos are for. */
+ /* pacify */
r300_pacify(dev_priv);
if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) {
diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h
index a6802f26afc..ee6f811599a 100644
--- a/drivers/gpu/drm/radeon/r300_reg.h
+++ b/drivers/gpu/drm/radeon/r300_reg.h
@@ -317,7 +317,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
* Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
* avoids bugs caused by still running shaders reading bad data from memory.
*/
-#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
+#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284
/* Absolutely no clue what this register is about. */
#define R300_VAP_UNKNOWN_2288 0x2288
@@ -513,7 +513,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* gap */
/* Zero to flush caches. */
-#define R300_TX_CNTL 0x4100
+#define R300_TX_INVALTAGS 0x4100
#define R300_TX_FLUSH 0x0
/* The upper enable bits are guessed, based on fglrx reported limits. */
@@ -1362,6 +1362,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
+#define R300_RB3D_AARESOLVE_CTL 0x4E88
/* gap */
/* Guess by Vladimir.
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index f0de81a5689..3331f88dcfb 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -40,6 +40,7 @@
#define RADEON_FIFO_DEBUG 0
static int radeon_do_cleanup_cp(struct drm_device * dev);
+static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
@@ -198,23 +199,8 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
DRM_UDELAY(1);
}
} else {
- /* 3D */
- tmp = RADEON_READ(R300_RB3D_DSTCACHE_CTLSTAT);
- tmp |= RADEON_RB3D_DC_FLUSH_ALL;
- RADEON_WRITE(R300_RB3D_DSTCACHE_CTLSTAT, tmp);
-
- /* 2D */
- tmp = RADEON_READ(R300_DSTCACHE_CTLSTAT);
- tmp |= RADEON_RB3D_DC_FLUSH_ALL;
- RADEON_WRITE(R300_DSTCACHE_CTLSTAT, tmp);
-
- for (i = 0; i < dev_priv->usec_timeout; i++) {
- if (!(RADEON_READ(R300_DSTCACHE_CTLSTAT)
- & RADEON_RB3D_DC_BUSY)) {
- return 0;
- }
- DRM_UDELAY(1);
- }
+ /* don't flush or purge cache here or lockup */
+ return 0;
}
#if RADEON_FIFO_DEBUG
@@ -237,6 +223,9 @@ static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
return 0;
DRM_UDELAY(1);
}
+ DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n",
+ RADEON_READ(RADEON_RBBM_STATUS),
+ RADEON_READ(R300_VAP_CNTL_STATUS));
#if RADEON_FIFO_DEBUG
DRM_ERROR("failed!\n");
@@ -263,6 +252,9 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
}
DRM_UDELAY(1);
}
+ DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n",
+ RADEON_READ(RADEON_RBBM_STATUS),
+ RADEON_READ(R300_VAP_CNTL_STATUS));
#if RADEON_FIFO_DEBUG
DRM_ERROR("failed!\n");
@@ -443,14 +435,20 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
dev_priv->cp_running = 1;
- BEGIN_RING(6);
-
+ BEGIN_RING(8);
+ /* isync can only be written through cp on r5xx write it here */
+ OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
+ OUT_RING(RADEON_ISYNC_ANY2D_IDLE3D |
+ RADEON_ISYNC_ANY3D_IDLE2D |
+ RADEON_ISYNC_WAIT_IDLEGUI |
+ RADEON_ISYNC_CPSCRATCH_IDLEGUI);
RADEON_PURGE_CACHE();
RADEON_PURGE_ZCACHE();
RADEON_WAIT_UNTIL_IDLE();
-
ADVANCE_RING();
COMMIT_RING();
+
+ dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED;
}
/* Reset the Command Processor. This will not flush any pending
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 3f0eca957aa..09938169317 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -220,6 +220,9 @@ struct radeon_virt_surface {
struct drm_file *file_priv;
};
+#define RADEON_FLUSH_EMITED (1 < 0)
+#define RADEON_PURGE_EMITED (1 < 1)
+
typedef struct drm_radeon_private {
drm_radeon_ring_buffer_t ring;
drm_radeon_sarea_t *sarea_priv;
@@ -311,6 +314,7 @@ typedef struct drm_radeon_private {
unsigned long fb_aper_offset;
int num_gb_pipes;
+ int track_flush;
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {
@@ -693,7 +697,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
#define R300_ZB_ZCACHE_CTLSTAT 0x4f18
# define R300_ZC_FLUSH (1 << 0)
# define R300_ZC_FREE (1 << 1)
-# define R300_ZC_FLUSH_ALL 0x3
# define R300_ZC_BUSY (1 << 31)
#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c
# define RADEON_RB3D_DC_FLUSH (3 << 0)
@@ -701,6 +704,8 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
# define RADEON_RB3D_DC_FLUSH_ALL 0xf
# define RADEON_RB3D_DC_BUSY (1 << 31)
#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c
+# define R300_RB3D_DC_FLUSH (2 << 0)
+# define R300_RB3D_DC_FREE (2 << 2)
# define R300_RB3D_DC_FINISH (1 << 4)
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_Z_TEST_MASK (7 << 4)
@@ -1246,17 +1251,17 @@ do { \
OUT_RING(RADEON_RB3D_DC_FLUSH); \
} else { \
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_DC_FLUSH); \
+ OUT_RING(R300_RB3D_DC_FLUSH); \
} \
} while (0)
#define RADEON_PURGE_CACHE() do { \
if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \
+ OUT_RING(RADEON_RB3D_DC_FLUSH | RADEON_RB3D_DC_FREE); \
} else { \
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \
+ OUT_RING(R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); \
} \
} while (0)
@@ -1273,10 +1278,10 @@ do { \
#define RADEON_PURGE_ZCACHE() do { \
if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \
- OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL); \
+ OUT_RING(RADEON_RB3D_ZC_FLUSH | RADEON_RB3D_ZC_FREE); \
} else { \
- OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \
- OUT_RING(R300_ZC_FLUSH_ALL); \
+ OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \
+ OUT_RING(R300_ZC_FLUSH | R300_ZC_FREE); \
} \
} while (0)
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 550853f79ae..b346a687ab5 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -108,6 +108,9 @@ static int i2c_device_probe(struct device *dev)
if (!driver->probe || !driver->id_table)
return -ENODEV;
client->driver = driver;
+ if (!device_can_wakeup(&client->dev))
+ device_init_wakeup(&client->dev,
+ client->flags & I2C_CLIENT_WAKE);
dev_dbg(dev, "probe\n");
status = driver->probe(client, i2c_match_id(driver->id_table, client));
@@ -262,9 +265,8 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
client->adapter = adap;
client->dev.platform_data = info->platform_data;
- device_init_wakeup(&client->dev, info->flags & I2C_CLIENT_WAKE);
- client->flags = info->flags & ~I2C_CLIENT_WAKE;
+ client->flags = info->flags;
client->addr = info->addr;
client->irq = info->irq;
@@ -1188,8 +1190,8 @@ int i2c_probe(struct i2c_adapter *adapter,
&& address_data->normal_i2c[0] == I2C_CLIENT_END)
return 0;
- dev_warn(&adapter->dev, "SMBus Quick command not supported, "
- "can't probe for chips\n");
+ dev_dbg(&adapter->dev, "SMBus Quick command not supported, "
+ "can't probe for chips\n");
return -EOPNOTSUPP;
}
@@ -1350,6 +1352,10 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
}
}
+ /* Stop here if the classes do not match */
+ if (!(adapter->class & driver->class))
+ goto exit_free;
+
/* Stop here if we can't use SMBUS_QUICK */
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
if (address_data->probe[0] == I2C_CLIENT_END
@@ -1362,10 +1368,6 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
goto exit_free;
}
- /* Stop here if the classes do not match */
- if (!(adapter->class & driver->class))
- goto exit_free;
-
/* Probe entries are done second, and are not affected by ignore
entries either */
for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) {
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index a4cdb465cd1..87f5c5a87b9 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -204,6 +204,8 @@ struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd,
if (err)
goto err_mr;
+ mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key;
+
return &mr->ibmr;
err_mr:
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index 6f227d3dbda..e348cfccc17 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -43,7 +43,7 @@
#include <linux/input.h>
#include <asm/portmux.h>
-#include <asm/mach/bf54x_keys.h>
+#include <mach/bf54x_keys.h>
#define DRV_NAME "bf54x-keys"
#define TIME_SCALE 100 /* 100 ns */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index a5c141cecd4..4a11296a951 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -822,14 +822,14 @@ config ULTRA32
will be called smc-ultra32.
config BFIN_MAC
- tristate "Blackfin 527/536/537 on-chip mac support"
- depends on NET_ETHERNET && (BF527 || BF537 || BF536)
+ tristate "Blackfin on-chip MAC support"
+ depends on NET_ETHERNET && (BF526 || BF527 || BF536 || BF537)
select CRC32
select MII
select PHYLIB
select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
help
- This is the driver for blackfin on-chip mac device. Say Y if you want it
+ This is the driver for Blackfin on-chip mac device. Say Y if you want it
compiled into the kernel. This driver is also available as a module
( = code which can be inserted in and removed from the running kernel
whenever you want). The module will be called bfin_mac.
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 82d7be1655d..7685b995ff9 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -2232,10 +2232,11 @@ static int atl1e_resume(struct pci_dev *pdev)
AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
- if (netif_running(netdev))
+ if (netif_running(netdev)) {
err = atl1e_request_irq(adapter);
if (err)
return err;
+ }
atl1e_reset_hw(&adapter->hw);
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index e6a7bb79d4d..e23ce77712f 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -3022,7 +3022,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netdev->features = NETIF_F_HW_CSUM;
netdev->features |= NETIF_F_SG;
netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
- netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_LLTX;
/*
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 19d32a227be..453115acaad 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1838,7 +1838,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
if ((le16_to_cpu(rfd->command) & cb_el) &&
(RU_RUNNING == nic->ru_running))
- if (readb(&nic->csr->scb.status) & rus_no_res)
+ if (ioread8(&nic->csr->scb.status) & rus_no_res)
nic->ru_running = RU_SUSPENDED;
return -ENODATA;
}
@@ -1861,7 +1861,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
if ((le16_to_cpu(rfd->command) & cb_el) &&
(RU_RUNNING == nic->ru_running)) {
- if (readb(&nic->csr->scb.status) & rus_no_res)
+ if (ioread8(&nic->csr->scb.status) & rus_no_res)
nic->ru_running = RU_SUSPENDED;
}
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index b9f90a5d3d4..213437d1315 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -208,7 +208,7 @@ struct e1000_option {
} r;
struct { /* list_option info */
int nr;
- struct e1000_opt_list { int i; char *str; } *p;
+ const struct e1000_opt_list { int i; char *str; } *p;
} l;
} arg;
};
@@ -242,7 +242,7 @@ static int __devinit e1000_validate_option(unsigned int *value,
break;
case list_option: {
int i;
- struct e1000_opt_list *ent;
+ const struct e1000_opt_list *ent;
for (i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
@@ -279,7 +279,9 @@ static void e1000_check_copper_options(struct e1000_adapter *adapter);
void __devinit e1000_check_options(struct e1000_adapter *adapter)
{
+ struct e1000_option opt;
int bd = adapter->bd_number;
+
if (bd >= E1000_MAX_NIC) {
DPRINTK(PROBE, NOTICE,
"Warning: no configuration for board #%i\n", bd);
@@ -287,19 +289,21 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
{ /* Transmit Descriptor Count */
- struct e1000_option opt = {
+ struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+ int i;
+ e1000_mac_type mac_type = adapter->hw.mac_type;
+
+ opt = (struct e1000_option) {
.type = range_option,
.name = "Transmit Descriptors",
.err = "using default of "
__MODULE_STRING(E1000_DEFAULT_TXD),
.def = E1000_DEFAULT_TXD,
- .arg = { .r = { .min = E1000_MIN_TXD }}
+ .arg = { .r = {
+ .min = E1000_MIN_TXD,
+ .max = mac_type < e1000_82544 ? E1000_MAX_TXD : E1000_MAX_82544_TXD
+ }}
};
- struct e1000_tx_ring *tx_ring = adapter->tx_ring;
- int i;
- e1000_mac_type mac_type = adapter->hw.mac_type;
- opt.arg.r.max = mac_type < e1000_82544 ?
- E1000_MAX_TXD : E1000_MAX_82544_TXD;
if (num_TxDescriptors > bd) {
tx_ring->count = TxDescriptors[bd];
@@ -313,19 +317,21 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
tx_ring[i].count = tx_ring->count;
}
{ /* Receive Descriptor Count */
- struct e1000_option opt = {
+ struct e1000_rx_ring *rx_ring = adapter->rx_ring;
+ int i;
+ e1000_mac_type mac_type = adapter->hw.mac_type;
+
+ opt = (struct e1000_option) {
.type = range_option,
.name = "Receive Descriptors",
.err = "using default of "
__MODULE_STRING(E1000_DEFAULT_RXD),
.def = E1000_DEFAULT_RXD,
- .arg = { .r = { .min = E1000_MIN_RXD }}
+ .arg = { .r = {
+ .min = E1000_MIN_RXD,
+ .max = mac_type < e1000_82544 ? E1000_MAX_RXD : E1000_MAX_82544_RXD
+ }}
};
- struct e1000_rx_ring *rx_ring = adapter->rx_ring;
- int i;
- e1000_mac_type mac_type = adapter->hw.mac_type;
- opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
- E1000_MAX_82544_RXD;
if (num_RxDescriptors > bd) {
rx_ring->count = RxDescriptors[bd];
@@ -339,7 +345,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
rx_ring[i].count = rx_ring->count;
}
{ /* Checksum Offload Enable/Disable */
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = enable_option,
.name = "Checksum Offload",
.err = "defaulting to Enabled",
@@ -363,7 +369,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
{ E1000_FC_FULL, "Flow Control Enabled" },
{ E1000_FC_DEFAULT, "Flow Control Hardware Default" }};
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = list_option,
.name = "Flow Control",
.err = "reading default settings from EEPROM",
@@ -381,7 +387,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
}
{ /* Transmit Interrupt Delay */
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = range_option,
.name = "Transmit Interrupt Delay",
.err = "using default of " __MODULE_STRING(DEFAULT_TIDV),
@@ -399,7 +405,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
}
{ /* Transmit Absolute Interrupt Delay */
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = range_option,
.name = "Transmit Absolute Interrupt Delay",
.err = "using default of " __MODULE_STRING(DEFAULT_TADV),
@@ -417,7 +423,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
}
{ /* Receive Interrupt Delay */
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = range_option,
.name = "Receive Interrupt Delay",
.err = "using default of " __MODULE_STRING(DEFAULT_RDTR),
@@ -435,7 +441,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
}
{ /* Receive Absolute Interrupt Delay */
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = range_option,
.name = "Receive Absolute Interrupt Delay",
.err = "using default of " __MODULE_STRING(DEFAULT_RADV),
@@ -453,7 +459,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
}
{ /* Interrupt Throttling Rate */
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = range_option,
.name = "Interrupt Throttling Rate (ints/sec)",
.err = "using default of " __MODULE_STRING(DEFAULT_ITR),
@@ -497,7 +503,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
}
{ /* Smart Power Down */
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = enable_option,
.name = "PHY Smart Power Down",
.err = "defaulting to Disabled",
@@ -513,7 +519,7 @@ void __devinit e1000_check_options(struct e1000_adapter *adapter)
}
}
{ /* Kumeran Lock Loss Workaround */
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = enable_option,
.name = "Kumeran Lock Loss Workaround",
.err = "defaulting to Enabled",
@@ -578,16 +584,18 @@ static void __devinit e1000_check_fiber_options(struct e1000_adapter *adapter)
static void __devinit e1000_check_copper_options(struct e1000_adapter *adapter)
{
+ struct e1000_option opt;
unsigned int speed, dplx, an;
int bd = adapter->bd_number;
{ /* Speed */
- struct e1000_opt_list speed_list[] = {{ 0, "" },
- { SPEED_10, "" },
- { SPEED_100, "" },
- { SPEED_1000, "" }};
+ static const struct e1000_opt_list speed_list[] = {
+ { 0, "" },
+ { SPEED_10, "" },
+ { SPEED_100, "" },
+ { SPEED_1000, "" }};
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = list_option,
.name = "Speed",
.err = "parameter ignored",
@@ -604,11 +612,12 @@ static void __devinit e1000_check_copper_options(struct e1000_adapter *adapter)
}
}
{ /* Duplex */
- struct e1000_opt_list dplx_list[] = {{ 0, "" },
- { HALF_DUPLEX, "" },
- { FULL_DUPLEX, "" }};
+ static const struct e1000_opt_list dplx_list[] = {
+ { 0, "" },
+ { HALF_DUPLEX, "" },
+ { FULL_DUPLEX, "" }};
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = list_option,
.name = "Duplex",
.err = "parameter ignored",
@@ -637,7 +646,7 @@ static void __devinit e1000_check_copper_options(struct e1000_adapter *adapter)
"parameter ignored\n");
adapter->hw.autoneg_advertised = AUTONEG_ADV_DEFAULT;
} else { /* Autoneg */
- struct e1000_opt_list an_list[] =
+ static const struct e1000_opt_list an_list[] =
#define AA "AutoNeg advertising "
{{ 0x01, AA "10/HD" },
{ 0x02, AA "10/FD" },
@@ -671,7 +680,7 @@ static void __devinit e1000_check_copper_options(struct e1000_adapter *adapter)
{ 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" },
{ 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }};
- struct e1000_option opt = {
+ opt = (struct e1000_option) {
.type = list_option,
.name = "AutoNeg",
.err = "parameter ignored",
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 053971e5fc9..331b86b01fa 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -5522,7 +5522,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (id->driver_data & DEV_HAS_CHECKSUM) {
np->rx_csum = 1;
np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
- dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+ dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
dev->features |= NETIF_F_TSO;
}
@@ -5835,7 +5835,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n",
dev->features & NETIF_F_HIGHDMA ? "highdma " : "",
- dev->features & (NETIF_F_HW_CSUM | NETIF_F_SG) ?
+ dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ?
"csum " : "",
dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ?
"vlan " : "",
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 9a51ec8293c..9d461825bf4 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -792,6 +792,10 @@ static int fs_enet_open(struct net_device *dev)
int r;
int err;
+ /* to initialize the fep->cur_rx,... */
+ /* not doing this, will cause a crash in fs_enet_rx_napi */
+ fs_init_bds(fep->ndev);
+
if (fep->fpi->use_napi)
napi_enable(&fep->napi);
@@ -1167,6 +1171,10 @@ static struct of_device_id fs_enet_match[] = {
.compatible = "fsl,cpm1-scc-enet",
.data = (void *)&fs_scc_ops,
},
+ {
+ .compatible = "fsl,cpm2-scc-enet",
+ .data = (void *)&fs_scc_ops,
+ },
#endif
#ifdef CONFIG_FS_ENET_HAS_FCC
{
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index 029b3c7ef29..22f50dd8b27 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -47,7 +47,6 @@
#include "fs_enet.h"
/*************************************************/
-
#if defined(CONFIG_CPM1)
/* for a 8xx __raw_xxx's are sufficient */
#define __fs_out32(addr, x) __raw_writel(x, addr)
@@ -62,6 +61,8 @@
#define __fs_out16(addr, x) out_be16(addr, x)
#define __fs_in32(addr) in_be32(addr)
#define __fs_in16(addr) in_be16(addr)
+#define __fs_out8(addr, x) out_8(addr, x)
+#define __fs_in8(addr) in_8(addr)
#endif
/* write, read, set bits, clear bits */
@@ -262,8 +263,13 @@ static void restart(struct net_device *dev)
/* Initialize function code registers for big-endian.
*/
+#ifndef CONFIG_NOT_COHERENT_CACHE
+ W8(ep, sen_genscc.scc_rfcr, SCC_EB | SCC_GBL);
+ W8(ep, sen_genscc.scc_tfcr, SCC_EB | SCC_GBL);
+#else
W8(ep, sen_genscc.scc_rfcr, SCC_EB);
W8(ep, sen_genscc.scc_tfcr, SCC_EB);
+#endif
/* Set maximum bytes per receive buffer.
* This appears to be an Ethernet frame size, not the buffer
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 999d6916827..4320a983a58 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -105,6 +105,7 @@ const char gfar_driver_version[] = "1.3";
static int gfar_enet_open(struct net_device *dev);
static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static void gfar_reset_task(struct work_struct *work);
static void gfar_timeout(struct net_device *dev);
static int gfar_close(struct net_device *dev);
struct sk_buff *gfar_new_skb(struct net_device *dev);
@@ -209,6 +210,7 @@ static int gfar_probe(struct platform_device *pdev)
spin_lock_init(&priv->txlock);
spin_lock_init(&priv->rxlock);
spin_lock_init(&priv->bflock);
+ INIT_WORK(&priv->reset_task, gfar_reset_task);
platform_set_drvdata(pdev, dev);
@@ -1212,6 +1214,7 @@ static int gfar_close(struct net_device *dev)
napi_disable(&priv->napi);
+ cancel_work_sync(&priv->reset_task);
stop_gfar(dev);
/* Disconnect from the PHY */
@@ -1326,13 +1329,16 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-/* gfar_timeout gets called when a packet has not been
+/* gfar_reset_task gets scheduled when a packet has not been
* transmitted after a set amount of time.
* For now, assume that clearing out all the structures, and
- * starting over will fix the problem. */
-static void gfar_timeout(struct net_device *dev)
+ * starting over will fix the problem.
+ */
+static void gfar_reset_task(struct work_struct *work)
{
- dev->stats.tx_errors++;
+ struct gfar_private *priv = container_of(work, struct gfar_private,
+ reset_task);
+ struct net_device *dev = priv->dev;
if (dev->flags & IFF_UP) {
stop_gfar(dev);
@@ -1342,6 +1348,14 @@ static void gfar_timeout(struct net_device *dev)
netif_tx_schedule_all(dev);
}
+static void gfar_timeout(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+
+ dev->stats.tx_errors++;
+ schedule_work(&priv->reset_task);
+}
+
/* Interrupt Handler for Transmit complete */
static int gfar_clean_tx_ring(struct net_device *dev)
{
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index d59df98bd63..f46e9b63af1 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -756,6 +756,7 @@ struct gfar_private {
uint32_t msg_enable;
+ struct work_struct reset_task;
/* Network Statistics */
struct gfar_extra_stats extra_stats;
};
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 2e720f26ca8..ccd9d9058f6 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -663,9 +663,6 @@ static int emac_configure(struct emac_instance *dev)
if (emac_phy_gpcs(dev->phy.mode))
emac_mii_reset_phy(&dev->phy);
- /* Required for Pause packet support in EMAC */
- dev_mc_add(ndev, default_mcast_addr, sizeof(default_mcast_addr), 1);
-
return 0;
}
@@ -1150,6 +1147,9 @@ static int emac_open(struct net_device *ndev)
} else
netif_carrier_on(dev->ndev);
+ /* Required for Pause packet support in EMAC */
+ dev_mc_add(ndev, default_mcast_addr, sizeof(default_mcast_addr), 1);
+
emac_configure(dev);
mal_poll_add(dev->mal, &dev->commac);
mal_enable_tx_channel(dev->mal, dev->mal_tx_chan);
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index a03fe1fb61c..c2d57f83608 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -904,8 +904,6 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
unsigned long data_dma_addr;
desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len;
- data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
- skb->len, DMA_TO_DEVICE);
if (skb->ip_summed == CHECKSUM_PARTIAL &&
ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) {
@@ -924,6 +922,8 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
buf[1] = 0;
}
+ data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) {
if (!firmware_has_feature(FW_FEATURE_CMO))
ibmveth_error_printk("tx: unable to map xmit buffer\n");
@@ -932,6 +932,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
desc.fields.address = adapter->bounce_buffer_dma;
tx_map_failed++;
used_bounce = 1;
+ wmb();
} else
desc.fields.address = data_dma_addr;
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index bb823acc744..f5e2e7235fc 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -87,7 +87,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
case E1000_DEV_ID_82576:
case E1000_DEV_ID_82576_FIBER:
case E1000_DEV_ID_82576_SERDES:
- case E1000_DEV_ID_82576_QUAD_COPPER:
mac->type = e1000_82576;
break;
default:
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index a65ccc3095c..99504a600a8 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -41,7 +41,6 @@ struct e1000_hw;
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
-#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 11aee130995..58906c984be 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -373,13 +373,17 @@ static void igb_get_regs(struct net_device *netdev,
regs_buff[12] = rd32(E1000_EECD);
/* Interrupt */
- regs_buff[13] = rd32(E1000_EICR);
+ /* Reading EICS for EICR because they read the
+ * same but EICS does not clear on read */
+ regs_buff[13] = rd32(E1000_EICS);
regs_buff[14] = rd32(E1000_EICS);
regs_buff[15] = rd32(E1000_EIMS);
regs_buff[16] = rd32(E1000_EIMC);
regs_buff[17] = rd32(E1000_EIAC);
regs_buff[18] = rd32(E1000_EIAM);
- regs_buff[19] = rd32(E1000_ICR);
+ /* Reading ICS for ICR because they read the
+ * same but ICS does not clear on read */
+ regs_buff[19] = rd32(E1000_ICS);
regs_buff[20] = rd32(E1000_ICS);
regs_buff[21] = rd32(E1000_IMS);
regs_buff[22] = rd32(E1000_IMC);
@@ -1746,15 +1750,6 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
/* return success for non excluded adapter ports */
retval = 0;
break;
- case E1000_DEV_ID_82576_QUAD_COPPER:
- /* quad port adapters only support WoL on port A */
- if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
- wol->supported = 0;
- break;
- }
- /* return success for non excluded adapter ports */
- retval = 0;
- break;
default:
/* dual port cards only support WoL on port A from now on
* unless it was enabled in the eeprom for port B
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 8f66e15ec8d..634c4c9d87b 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -61,7 +61,6 @@ static struct pci_device_id igb_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
@@ -521,7 +520,7 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
adapter->msix_entries,
numvecs);
if (err == 0)
- return;
+ goto out;
igb_reset_interrupt_capability(adapter);
@@ -531,7 +530,7 @@ msi_only:
adapter->num_tx_queues = 1;
if (!pci_enable_msi(adapter->pdev))
adapter->flags |= IGB_FLAG_HAS_MSI;
-
+out:
/* Notify the stack of the (possibly) reduced Tx Queue count. */
adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
return;
@@ -1217,16 +1216,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
adapter->eeprom_wol = 0;
break;
- case E1000_DEV_ID_82576_QUAD_COPPER:
- /* if quad port adapter, disable WoL on all but port A */
- if (global_quad_port_a != 0)
- adapter->eeprom_wol = 0;
- else
- adapter->flags |= IGB_FLAG_QUAD_PORT_A;
- /* Reset for multiple quad port adapters */
- if (++global_quad_port_a == 4)
- global_quad_port_a = 0;
- break;
}
/* initialize the wol settings based on the eeprom settings */
@@ -2290,7 +2279,9 @@ static void igb_watchdog_task(struct work_struct *work)
struct igb_ring *tx_ring = adapter->tx_ring;
struct e1000_mac_info *mac = &adapter->hw.mac;
u32 link;
+ u32 eics = 0;
s32 ret_val;
+ int i;
if ((netif_carrier_ok(netdev)) &&
(rd32(E1000_STATUS) & E1000_STATUS_LU))
@@ -2392,7 +2383,13 @@ link_up:
}
/* Cause software interrupt to ensure rx ring is cleaned */
- wr32(E1000_ICS, E1000_ICS_RXDMT0);
+ if (adapter->msix_entries) {
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ eics |= adapter->rx_ring[i].eims_value;
+ wr32(E1000_EICS, eics);
+ } else {
+ wr32(E1000_ICS, E1000_ICS_RXDMT0);
+ }
/* Force detection of hung controller every watchdog period */
tx_ring->detect_tx_hung = true;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 34bca16d48a..53f41b649f0 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1636,16 +1636,17 @@ static void ixgbe_set_multi(struct net_device *netdev)
struct ixgbe_hw *hw = &adapter->hw;
struct dev_mc_list *mc_ptr;
u8 *mta_list;
- u32 fctrl;
+ u32 fctrl, vlnctrl;
int i;
/* Check for Promiscuous and All Multicast modes */
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
if (netdev->flags & IFF_PROMISC) {
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- fctrl &= ~IXGBE_VLNCTRL_VFE;
+ vlnctrl &= ~IXGBE_VLNCTRL_VFE;
} else {
if (netdev->flags & IFF_ALLMULTI) {
fctrl |= IXGBE_FCTRL_MPE;
@@ -1653,10 +1654,11 @@ static void ixgbe_set_multi(struct net_device *netdev)
} else {
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
}
- fctrl |= IXGBE_VLNCTRL_VFE;
+ vlnctrl |= IXGBE_VLNCTRL_VFE;
}
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
if (netdev->mc_count) {
mta_list = kcalloc(netdev->mc_count, ETH_ALEN, GFP_ATOMIC);
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 46819af3b06..0a18b9e96da 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -55,7 +55,7 @@
#include <asm/system.h>
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
-static char mv643xx_eth_driver_version[] = "1.2";
+static char mv643xx_eth_driver_version[] = "1.3";
#define MV643XX_ETH_CHECKSUM_OFFLOAD_TX
#define MV643XX_ETH_NAPI
@@ -474,11 +474,19 @@ static void rxq_refill(struct rx_queue *rxq)
/*
* Reserve 2+14 bytes for an ethernet header (the
* hardware automatically prepends 2 bytes of dummy
- * data to each received packet), 4 bytes for a VLAN
- * header, and 4 bytes for the trailing FCS -- 24
- * bytes total.
+ * data to each received packet), 16 bytes for up to
+ * four VLAN tags, and 4 bytes for the trailing FCS
+ * -- 36 bytes total.
*/
- skb_size = mp->dev->mtu + 24;
+ skb_size = mp->dev->mtu + 36;
+
+ /*
+ * Make sure that the skb size is a multiple of 8
+ * bytes, as the lower three bits of the receive
+ * descriptor's buffer size field are ignored by
+ * the hardware.
+ */
+ skb_size = (skb_size + 7) & ~7;
skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1);
if (skb == NULL)
@@ -509,10 +517,8 @@ static void rxq_refill(struct rx_queue *rxq)
skb_reserve(skb, 2);
}
- if (rxq->rx_desc_count != rxq->rx_ring_size) {
- rxq->rx_oom.expires = jiffies + (HZ / 10);
- add_timer(&rxq->rx_oom);
- }
+ if (rxq->rx_desc_count != rxq->rx_ring_size)
+ mod_timer(&rxq->rx_oom, jiffies + (HZ / 10));
spin_unlock_irqrestore(&mp->lock, flags);
}
@@ -529,7 +535,7 @@ static int rxq_process(struct rx_queue *rxq, int budget)
int rx;
rx = 0;
- while (rx < budget) {
+ while (rx < budget && rxq->rx_desc_count) {
struct rx_desc *rx_desc;
unsigned int cmd_sts;
struct sk_buff *skb;
@@ -554,7 +560,7 @@ static int rxq_process(struct rx_queue *rxq, int budget)
spin_unlock_irqrestore(&mp->lock, flags);
dma_unmap_single(NULL, rx_desc->buf_ptr + 2,
- mp->dev->mtu + 24, DMA_FROM_DEVICE);
+ rx_desc->buf_size, DMA_FROM_DEVICE);
rxq->rx_desc_count--;
rx++;
@@ -636,9 +642,9 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
txq_reclaim(mp->txq + i, 0);
if (netif_carrier_ok(mp->dev)) {
- spin_lock(&mp->lock);
+ spin_lock_irq(&mp->lock);
__txq_maybe_wake(mp->txq + mp->txq_primary);
- spin_unlock(&mp->lock);
+ spin_unlock_irq(&mp->lock);
}
}
#endif
@@ -650,8 +656,6 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
if (rx < budget) {
netif_rx_complete(mp->dev, napi);
- wrl(mp, INT_CAUSE(mp->port_num), 0);
- wrl(mp, INT_CAUSE_EXT(mp->port_num), 0);
wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
}
@@ -1796,6 +1800,7 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
*/
#ifdef MV643XX_ETH_NAPI
if (int_cause & INT_RX) {
+ wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_RX));
wrl(mp, INT_MASK(mp->port_num), 0x00000000);
rdl(mp, INT_MASK(mp->port_num));
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 54cd89cb083..d6524db321a 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -75,7 +75,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.3.99-1.347"
+#define MYRI10GE_VERSION_STR "1.4.3-1.358"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a3e3895e503..0f6f9747d25 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2792,7 +2792,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
pkt_size, PCI_DMA_FROMDEVICE);
rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
} else {
- pci_unmap_single(pdev, addr, pkt_size,
+ pci_unmap_single(pdev, addr, tp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
tp->Rx_skbuff[entry] = NULL;
}
diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c
index 889f9872461..a85efcfd9d0 100644
--- a/drivers/net/skfp/ess.c
+++ b/drivers/net/skfp/ess.c
@@ -510,7 +510,7 @@ static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
chg->path.para.p_type = SMT_P320B ;
chg->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
chg->path.mib_index = SBAPATHINDEX ;
- chg->path.path_pad = (u_short)NULL ;
+ chg->path.path_pad = 0;
chg->path.path_index = PRIMARY_RING ;
/* set P320F */
@@ -606,7 +606,7 @@ static void ess_send_alc_req(struct s_smc *smc)
req->path.para.p_type = SMT_P320B ;
req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
req->path.mib_index = SBAPATHINDEX ;
- req->path.path_pad = (u_short)NULL ;
+ req->path.path_pad = 0;
req->path.path_index = PRIMARY_RING ;
/* set P0017 */
@@ -636,7 +636,7 @@ static void ess_send_alc_req(struct s_smc *smc)
/* set P19 */
req->a_addr.para.p_type = SMT_P0019 ;
req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ;
- req->a_addr.sba_pad = (u_short)NULL ;
+ req->a_addr.sba_pad = 0;
req->a_addr.alloc_addr = null_addr ;
/* set P1A */
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 2040965d772..24768c10cad 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -2255,7 +2255,7 @@ static int smc_drv_remove(struct platform_device *pdev)
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
if (!res)
- platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, SMC_IO_EXTENT);
free_netdev(ndev);
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 1b7cac77159..6e42b5a8c22 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -397,7 +397,7 @@ static const struct usb_device_id hso_ids[] = {
{default_port_device(0x0af0, 0xc031)}, /* Icon-Edge */
{icon321_port_device(0x0af0, 0xd013)}, /* Module HSxPA */
{icon321_port_device(0x0af0, 0xd031)}, /* Icon-321 */
- {default_port_device(0x0af0, 0xd033)}, /* Icon-322 */
+ {icon321_port_device(0x0af0, 0xd033)}, /* Icon-322 */
{USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */
{USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */
{USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */
@@ -2613,6 +2613,7 @@ static int hso_resume(struct usb_interface *iface)
"Transmitting lingering data\n");
hso_net_start_xmit(hso_net->skb_tx_buf,
hso_net->net);
+ hso_net->skb_tx_buf = NULL;
}
result = hso_start_net_device(network_table[i]);
if (result)
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index c3d119f997f..ca9d00c1194 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -46,6 +46,10 @@
#define MCS7830_VENDOR_ID 0x9710
#define MCS7830_PRODUCT_ID 0x7830
+#define MCS7730_PRODUCT_ID 0x7730
+
+#define SITECOM_VENDOR_ID 0x0DF6
+#define LN_030_PRODUCT_ID 0x0021
#define MCS7830_MII_ADVERTISE (ADVERTISE_PAUSE_CAP | ADVERTISE_100FULL | \
ADVERTISE_100HALF | ADVERTISE_10FULL | \
@@ -442,6 +446,29 @@ static struct ethtool_ops mcs7830_ethtool_ops = {
.nway_reset = usbnet_nway_reset,
};
+static int mcs7830_set_mac_address(struct net_device *netdev, void *p)
+{
+ int ret;
+ struct usbnet *dev = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+
+ if (netif_running(netdev))
+ return -EBUSY;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+
+ ret = mcs7830_set_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN,
+ netdev->dev_addr);
+
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
{
struct net_device *net = dev->net;
@@ -455,6 +482,7 @@ static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
net->ethtool_ops = &mcs7830_ethtool_ops;
net->set_multicast_list = mcs7830_set_multicast;
mcs7830_set_multicast(net);
+ net->set_mac_address = mcs7830_set_mac_address;
/* reserve space for the status byte on rx */
dev->rx_urb_size = ETH_FRAME_LEN + 1;
@@ -491,7 +519,16 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
}
static const struct driver_info moschip_info = {
- .description = "MOSCHIP 7830 usb-NET adapter",
+ .description = "MOSCHIP 7830/7730 usb-NET adapter",
+ .bind = mcs7830_bind,
+ .rx_fixup = mcs7830_rx_fixup,
+ .flags = FLAG_ETHER,
+ .in = 1,
+ .out = 2,
+};
+
+static const struct driver_info sitecom_info = {
+ .description = "Sitecom LN-30 usb-NET adapter",
.bind = mcs7830_bind,
.rx_fixup = mcs7830_rx_fixup,
.flags = FLAG_ETHER,
@@ -504,6 +541,14 @@ static const struct usb_device_id products[] = {
USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID),
.driver_info = (unsigned long) &moschip_info,
},
+ {
+ USB_DEVICE(MCS7830_VENDOR_ID, MCS7730_PRODUCT_ID),
+ .driver_info = (unsigned long) &moschip_info,
+ },
+ {
+ USB_DEVICE(SITECOM_VENDOR_ID, LN_030_PRODUCT_ID),
+ .driver_info = (unsigned long) &sitecom_info,
+ },
{},
};
MODULE_DEVICE_TABLE(usb, products);
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index e59255a155a..6596cd0742b 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -1317,7 +1317,7 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
break;
case SIOCDEVRESINSTATS :
- if( current->euid != 0 ) /* root only */
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
break;
@@ -1334,7 +1334,7 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
break;
case SIOCDEVSHWSTATE :
- if( current->euid != 0 ) /* root only */
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock( &nl->lock );
@@ -1355,7 +1355,7 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
#ifdef CONFIG_SBNI_MULTILINE
case SIOCDEVENSLAVE :
- if( current->euid != 0 ) /* root only */
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (copy_from_user( slave_name, ifr->ifr_data, sizeof slave_name ))
@@ -1370,7 +1370,7 @@ sbni_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd )
return enslave( dev, slave_dev );
case SIOCDEVEMANSIPATE :
- if( current->euid != 0 ) /* root only */
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
return emancipate( dev );
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index 6f9aa164374..fa14255282a 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -337,7 +337,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ei_poll;
#endif
- NS8390p_init(dev, 0);
+ NS8390_init(dev, 0);
#if 1
/* Enable interrupt generation on softconfig cards -- M.U */
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index b20a45aa868..0676c6d8438 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -251,7 +251,7 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
return;
pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
PCI_DMA_TODEVICE);
- dev_kfree_skb(bf->skb);
+ dev_kfree_skb_any(bf->skb);
bf->skb = NULL;
}
@@ -466,6 +466,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
mutex_init(&sc->lock);
spin_lock_init(&sc->rxbuflock);
spin_lock_init(&sc->txbuflock);
+ spin_lock_init(&sc->block);
/* Set private data */
pci_set_drvdata(pdev, hw);
@@ -2179,8 +2180,11 @@ ath5k_beacon_config(struct ath5k_softc *sc)
sc->imask |= AR5K_INT_SWBA;
- if (ath5k_hw_hasveol(ah))
+ if (ath5k_hw_hasveol(ah)) {
+ spin_lock(&sc->block);
ath5k_beacon_send(sc);
+ spin_unlock(&sc->block);
+ }
}
/* TODO else AP */
@@ -2403,7 +2407,9 @@ ath5k_intr(int irq, void *dev_id)
TSF_TO_TU(tsf),
(unsigned long long) tsf);
} else {
+ spin_lock(&sc->block);
ath5k_beacon_send(sc);
+ spin_unlock(&sc->block);
}
}
if (status & AR5K_INT_RXEOL) {
@@ -2745,6 +2751,11 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
ret = -EOPNOTSUPP;
goto end;
}
+
+ /* Set to a reasonable value. Note that this will
+ * be set to mac80211's value at ath5k_config(). */
+ sc->bintval = 1000;
+
ret = 0;
end:
mutex_unlock(&sc->lock);
@@ -2789,9 +2800,6 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ath5k_hw *ah = sc->ah;
int ret;
- /* Set to a reasonable value. Note that this will
- * be set to mac80211's value at ath5k_config(). */
- sc->bintval = 1000;
mutex_lock(&sc->lock);
if (sc->vif != vif) {
ret = -EIO;
@@ -3050,6 +3058,7 @@ static int
ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ath5k_softc *sc = hw->priv;
+ unsigned long flags;
int ret;
ath5k_debug_dump_skb(sc, skb, "BC ", 1);
@@ -3059,12 +3068,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
goto end;
}
+ spin_lock_irqsave(&sc->block, flags);
ath5k_txbuf_free(sc, sc->bbuf);
sc->bbuf->skb = skb;
ret = ath5k_beacon_setup(sc, sc->bbuf);
if (ret)
sc->bbuf->skb = NULL;
- else {
+ spin_unlock_irqrestore(&sc->block, flags);
+ if (!ret) {
ath5k_beacon_config(sc);
mmiowb();
}
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
index d7e03e6b827..7ec2f377d5c 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -172,6 +172,7 @@ struct ath5k_softc {
struct tasklet_struct txtq; /* tx intr tasklet */
struct ath5k_led tx_led; /* tx led */
+ spinlock_t block; /* protects beacon */
struct ath5k_buf *bbuf; /* beacon buffer */
unsigned int bhalq, /* SW q for outgoing beacons */
bmisscount, /* missed beacon transmits */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index bd35bb0a148..bd65c485098 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1304,7 +1304,7 @@ EXPORT_SYMBOL(atmel_open);
int atmel_open(struct net_device *dev)
{
struct atmel_private *priv = netdev_priv(dev);
- int i, channel;
+ int i, channel, err;
/* any scheduled timer is no longer needed and might screw things up.. */
del_timer_sync(&priv->management_timer);
@@ -1328,8 +1328,9 @@ int atmel_open(struct net_device *dev)
priv->site_survey_state = SITE_SURVEY_IDLE;
priv->station_is_associated = 0;
- if (!reset_atmel_card(dev))
- return -EAGAIN;
+ err = reset_atmel_card(dev);
+ if (err)
+ return err;
if (priv->config_reg_domain) {
priv->reg_domain = priv->config_reg_domain;
@@ -3061,12 +3062,20 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
}
if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
- /* Do opensystem first, then try sharedkey */
+ /* Flip back and forth between WEP auth modes until the max
+ * authentication tries has been exceeded.
+ */
if (system == WLAN_AUTH_OPEN) {
priv->CurrentAuthentTransactionSeqNum = 0x001;
priv->exclude_unencrypted = 1;
send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
return;
+ } else if ( system == WLAN_AUTH_SHARED_KEY
+ && priv->wep_is_on) {
+ priv->CurrentAuthentTransactionSeqNum = 0x001;
+ priv->exclude_unencrypted = 0;
+ send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
+ return;
} else if (priv->connect_to_any_BSS) {
int bss_index;
@@ -3580,12 +3589,12 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
if (i == 0) {
printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
- return 0;
+ return -EIO;
}
if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
- return 0;
+ return -ENODEV;
}
/* now check for completion of MAC initialization through
@@ -3609,19 +3618,19 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
if (i == 0) {
printk(KERN_ALERT "%s: MAC failed to initialise.\n",
priv->dev->name);
- return 0;
+ return -EIO;
}
/* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
if ((mr3 & MAC_INIT_COMPLETE) &&
!(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
- return 0;
+ return -EIO;
}
if ((mr1 & MAC_INIT_COMPLETE) &&
!(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
- return 0;
+ return -EIO;
}
atmel_copy_to_host(priv->dev, (unsigned char *)iface,
@@ -3642,7 +3651,7 @@ static int atmel_wakeup_firmware(struct atmel_private *priv)
iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
iface->mac_status = le16_to_cpu(iface->mac_status);
- return 1;
+ return 0;
}
/* determine type of memory and MAC address */
@@ -3693,7 +3702,7 @@ static int probe_atmel_card(struct net_device *dev)
/* Standard firmware in flash, boot it up and ask
for the Mac Address */
priv->card_type = CARD_TYPE_SPI_FLASH;
- if (atmel_wakeup_firmware(priv)) {
+ if (atmel_wakeup_firmware(priv) == 0) {
atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
/* got address, now squash it again until the network
@@ -3835,6 +3844,7 @@ static int reset_atmel_card(struct net_device *dev)
struct atmel_private *priv = netdev_priv(dev);
u8 configuration;
int old_state = priv->station_state;
+ int err = 0;
/* data to add to the firmware names, in priority order
this implemenents firmware versioning */
@@ -3868,11 +3878,12 @@ static int reset_atmel_card(struct net_device *dev)
dev->name);
strcpy(priv->firmware_id, "atmel_at76c502.bin");
}
- if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) {
+ err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
+ if (err != 0) {
printk(KERN_ALERT
"%s: firmware %s is missing, cannot continue.\n",
dev->name, priv->firmware_id);
- return 0;
+ return err;
}
} else {
int fw_index = 0;
@@ -3901,7 +3912,7 @@ static int reset_atmel_card(struct net_device *dev)
"%s: firmware %s is missing, cannot start.\n",
dev->name, priv->firmware_id);
priv->firmware_id[0] = '\0';
- return 0;
+ return -ENOENT;
}
}
@@ -3926,8 +3937,9 @@ static int reset_atmel_card(struct net_device *dev)
release_firmware(fw_entry);
}
- if (!atmel_wakeup_firmware(priv))
- return 0;
+ err = atmel_wakeup_firmware(priv);
+ if (err != 0)
+ return err;
/* Check the version and set the correct flag for wpa stuff,
old and new firmware is incompatible.
@@ -3968,10 +3980,9 @@ static int reset_atmel_card(struct net_device *dev)
if (!priv->radio_on_broken) {
if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
CMD_STATUS_REJECTED_RADIO_OFF) {
- printk(KERN_INFO
- "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
+ printk(KERN_INFO "%s: cannot turn the radio on.\n",
dev->name);
- return 0;
+ return -EIO;
}
}
@@ -4006,7 +4017,7 @@ static int reset_atmel_card(struct net_device *dev)
wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
}
- return 1;
+ return 0;
}
static void atmel_send_command(struct atmel_private *priv, int command,
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 2450b3a393f..7ba78e6d210 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -38,8 +38,10 @@ void free_cpu_buffers(void)
{
int i;
- for_each_online_cpu(i)
+ for_each_online_cpu(i) {
vfree(per_cpu(cpu_buffer, i).buffer);
+ per_cpu(cpu_buffer, i).buffer = NULL;
+ }
}
int alloc_cpu_buffers(void)
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
index e7fbac52993..8d692a5c8e7 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -93,6 +93,8 @@ out:
void free_event_buffer(void)
{
vfree(event_buffer);
+
+ event_buffer = NULL;
}
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index db85f1fb131..711b3004b3e 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -384,9 +384,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
* get minor, add to list
*/
down_write(&dcssblk_devices_sem);
- if (dcssblk_get_segment_by_name(local_buf)) {
+ if (dcssblk_get_device_by_name(local_buf)) {
+ up_write(&dcssblk_devices_sem);
rc = -EEXIST;
- goto release_gd;
+ goto unload_seg;
}
rc = dcssblk_assign_free_minor(dev_info);
if (rc) {
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index a08b1682c8e..e10ac9ab2d4 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -133,14 +133,14 @@ claw_register_debug_facility(void)
static inline void
claw_set_busy(struct net_device *dev)
{
- ((struct claw_privbk *) dev->priv)->tbusy=1;
+ ((struct claw_privbk *)dev->ml_priv)->tbusy = 1;
eieio();
}
static inline void
claw_clear_busy(struct net_device *dev)
{
- clear_bit(0, &(((struct claw_privbk *) dev->priv)->tbusy));
+ clear_bit(0, &(((struct claw_privbk *) dev->ml_priv)->tbusy));
netif_wake_queue(dev);
eieio();
}
@@ -149,20 +149,20 @@ static inline int
claw_check_busy(struct net_device *dev)
{
eieio();
- return ((struct claw_privbk *) dev->priv)->tbusy;
+ return ((struct claw_privbk *) dev->ml_priv)->tbusy;
}
static inline void
claw_setbit_busy(int nr,struct net_device *dev)
{
netif_stop_queue(dev);
- set_bit(nr, (void *)&(((struct claw_privbk *)dev->priv)->tbusy));
+ set_bit(nr, (void *)&(((struct claw_privbk *)dev->ml_priv)->tbusy));
}
static inline void
claw_clearbit_busy(int nr,struct net_device *dev)
{
- clear_bit(nr,(void *)&(((struct claw_privbk *)dev->priv)->tbusy));
+ clear_bit(nr, (void *)&(((struct claw_privbk *)dev->ml_priv)->tbusy));
netif_wake_queue(dev);
}
@@ -171,7 +171,7 @@ claw_test_and_setbit_busy(int nr,struct net_device *dev)
{
netif_stop_queue(dev);
return test_and_set_bit(nr,
- (void *)&(((struct claw_privbk *) dev->priv)->tbusy));
+ (void *)&(((struct claw_privbk *) dev->ml_priv)->tbusy));
}
@@ -271,6 +271,7 @@ claw_probe(struct ccwgroup_device *cgdev)
if (!get_device(&cgdev->dev))
return -ENODEV;
privptr = kzalloc(sizeof(struct claw_privbk), GFP_KERNEL);
+ cgdev->dev.driver_data = privptr;
if (privptr == NULL) {
probe_error(cgdev);
put_device(&cgdev->dev);
@@ -305,7 +306,6 @@ claw_probe(struct ccwgroup_device *cgdev)
privptr->p_env->p_priv = privptr;
cgdev->cdev[0]->handler = claw_irq_handler;
cgdev->cdev[1]->handler = claw_irq_handler;
- cgdev->dev.driver_data = privptr;
CLAW_DBF_TEXT(2, setup, "prbext 0");
return 0;
@@ -319,7 +319,7 @@ static int
claw_tx(struct sk_buff *skb, struct net_device *dev)
{
int rc;
- struct claw_privbk *privptr=dev->priv;
+ struct claw_privbk *privptr = dev->ml_priv;
unsigned long saveflags;
struct chbk *p_ch;
@@ -404,7 +404,7 @@ claw_pack_skb(struct claw_privbk *privptr)
static int
claw_change_mtu(struct net_device *dev, int new_mtu)
{
- struct claw_privbk *privptr=dev->priv;
+ struct claw_privbk *privptr = dev->ml_priv;
int buff_size;
CLAW_DBF_TEXT(4, trace, "setmtu");
buff_size = privptr->p_env->write_size;
@@ -434,7 +434,7 @@ claw_open(struct net_device *dev)
struct ccwbk *p_buf;
CLAW_DBF_TEXT(4, trace, "open");
- privptr = (struct claw_privbk *)dev->priv;
+ privptr = (struct claw_privbk *)dev->ml_priv;
/* allocate and initialize CCW blocks */
if (privptr->buffs_alloc == 0) {
rc=init_ccw_bk(dev);
@@ -780,7 +780,7 @@ claw_irq_tasklet ( unsigned long data )
p_ch = (struct chbk *) data;
dev = (struct net_device *)p_ch->ndev;
CLAW_DBF_TEXT(4, trace, "IRQtask");
- privptr = (struct claw_privbk *) dev->priv;
+ privptr = (struct claw_privbk *)dev->ml_priv;
unpack_read(dev);
clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a);
CLAW_DBF_TEXT(4, trace, "TskletXt");
@@ -805,7 +805,7 @@ claw_release(struct net_device *dev)
if (!dev)
return 0;
- privptr = (struct claw_privbk *) dev->priv;
+ privptr = (struct claw_privbk *)dev->ml_priv;
if (!privptr)
return 0;
CLAW_DBF_TEXT(4, trace, "release");
@@ -960,7 +960,7 @@ claw_write_next ( struct chbk * p_ch )
if (p_ch->claw_state == CLAW_STOP)
return;
dev = (struct net_device *) p_ch->ndev;
- privptr = (struct claw_privbk *) dev->priv;
+ privptr = (struct claw_privbk *) dev->ml_priv;
claw_free_wrt_buf( dev );
if ((privptr->write_free_count > 0) &&
!skb_queue_empty(&p_ch->collect_queue)) {
@@ -1042,7 +1042,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
struct ccw1 temp_ccw;
struct endccw * p_end;
CLAW_DBF_TEXT(4, trace, "addreads");
- privptr = dev->priv;
+ privptr = dev->ml_priv;
p_end = privptr->p_end_ccw;
/* first CCW and last CCW contains a new set of read channel programs
@@ -1212,7 +1212,7 @@ find_link(struct net_device *dev, char *host_name, char *ws_name )
int rc=0;
CLAW_DBF_TEXT(2, setup, "findlink");
- privptr=dev->priv;
+ privptr = dev->ml_priv;
p_env=privptr->p_env;
switch (p_env->packing)
{
@@ -1264,7 +1264,7 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
struct chbk *ch;
CLAW_DBF_TEXT(4, trace, "hw_tx");
- privptr = (struct claw_privbk *) (dev->priv);
+ privptr = (struct claw_privbk *)(dev->ml_priv);
p_ch=(struct chbk *)&privptr->channel[WRITE];
p_env =privptr->p_env;
claw_free_wrt_buf(dev); /* Clean up free chain if posible */
@@ -1483,8 +1483,8 @@ init_ccw_bk(struct net_device *dev)
struct ccwbk*p_last_CCWB;
struct ccwbk*p_first_CCWB;
struct endccw *p_endccw=NULL;
- addr_t real_address;
- struct claw_privbk *privptr=dev->priv;
+ addr_t real_address;
+ struct claw_privbk *privptr = dev->ml_priv;
struct clawh *pClawH=NULL;
addr_t real_TIC_address;
int i,j;
@@ -1960,19 +1960,16 @@ init_ccw_bk(struct net_device *dev)
static void
probe_error( struct ccwgroup_device *cgdev)
{
- struct claw_privbk *privptr;
+ struct claw_privbk *privptr;
CLAW_DBF_TEXT(4, trace, "proberr");
- privptr=(struct claw_privbk *)cgdev->dev.driver_data;
- if (privptr!=NULL) {
+ privptr = (struct claw_privbk *) cgdev->dev.driver_data;
+ if (privptr != NULL) {
+ cgdev->dev.driver_data = NULL;
kfree(privptr->p_env);
- privptr->p_env=NULL;
- kfree(privptr->p_mtc_envelope);
- privptr->p_mtc_envelope=NULL;
- kfree(privptr);
- privptr=NULL;
- }
- return;
+ kfree(privptr->p_mtc_envelope);
+ kfree(privptr);
+ }
} /* probe_error */
/*-------------------------------------------------------------------*
@@ -2000,7 +1997,7 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
CLAW_DBF_TEXT(2, setup, "clw_cntl");
udelay(1000); /* Wait a ms for the control packets to
*catch up to each other */
- privptr=dev->priv;
+ privptr = dev->ml_priv;
p_env=privptr->p_env;
tdev = &privptr->channel[READ].cdev->dev;
memcpy( &temp_host_name, p_env->host_name, 8);
@@ -2278,7 +2275,7 @@ claw_send_control(struct net_device *dev, __u8 type, __u8 link,
struct sk_buff *skb;
CLAW_DBF_TEXT(2, setup, "sndcntl");
- privptr=dev->priv;
+ privptr = dev->ml_priv;
p_ctl=(struct clawctl *)&privptr->ctl_bk;
p_ctl->command=type;
@@ -2348,7 +2345,7 @@ static int
claw_snd_conn_req(struct net_device *dev, __u8 link)
{
int rc;
- struct claw_privbk *privptr=dev->priv;
+ struct claw_privbk *privptr = dev->ml_priv;
struct clawctl *p_ctl;
CLAW_DBF_TEXT(2, setup, "snd_conn");
@@ -2408,7 +2405,7 @@ claw_snd_sys_validate_rsp(struct net_device *dev,
int rc;
CLAW_DBF_TEXT(2, setup, "chkresp");
- privptr = dev->priv;
+ privptr = dev->ml_priv;
p_env=privptr->p_env;
rc=claw_send_control(dev, SYSTEM_VALIDATE_RESPONSE,
p_ctl->linkid,
@@ -2446,7 +2443,7 @@ net_device_stats *claw_stats(struct net_device *dev)
struct claw_privbk *privptr;
CLAW_DBF_TEXT(4, trace, "stats");
- privptr = dev->priv;
+ privptr = dev->ml_priv;
return &privptr->stats;
} /* end of claw_stats */
@@ -2482,7 +2479,7 @@ unpack_read(struct net_device *dev )
p_last_ccw=NULL;
p_packh=NULL;
p_packd=NULL;
- privptr=dev->priv;
+ privptr = dev->ml_priv;
p_dev = &privptr->channel[READ].cdev->dev;
p_env = privptr->p_env;
@@ -2651,7 +2648,7 @@ claw_strt_read (struct net_device *dev, int lock )
int rc = 0;
__u32 parm;
unsigned long saveflags = 0;
- struct claw_privbk *privptr=dev->priv;
+ struct claw_privbk *privptr = dev->ml_priv;
struct ccwbk*p_ccwbk;
struct chbk *p_ch;
struct clawh *p_clawh;
@@ -2708,7 +2705,7 @@ claw_strt_out_IO( struct net_device *dev )
if (!dev) {
return;
}
- privptr=(struct claw_privbk *)dev->priv;
+ privptr = (struct claw_privbk *)dev->ml_priv;
p_ch=&privptr->channel[WRITE];
CLAW_DBF_TEXT(4, trace, "strt_io");
@@ -2741,7 +2738,7 @@ static void
claw_free_wrt_buf( struct net_device *dev )
{
- struct claw_privbk *privptr=(struct claw_privbk *)dev->priv;
+ struct claw_privbk *privptr = (struct claw_privbk *)dev->ml_priv;
struct ccwbk*p_first_ccw;
struct ccwbk*p_last_ccw;
struct ccwbk*p_this_ccw;
@@ -2798,13 +2795,13 @@ claw_free_netdevice(struct net_device * dev, int free_dev)
if (!dev)
return;
CLAW_DBF_TEXT_(2, setup, "%s", dev->name);
- privptr = dev->priv;
+ privptr = dev->ml_priv;
if (dev->flags & IFF_RUNNING)
claw_release(dev);
if (privptr) {
privptr->channel[READ].ndev = NULL; /* say it's free */
}
- dev->priv=NULL;
+ dev->ml_priv = NULL;
#ifdef MODULE
if (free_dev) {
free_netdev(dev);
@@ -2921,7 +2918,7 @@ claw_new_device(struct ccwgroup_device *cgdev)
printk(KERN_WARNING "%s:alloc_netdev failed\n",__func__);
goto out;
}
- dev->priv = privptr;
+ dev->ml_priv = privptr;
cgdev->dev.driver_data = privptr;
cgdev->cdev[READ]->dev.driver_data = privptr;
cgdev->cdev[WRITE]->dev.driver_data = privptr;
@@ -3002,7 +2999,7 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
ret = claw_release(ndev);
ndev->flags &=~IFF_RUNNING;
unregister_netdev(ndev);
- ndev->priv = NULL; /* cgdev data, not ndev's to free */
+ ndev->ml_priv = NULL; /* cgdev data, not ndev's to free */
claw_free_netdevice(ndev, 1);
priv->channel[READ].ndev = NULL;
priv->channel[WRITE].ndev = NULL;
diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c
index 0b4e6253abe..42776550acf 100644
--- a/drivers/s390/net/ctcm_fsms.c
+++ b/drivers/s390/net/ctcm_fsms.c
@@ -245,7 +245,7 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct sk_buff *skb;
int first = 1;
int i;
@@ -336,7 +336,7 @@ void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCM_PR_DEBUG("%s(%s): %s\n", __func__, ch->id, dev->name);
@@ -357,7 +357,7 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
int len = ch->max_bufsize - ch->irb->scsw.cmd.count;
struct sk_buff *skb = ch->trans_skb;
__u16 block_len = *((__u16 *)skb->data);
@@ -459,7 +459,7 @@ static void chx_firstio(fsm_instance *fi, int event, void *arg)
chx_rxidle(fi, event, arg);
} else {
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
fsm_newstate(fi, CTC_STATE_TXIDLE);
fsm_event(priv->fsm, DEV_EVENT_TXUP, dev);
}
@@ -496,7 +496,7 @@ static void chx_firstio(fsm_instance *fi, int event, void *arg)
if ((CHANNEL_DIRECTION(ch->flags) == READ) &&
(ch->protocol == CTCM_PROTO_S390)) {
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
fsm_event(priv->fsm, DEV_EVENT_RXUP, dev);
}
}
@@ -514,7 +514,7 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
__u16 buflen;
int rc;
@@ -699,7 +699,7 @@ static void ctcm_chx_cleanup(fsm_instance *fi, int state,
struct channel *ch)
{
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCM_DBF_TEXT_(SETUP, CTC_DBF_NOTICE,
"%s(%s): %s[%d]\n",
@@ -784,7 +784,7 @@ static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
/*
* Special case: Got UC_RCRESET on setmode.
@@ -874,7 +874,7 @@ static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
if (event == CTC_EVENT_TIMER) {
if (!IS_MPCDEV(dev))
@@ -902,7 +902,7 @@ static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
"%s(%s): RX %s busy, init. fail",
@@ -923,7 +923,7 @@ static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg)
struct channel *ch = arg;
struct channel *ch2;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
"%s: %s: remote disconnect - re-init ...",
@@ -954,7 +954,7 @@ static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
if (event == CTC_EVENT_TIMER) {
fsm_deltimer(&ch->timer);
@@ -984,7 +984,7 @@ static void ctcm_chx_txretry(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct sk_buff *skb;
CTCM_PR_DEBUG("Enter: %s: cp=%i ch=0x%p id=%s\n",
@@ -1057,7 +1057,7 @@ static void ctcm_chx_iofatal(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
int rd = CHANNEL_DIRECTION(ch->flags);
fsm_deltimer(&ch->timer);
@@ -1207,7 +1207,7 @@ static void ctcmpc_chx_txdone(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct sk_buff *skb;
int first = 1;
@@ -1368,7 +1368,7 @@ static void ctcmpc_chx_rx(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct sk_buff *skb = ch->trans_skb;
struct sk_buff *new_skb;
@@ -1471,7 +1471,7 @@ static void ctcmpc_chx_firstio(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *gptr = priv->mpcg;
CTCM_PR_DEBUG("Enter %s: id=%s, ch=0x%p\n",
@@ -1525,7 +1525,7 @@ void ctcmpc_chx_rxidle(fsm_instance *fi, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
int rc;
unsigned long saveflags = 0; /* avoids compiler warning */
@@ -1580,7 +1580,7 @@ static void ctcmpc_chx_attn(fsm_instance *fsm, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
CTCM_PR_DEBUG("%s(%s): %s(ch=0x%p), cp=%i, ChStat:%s, GrpStat:%s\n",
@@ -1639,7 +1639,7 @@ static void ctcmpc_chx_attnbusy(fsm_instance *fsm, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
CTCM_PR_DEBUG("%s(%s): %s\n ChState:%s GrpState:%s\n",
@@ -1724,7 +1724,7 @@ static void ctcmpc_chx_resend(fsm_instance *fsm, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
fsm_event(grp->fsm, MPCG_EVENT_XID0DO, ch);
@@ -1740,7 +1740,7 @@ static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg)
{
struct channel *ach = arg;
struct net_device *dev = ach->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct channel *wch = priv->channel[WRITE];
struct channel *rch = priv->channel[READ];
@@ -2050,7 +2050,7 @@ int mpc_ch_fsm_len = ARRAY_SIZE(ctcmpc_ch_fsm);
static void dev_action_start(fsm_instance *fi, int event, void *arg)
{
struct net_device *dev = arg;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
int direction;
CTCMY_DBF_DEV_NAME(SETUP, dev, "");
@@ -2076,7 +2076,7 @@ static void dev_action_stop(fsm_instance *fi, int event, void *arg)
{
int direction;
struct net_device *dev = arg;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCMY_DBF_DEV_NAME(SETUP, dev, "");
@@ -2096,7 +2096,7 @@ static void dev_action_restart(fsm_instance *fi, int event, void *arg)
{
int restart_timer;
struct net_device *dev = arg;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCMY_DBF_DEV_NAME(TRACE, dev, "");
@@ -2133,12 +2133,12 @@ static void dev_action_restart(fsm_instance *fi, int event, void *arg)
static void dev_action_chup(fsm_instance *fi, int event, void *arg)
{
struct net_device *dev = arg;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
int dev_stat = fsm_getstate(fi);
CTCM_DBF_TEXT_(SETUP, CTC_DBF_NOTICE,
"%s(%s): priv = %p [%d,%d]\n ", CTCM_FUNTAIL,
- dev->name, dev->priv, dev_stat, event);
+ dev->name, dev->ml_priv, dev_stat, event);
switch (fsm_getstate(fi)) {
case DEV_STATE_STARTWAIT_RXTX:
@@ -2195,7 +2195,7 @@ static void dev_action_chdown(fsm_instance *fi, int event, void *arg)
{
struct net_device *dev = arg;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCMY_DBF_DEV_NAME(SETUP, dev, "");
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 126a3ebb8ab..b11fec24c7d 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -69,7 +69,7 @@ struct channel *channels;
void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
{
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
__u16 len = *((__u16 *) pskb->data);
skb_put(pskb, 2 + LL_HEADER_LENGTH);
@@ -414,7 +414,7 @@ int ctcm_ch_alloc_buffer(struct channel *ch)
*/
int ctcm_open(struct net_device *dev)
{
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCMY_DBF_DEV_NAME(SETUP, dev, "");
if (!IS_MPC(priv))
@@ -432,7 +432,7 @@ int ctcm_open(struct net_device *dev)
*/
int ctcm_close(struct net_device *dev)
{
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
CTCMY_DBF_DEV_NAME(SETUP, dev, "");
if (!IS_MPC(priv))
@@ -573,7 +573,7 @@ static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
skb_pull(skb, LL_HEADER_LENGTH + 2);
} else if (ccw_idx == 0) {
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
priv->stats.tx_packets++;
priv->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
}
@@ -592,7 +592,7 @@ static void ctcmpc_send_sweep_req(struct channel *rch)
struct channel *ch;
/* int rc = 0; */
- priv = dev->priv;
+ priv = dev->ml_priv;
grp = priv->mpcg;
ch = priv->channel[WRITE];
@@ -652,7 +652,7 @@ static int ctcmpc_transmit_skb(struct channel *ch, struct sk_buff *skb)
{
struct pdu *p_header;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct th_header *header;
struct sk_buff *nskb;
@@ -867,7 +867,7 @@ done:
/* first merge version - leaving both functions separated */
static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
{
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
if (skb == NULL) {
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
@@ -911,7 +911,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
{
int len = 0;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct sk_buff *newskb = NULL;
@@ -1025,7 +1025,7 @@ static int ctcm_change_mtu(struct net_device *dev, int new_mtu)
if (new_mtu < 576 || new_mtu > 65527)
return -EINVAL;
- priv = dev->priv;
+ priv = dev->ml_priv;
max_bufsize = priv->channel[READ]->max_bufsize;
if (IS_MPC(priv)) {
@@ -1050,7 +1050,7 @@ static int ctcm_change_mtu(struct net_device *dev, int new_mtu)
*/
static struct net_device_stats *ctcm_stats(struct net_device *dev)
{
- return &((struct ctcm_priv *)dev->priv)->stats;
+ return &((struct ctcm_priv *)dev->ml_priv)->stats;
}
static void ctcm_free_netdevice(struct net_device *dev)
@@ -1060,7 +1060,7 @@ static void ctcm_free_netdevice(struct net_device *dev)
CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
"%s(%s)", CTCM_FUNTAIL, dev->name);
- priv = dev->priv;
+ priv = dev->ml_priv;
if (priv) {
grp = priv->mpcg;
if (grp) {
@@ -1125,7 +1125,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
CTCM_FUNTAIL);
return NULL;
}
- dev->priv = priv;
+ dev->ml_priv = priv;
priv->fsm = init_fsm("ctcmdev", dev_state_names, dev_event_names,
CTCM_NR_DEV_STATES, CTCM_NR_DEV_EVENTS,
dev_fsm, dev_fsm_len, GFP_KERNEL);
diff --git a/drivers/s390/net/ctcm_main.h b/drivers/s390/net/ctcm_main.h
index a72e0feeb27..8e10ee86a5e 100644
--- a/drivers/s390/net/ctcm_main.h
+++ b/drivers/s390/net/ctcm_main.h
@@ -229,14 +229,14 @@ void ctcm_remove_files(struct device *dev);
*/
static inline void ctcm_clear_busy_do(struct net_device *dev)
{
- clear_bit(0, &(((struct ctcm_priv *)dev->priv)->tbusy));
+ clear_bit(0, &(((struct ctcm_priv *)dev->ml_priv)->tbusy));
netif_wake_queue(dev);
}
static inline void ctcm_clear_busy(struct net_device *dev)
{
struct mpc_group *grp;
- grp = ((struct ctcm_priv *)dev->priv)->mpcg;
+ grp = ((struct ctcm_priv *)dev->ml_priv)->mpcg;
if (!(grp && grp->in_sweep))
ctcm_clear_busy_do(dev);
@@ -246,7 +246,8 @@ static inline void ctcm_clear_busy(struct net_device *dev)
static inline int ctcm_test_and_set_busy(struct net_device *dev)
{
netif_stop_queue(dev);
- return test_and_set_bit(0, &(((struct ctcm_priv *)dev->priv)->tbusy));
+ return test_and_set_bit(0,
+ &(((struct ctcm_priv *)dev->ml_priv)->tbusy));
}
extern int loglevel;
@@ -292,7 +293,7 @@ struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv);
#define IS_MPC(p) ((p)->protocol == CTCM_PROTO_MPC)
/* test if struct ctcm_priv of struct net_device has MPC protocol setting */
-#define IS_MPCDEV(d) IS_MPC((struct ctcm_priv *)d->priv)
+#define IS_MPCDEV(dev) IS_MPC((struct ctcm_priv *)dev->ml_priv)
static inline gfp_t gfp_type(void)
{
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index 2de1e2fccbf..cbe470493bf 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -312,10 +312,10 @@ static struct net_device *ctcmpc_get_dev(int port_num)
CTCM_FUNTAIL, device);
return NULL;
}
- priv = dev->priv;
+ priv = dev->ml_priv;
if (priv == NULL) {
CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
- "%s(%s): dev->priv is NULL",
+ "%s(%s): dev->ml_priv is NULL",
CTCM_FUNTAIL, device);
return NULL;
}
@@ -344,7 +344,7 @@ int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int))
dev = ctcmpc_get_dev(port_num);
if (dev == NULL)
return 1;
- priv = dev->priv;
+ priv = dev->ml_priv;
grp = priv->mpcg;
grp->allochanfunc = callback;
@@ -416,7 +416,7 @@ void ctc_mpc_establish_connectivity(int port_num,
dev = ctcmpc_get_dev(port_num);
if (dev == NULL)
return;
- priv = dev->priv;
+ priv = dev->ml_priv;
grp = priv->mpcg;
rch = priv->channel[READ];
wch = priv->channel[WRITE];
@@ -534,7 +534,7 @@ void ctc_mpc_dealloc_ch(int port_num)
dev = ctcmpc_get_dev(port_num);
if (dev == NULL)
return;
- priv = dev->priv;
+ priv = dev->ml_priv;
grp = priv->mpcg;
CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_DEBUG,
@@ -570,7 +570,7 @@ void ctc_mpc_flow_control(int port_num, int flowc)
dev = ctcmpc_get_dev(port_num);
if (dev == NULL)
return;
- priv = dev->priv;
+ priv = dev->ml_priv;
grp = priv->mpcg;
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_DEBUG,
@@ -619,7 +619,7 @@ static void mpc_rcvd_sweep_resp(struct mpcg_info *mpcginfo)
{
struct channel *rch = mpcginfo->ch;
struct net_device *dev = rch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct channel *ch = priv->channel[WRITE];
@@ -650,7 +650,7 @@ static void mpc_rcvd_sweep_resp(struct mpcg_info *mpcginfo)
static void ctcmpc_send_sweep_resp(struct channel *rch)
{
struct net_device *dev = rch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
int rc = 0;
struct th_sweep *header;
@@ -712,7 +712,7 @@ static void mpc_rcvd_sweep_req(struct mpcg_info *mpcginfo)
{
struct channel *rch = mpcginfo->ch;
struct net_device *dev = rch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct channel *ch = priv->channel[WRITE];
@@ -846,7 +846,7 @@ static int mpcg_fsm_len = ARRAY_SIZE(mpcg_fsm);
static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg)
{
struct net_device *dev = arg;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
if (grp == NULL) {
@@ -890,7 +890,7 @@ static void mpc_action_go_ready(fsm_instance *fsm, int event, void *arg)
void mpc_group_ready(unsigned long adev)
{
struct net_device *dev = (struct net_device *)adev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct channel *ch = NULL;
@@ -946,7 +946,7 @@ void mpc_group_ready(unsigned long adev)
void mpc_channel_action(struct channel *ch, int direction, int action)
{
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
if (grp == NULL) {
@@ -1056,7 +1056,7 @@ done:
static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
{
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct pdu *curr_pdu;
struct mpcg_info *mpcginfo;
@@ -1254,7 +1254,7 @@ void ctcmpc_bh(unsigned long thischan)
struct channel *ch = (struct channel *)thischan;
struct sk_buff *skb;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
CTCM_PR_DEBUG("%s cp:%i enter: %s() %s\n",
@@ -1376,7 +1376,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
BUG_ON(dev == NULL);
CTCM_PR_DEBUG("Enter %s: %s\n", __func__, dev->name);
- priv = dev->priv;
+ priv = dev->ml_priv;
grp = priv->mpcg;
grp->flow_off_called = 0;
fsm_deltimer(&grp->timer);
@@ -1482,7 +1482,7 @@ static void mpc_action_timeout(fsm_instance *fi, int event, void *arg)
BUG_ON(dev == NULL);
- priv = dev->priv;
+ priv = dev->ml_priv;
grp = priv->mpcg;
wch = priv->channel[WRITE];
rch = priv->channel[READ];
@@ -1520,7 +1520,7 @@ void mpc_action_discontact(fsm_instance *fi, int event, void *arg)
if (ch) {
dev = ch->netdev;
if (dev) {
- priv = dev->priv;
+ priv = dev->ml_priv;
if (priv) {
CTCM_DBF_TEXT_(MPC_TRACE, CTC_DBF_NOTICE,
"%s: %s: %s\n",
@@ -1568,7 +1568,7 @@ static int mpc_validate_xid(struct mpcg_info *mpcginfo)
{
struct channel *ch = mpcginfo->ch;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
struct xid2 *xid = mpcginfo->xid;
int rc = 0;
@@ -1865,7 +1865,7 @@ static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg)
{
struct channel *ch = arg;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
CTCM_PR_DEBUG("Enter %s: cp=%i ch=0x%p id=%s\n",
@@ -1905,7 +1905,7 @@ static void mpc_action_doxid0(fsm_instance *fsm, int event, void *arg)
static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg)
{
struct net_device *dev = arg;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = NULL;
int direction;
int send = 0;
@@ -1982,7 +1982,7 @@ static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg)
struct mpcg_info *mpcginfo = arg;
struct channel *ch = mpcginfo->ch;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
CTCM_PR_DEBUG("%s: ch-id:%s xid2:%i xid7:%i xidt_p2:%i \n",
@@ -2044,7 +2044,7 @@ static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg)
struct mpcg_info *mpcginfo = arg;
struct channel *ch = mpcginfo->ch;
struct net_device *dev = ch->netdev;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
CTCM_PR_DEBUG("Enter %s: cp=%i ch=0x%p id=%s\n",
@@ -2096,7 +2096,7 @@ static int mpc_send_qllc_discontact(struct net_device *dev)
__u32 new_len = 0;
struct sk_buff *skb;
struct qllc *qllcptr;
- struct ctcm_priv *priv = dev->priv;
+ struct ctcm_priv *priv = dev->ml_priv;
struct mpc_group *grp = priv->mpcg;
CTCM_PR_DEBUG("%s: GROUP STATE: %s\n",
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 6de28385b35..9bcfa04d863 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1412,7 +1412,8 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
}
/* How far in the ccw chain have we processed? */
if ((channel->state != LCS_CH_STATE_INIT) &&
- (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC)) {
+ (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
+ (irb->scsw.cmd.cpa != 0)) {
index = (struct ccw1 *) __va((addr_t) irb->scsw.cmd.cpa)
- channel->ccws;
if ((irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED) ||
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 80971c21ea1..bf8a75c92f2 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -689,6 +689,7 @@ struct qeth_mc_mac {
struct list_head list;
__u8 mc_addr[MAX_ADDR_LEN];
unsigned char mc_addrlen;
+ int is_vmac;
};
struct qeth_card {
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index bd420d1b9a0..c7ab1b86451 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3024,7 +3024,7 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb,
struct qdio_buffer *buffer, int is_tso, int *next_element_to_fill,
int offset)
{
- int length = skb->len;
+ int length = skb->len - offset;
int length_here;
int element;
char *data;
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index b3cee032f57..3ac3cc1e03c 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -177,9 +177,10 @@ static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
qeth_l2_send_delgroupmac_cb);
}
-static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac)
+static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac)
{
struct qeth_mc_mac *mc;
+ int rc;
mc = kmalloc(sizeof(struct qeth_mc_mac), GFP_ATOMIC);
@@ -188,8 +189,16 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac)
memcpy(mc->mc_addr, mac, OSA_ADDR_LEN);
mc->mc_addrlen = OSA_ADDR_LEN;
+ mc->is_vmac = vmac;
+
+ if (vmac) {
+ rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC,
+ NULL);
+ } else {
+ rc = qeth_l2_send_setgroupmac(card, mac);
+ }
- if (!qeth_l2_send_setgroupmac(card, mac))
+ if (!rc)
list_add_tail(&mc->list, &card->mc_list);
else
kfree(mc);
@@ -201,7 +210,11 @@ static void qeth_l2_del_all_mc(struct qeth_card *card)
spin_lock_bh(&card->mclock);
list_for_each_entry_safe(mc, tmp, &card->mc_list, list) {
- qeth_l2_send_delgroupmac(card, mc->mc_addr);
+ if (mc->is_vmac)
+ qeth_l2_send_setdelmac(card, mc->mc_addr,
+ IPA_CMD_DELVMAC, NULL);
+ else
+ qeth_l2_send_delgroupmac(card, mc->mc_addr);
list_del(&mc->list);
kfree(mc);
}
@@ -590,7 +603,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
static void qeth_l2_set_multicast_list(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
- struct dev_mc_list *dm;
+ struct dev_addr_list *dm;
if (card->info.type == QETH_CARD_TYPE_OSN)
return ;
@@ -599,7 +612,11 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
qeth_l2_del_all_mc(card);
spin_lock_bh(&card->mclock);
for (dm = dev->mc_list; dm; dm = dm->next)
- qeth_l2_add_mc(card, dm->dmi_addr);
+ qeth_l2_add_mc(card, dm->da_addr, 0);
+
+ for (dm = dev->uc_list; dm; dm = dm->next)
+ qeth_l2_add_mc(card, dm->da_addr, 1);
+
spin_unlock_bh(&card->mclock);
if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
return;
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index ac1993708ae..210ddb63974 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -136,7 +136,7 @@ static ssize_t qeth_l3_dev_route6_store(struct device *dev,
return -EINVAL;
if (!qeth_is_supported(card, IPA_IPV6)) {
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}
return qeth_l3_dev_route_store(card, &card->options.route6,
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 3d36270a8b4..661f9f21650 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -217,6 +217,18 @@ static int sg_last_dev(void);
#define SZ_SG_IOVEC sizeof(sg_iovec_t)
#define SZ_SG_REQ_INFO sizeof(sg_req_info_t)
+static int sg_allow_access(struct file *filp, unsigned char *cmd)
+{
+ struct sg_fd *sfp = (struct sg_fd *)filp->private_data;
+ struct request_queue *q = sfp->parentdp->device->request_queue;
+
+ if (sfp->parentdp->device->type == TYPE_SCANNER)
+ return 0;
+
+ return blk_verify_command(&q->cmd_filter,
+ cmd, filp->f_mode & FMODE_WRITE);
+}
+
static int
sg_open(struct inode *inode, struct file *filp)
{
@@ -689,7 +701,7 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
sg_remove_request(sfp, srp);
return -EFAULT;
}
- if (read_only && !blk_verify_command(file, cmnd)) {
+ if (read_only && sg_allow_access(file, cmnd)) {
sg_remove_request(sfp, srp);
return -EPERM;
}
@@ -793,6 +805,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
return -ENXIO;
+
SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: %s, cmd=0x%x\n",
sdp->disk->disk_name, (int) cmd_in));
read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));
@@ -1061,7 +1074,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
if (copy_from_user(&opcode, siocp->data, 1))
return -EFAULT;
- if (!blk_verify_command(filp, &opcode))
+ if (sg_allow_access(filp, &opcode))
return -EPERM;
}
return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p);
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index efcd44344fb..4a0d30bed9f 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -28,7 +28,7 @@
#endif
#include <asm/gpio.h>
-#include <asm/mach/bfin_serial_5xx.h>
+#include <mach/bfin_serial_5xx.h>
#ifdef CONFIG_SERIAL_BFIN_DMA
#include <linux/dma-mapping.h>
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index 6d5aa806777..7644ed24956 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -58,7 +58,7 @@
#include <asm/gpio.h>
#include <asm/portmux.h>
-#include <asm/mach/bf54x-lq043.h>
+#include <mach/bf54x-lq043.h>
#define NO_BL_SUPPORT
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index db20542796b..c5103671670 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -465,6 +465,16 @@ config PC87413_WDT
Most people will say N.
+config RDC321X_WDT
+ tristate "RDC R-321x SoC watchdog"
+ depends on X86_RDC321X
+ help
+ This is the driver for the built in hardware watchdog
+ in the RDC R-321x SoC.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rdc321x_wdt.
+
config 60XX_WDT
tristate "SBC-60XX Watchdog Timer"
depends on X86
@@ -633,6 +643,16 @@ config SBC_EPX_C3_WATCHDOG
# MIPS Architecture
+config RC32434_WDT
+ tristate "IDT RC32434 SoC Watchdog Timer"
+ depends on MIKROTIK_RB532
+ help
+ Hardware driver for the IDT RC32434 SoC built-in
+ watchdog timer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rc32434_wdt.
+
config INDYDOG
tristate "Indy/I2 Hardware Watchdog"
depends on SGI_HAS_INDYDOG
@@ -692,10 +712,6 @@ config MPC5200_WDT
tristate "MPC5200 Watchdog Timer"
depends on PPC_MPC52xx
-config 8xx_WDT
- tristate "MPC8xx Watchdog Timer"
- depends on 8xx
-
config 8xxx_WDT
tristate "MPC8xxx Platform Watchdog Timer"
depends on PPC_8xx || PPC_83xx || PPC_86xx
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index ca3dc043d78..e0ef123fbde 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_PC87413_WDT) += pc87413_wdt.o
+obj-$(CONFIG_RDC321X_WDT) += rdc321x_wdt.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
obj-$(CONFIG_SBC7240_WDT) += sbc7240_wdt.o
@@ -94,6 +95,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
# M68KNOMMU Architecture
# MIPS Architecture
+obj-$(CONFIG_RC32434_WDT) += rc32434_wdt.o
obj-$(CONFIG_INDYDOG) += indydog.o
obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
@@ -104,7 +106,6 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
# PARISC Architecture
# POWERPC Architecture
-obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o
obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o
obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index d061f0ad2d2..993e5f52afe 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -241,7 +241,7 @@ static int at91wdt_resume(struct platform_device *pdev)
{
if (at91wdt_busy)
at91_wdt_start();
- return 0;
+ return 0;
}
#else
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index d039d5f2fd1..a3765e0be4a 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -116,6 +116,7 @@ static unsigned int reload; /* the computed soft_margin */
static int nowayout = WATCHDOG_NOWAYOUT;
static char expect_release;
static unsigned long hpwdt_is_open;
+static unsigned int allow_kdump;
static void __iomem *pci_mem_addr; /* the PCI-memory address */
static unsigned long __iomem *hpwdt_timer_reg;
@@ -221,19 +222,19 @@ static int __devinit cru_detect(unsigned long map_entry,
if (cmn_regs.u1.ral != 0) {
printk(KERN_WARNING
- "hpwdt: Call succeeded but with an error: 0x%x\n",
- cmn_regs.u1.ral);
+ "hpwdt: Call succeeded but with an error: 0x%x\n",
+ cmn_regs.u1.ral);
} else {
physical_bios_base = cmn_regs.u2.rebx;
physical_bios_offset = cmn_regs.u4.redx;
cru_length = cmn_regs.u3.recx;
cru_physical_address =
- physical_bios_base + physical_bios_offset;
+ physical_bios_base + physical_bios_offset;
/* If the values look OK, then map it in. */
if ((physical_bios_base + physical_bios_offset)) {
cru_rom_addr =
- ioremap(cru_physical_address, cru_length);
+ ioremap(cru_physical_address, cru_length);
if (cru_rom_addr)
retval = 0;
}
@@ -356,7 +357,6 @@ asm(".text \n\t"
"call *%r12 \n\t"
"pushfq \n\t"
"popq %r12 \n\t"
- "popfq \n\t"
"movl %eax, (%r9) \n\t"
"movl %ebx, 4(%r9) \n\t"
"movl %ecx, 8(%r9) \n\t"
@@ -390,10 +390,10 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm)
smbios_cru64_ptr = (struct smbios_cru64_info *) dm;
if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) {
cru_physical_address =
- smbios_cru64_ptr->physical_address +
- smbios_cru64_ptr->double_offset;
+ smbios_cru64_ptr->physical_address +
+ smbios_cru64_ptr->double_offset;
cru_rom_addr = ioremap(cru_physical_address,
- smbios_cru64_ptr->double_length);
+ smbios_cru64_ptr->double_length);
}
}
}
@@ -405,7 +405,7 @@ static int __devinit detect_cru_service(void)
dmi_walk(dmi_find_cru);
/* if cru_rom_addr has been set then we found a CRU service */
- return ((cru_rom_addr != NULL) ? 0: -ENODEV);
+ return ((cru_rom_addr != NULL) ? 0 : -ENODEV);
}
/* ------------------------------------------------------------------------- */
@@ -413,34 +413,6 @@ static int __devinit detect_cru_service(void)
#endif
/*
- * NMI Handler
- */
-static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
- void *data)
-{
- unsigned long rom_pl;
- static int die_nmi_called;
-
- if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
- return NOTIFY_OK;
-
- spin_lock_irqsave(&rom_lock, rom_pl);
- if (!die_nmi_called)
- asminline_call(&cmn_regs, cru_rom_addr);
- die_nmi_called = 1;
- spin_unlock_irqrestore(&rom_lock, rom_pl);
- if (cmn_regs.u1.ral == 0) {
- printk(KERN_WARNING "hpwdt: An NMI occurred, "
- "but unable to determine source.\n");
- } else {
- panic("An NMI occurred, please see the Integrated "
- "Management Log for details.\n");
- }
-
- return NOTIFY_STOP;
-}
-
-/*
* Watchdog operations
*/
static void hpwdt_start(void)
@@ -484,6 +456,36 @@ static int hpwdt_change_timer(int new_margin)
}
/*
+ * NMI Handler
+ */
+static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
+ void *data)
+{
+ unsigned long rom_pl;
+ static int die_nmi_called;
+
+ if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
+ return NOTIFY_OK;
+
+ spin_lock_irqsave(&rom_lock, rom_pl);
+ if (!die_nmi_called)
+ asminline_call(&cmn_regs, cru_rom_addr);
+ die_nmi_called = 1;
+ spin_unlock_irqrestore(&rom_lock, rom_pl);
+ if (cmn_regs.u1.ral == 0) {
+ printk(KERN_WARNING "hpwdt: An NMI occurred, "
+ "but unable to determine source.\n");
+ } else {
+ if (allow_kdump)
+ hpwdt_stop();
+ panic("An NMI occurred, please see the Integrated "
+ "Management Log for details.\n");
+ }
+
+ return NOTIFY_STOP;
+}
+
+/*
* /dev/watchdog handling
*/
static int hpwdt_open(struct inode *inode, struct file *file)
@@ -625,17 +627,18 @@ static struct notifier_block die_notifier = {
*/
static int __devinit hpwdt_init_one(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
int retval;
/*
* First let's find out if we are on an iLO2 server. We will
* not run on a legacy ASM box.
+ * So we only support the G5 ProLiant servers and higher.
*/
if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) {
dev_warn(&dev->dev,
- "This server does not have an iLO2 ASIC.\n");
+ "This server does not have an iLO2 ASIC.\n");
return -ENODEV;
}
@@ -669,7 +672,7 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
retval = detect_cru_service();
if (retval < 0) {
dev_warn(&dev->dev,
- "Unable to detect the %d Bit CRU Service.\n",
+ "Unable to detect the %d Bit CRU Service.\n",
HPWDT_ARCH);
goto error_get_cru;
}
@@ -684,7 +687,7 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
retval = register_die_notifier(&die_notifier);
if (retval != 0) {
dev_warn(&dev->dev,
- "Unable to register a die notifier (err=%d).\n",
+ "Unable to register a die notifier (err=%d).\n",
retval);
goto error_die_notifier;
}
@@ -699,8 +702,9 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
printk(KERN_INFO
"hp Watchdog Timer Driver: 1.00"
- ", timer margin: %d seconds( nowayout=%d).\n",
- soft_margin, nowayout);
+ ", timer margin: %d seconds (nowayout=%d)"
+ ", allow kernel dump: %s (default = 0/OFF).\n",
+ soft_margin, nowayout, (allow_kdump == 0) ? "OFF" : "ON");
return 0;
@@ -755,6 +759,9 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
module_param(soft_margin, int, 0);
MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
+module_param(allow_kdump, int, 0);
+MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
+
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
deleted file mode 100644
index 1336425acf2..00000000000
--- a/drivers/watchdog/mpc8xx_wdt.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * mpc8xx_wdt.c - MPC8xx watchdog userspace interface
- *
- * Author: Florian Schirmer <jolt@tuxbox.org>
- *
- * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/miscdevice.h>
-#include <linux/module.h>
-#include <linux/watchdog.h>
-#include <asm/8xx_immap.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <syslib/m8xx_wdt.h>
-
-static unsigned long wdt_opened;
-static int wdt_status;
-static spinlock_t wdt_lock;
-
-static void mpc8xx_wdt_handler_disable(void)
-{
- volatile uint __iomem *piscr;
- piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr;
-
- if (!m8xx_has_internal_rtc)
- m8xx_wdt_stop_timer();
- else
- out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE));
- printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n");
-}
-
-static void mpc8xx_wdt_handler_enable(void)
-{
- volatile uint __iomem *piscr;
- piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr;
-
- if (!m8xx_has_internal_rtc)
- m8xx_wdt_install_timer();
- else
- out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE);
- printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n");
-}
-
-static int mpc8xx_wdt_open(struct inode *inode, struct file *file)
-{
- if (test_and_set_bit(0, &wdt_opened))
- return -EBUSY;
- m8xx_wdt_reset();
- mpc8xx_wdt_handler_disable();
- return nonseekable_open(inode, file);
-}
-
-static int mpc8xx_wdt_release(struct inode *inode, struct file *file)
-{
- m8xx_wdt_reset();
-#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
- mpc8xx_wdt_handler_enable();
-#endif
- clear_bit(0, &wdt_opened);
- return 0;
-}
-
-static ssize_t mpc8xx_wdt_write(struct file *file, const char *data,
- size_t len, loff_t *ppos)
-{
- if (len) {
- spin_lock(&wdt_lock);
- m8xx_wdt_reset();
- spin_unlock(&wdt_lock);
- }
- return len;
-}
-
-static long mpc8xx_wdt_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int timeout;
- static struct watchdog_info info = {
- .options = WDIOF_KEEPALIVEPING,
- .firmware_version = 0,
- .identity = "MPC8xx watchdog",
- };
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- if (copy_to_user((void *)arg, &info, sizeof(info)))
- return -EFAULT;
- break;
-
- case WDIOC_GETSTATUS:
- case WDIOC_GETBOOTSTATUS:
- if (put_user(wdt_status, (int *)arg))
- return -EFAULT;
- wdt_status &= ~WDIOF_KEEPALIVEPING;
- break;
-
- case WDIOC_GETTEMP:
- return -EOPNOTSUPP;
-
- case WDIOC_SETOPTIONS:
- return -EOPNOTSUPP;
-
- case WDIOC_KEEPALIVE:
- spin_lock(&wdt_lock);
- m8xx_wdt_reset();
- wdt_status |= WDIOF_KEEPALIVEPING;
- spin_unlock(&wdt_lock);
- break;
-
- case WDIOC_SETTIMEOUT:
- return -EOPNOTSUPP;
-
- case WDIOC_GETTIMEOUT:
- spin_lock(&wdt_lock);
- timeout = m8xx_wdt_get_timeout();
- spin_unlock(&wdt_lock);
- if (put_user(timeout, (int *)arg))
- return -EFAULT;
- break;
-
- default:
- return -ENOTTY;
- }
-
- return 0;
-}
-
-static const struct file_operations mpc8xx_wdt_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = mpc8xx_wdt_write,
- .unlocked_ioctl = mpc8xx_wdt_ioctl,
- .open = mpc8xx_wdt_open,
- .release = mpc8xx_wdt_release,
-};
-
-static struct miscdevice mpc8xx_wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &mpc8xx_wdt_fops,
-};
-
-static int __init mpc8xx_wdt_init(void)
-{
- spin_lock_init(&wdt_lock);
- return misc_register(&mpc8xx_wdt_miscdev);
-}
-
-static void __exit mpc8xx_wdt_exit(void)
-{
- misc_deregister(&mpc8xx_wdt_miscdev);
-
- m8xx_wdt_reset();
- mpc8xx_wdt_handler_enable();
-}
-
-module_init(mpc8xx_wdt_init);
-module_exit(mpc8xx_wdt_exit);
-
-MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>");
-MODULE_DESCRIPTION("MPC8xx watchdog driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index f2094960e66..38c588ee694 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -48,6 +48,7 @@ struct mpc8xxx_wdt_type {
};
static struct mpc8xxx_wdt __iomem *wd_base;
+static int mpc8xxx_wdt_init_late(void);
static u16 timeout = 0xffff;
module_param(timeout, ushort, 0);
@@ -213,6 +214,12 @@ static int __devinit mpc8xxx_wdt_probe(struct of_device *ofdev,
else
timeout_sec = timeout / freq;
+#ifdef MODULE
+ ret = mpc8xxx_wdt_init_late();
+ if (ret)
+ goto err_unmap;
+#endif
+
pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d "
"(%d seconds)\n", reset ? "reset" : "interrupt", timeout,
timeout_sec);
@@ -280,7 +287,7 @@ static struct of_platform_driver mpc8xxx_wdt_driver = {
* very early to start pinging the watchdog (misc devices are not yet
* available), and later module_init() just registers the misc device.
*/
-static int __init mpc8xxx_wdt_init_late(void)
+static int mpc8xxx_wdt_init_late(void)
{
int ret;
@@ -295,7 +302,9 @@ static int __init mpc8xxx_wdt_init_late(void)
}
return 0;
}
+#ifndef MODULE
module_init(mpc8xxx_wdt_init_late);
+#endif
static int __init mpc8xxx_wdt_init(void)
{
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index e91ada72da1..484c215e9f3 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -30,7 +30,6 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
-#include <linux/version.h>
#include <linux/io.h>
#include <linux/uaccess.h>
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
new file mode 100644
index 00000000000..6756bcb009e
--- /dev/null
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -0,0 +1,344 @@
+/*
+ * IDT Interprise 79RC32434 watchdog driver
+ *
+ * Copyright (C) 2006, Ondrej Zajicek <santiago@crfreenet.org>
+ * Copyright (C) 2008, Florian Fainelli <florian@openwrt.org>
+ *
+ * based on
+ * SoftDog 0.05: A Software Watchdog Device
+ *
+ * (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *
+ * 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 the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/mach-rc32434/integ.h>
+
+#define MAX_TIMEOUT 20
+#define RC32434_WDT_INTERVAL (15 * HZ)
+
+#define VERSION "0.2"
+
+static struct {
+ struct completion stop;
+ int running;
+ struct timer_list timer;
+ int queue;
+ int default_ticks;
+ unsigned long inuse;
+} rc32434_wdt_device;
+
+static struct integ __iomem *wdt_reg;
+static int ticks = 100 * HZ;
+
+static int expect_close;
+static int timeout;
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+
+static void rc32434_wdt_start(void)
+{
+ u32 val;
+
+ if (!rc32434_wdt_device.inuse) {
+ writel(0, &wdt_reg->wtcount);
+
+ val = RC32434_ERR_WRE;
+ writel(readl(&wdt_reg->errcs) | val, &wdt_reg->errcs);
+
+ val = RC32434_WTC_EN;
+ writel(readl(&wdt_reg->wtc) | val, &wdt_reg->wtc);
+ }
+ rc32434_wdt_device.running++;
+}
+
+static void rc32434_wdt_stop(void)
+{
+ u32 val;
+
+ if (rc32434_wdt_device.running) {
+
+ val = ~RC32434_WTC_EN;
+ writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc);
+
+ val = ~RC32434_ERR_WRE;
+ writel(readl(&wdt_reg->errcs) & val, &wdt_reg->errcs);
+
+ rc32434_wdt_device.running = 0;
+ }
+}
+
+static void rc32434_wdt_set(int new_timeout)
+{
+ u32 cmp = new_timeout * HZ;
+ u32 state, val;
+
+ timeout = new_timeout;
+ /*
+ * store and disable WTC
+ */
+ state = (u32)(readl(&wdt_reg->wtc) & RC32434_WTC_EN);
+ val = ~RC32434_WTC_EN;
+ writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc);
+
+ writel(0, &wdt_reg->wtcount);
+ writel(cmp, &wdt_reg->wtcompare);
+
+ /*
+ * restore WTC
+ */
+
+ writel(readl(&wdt_reg->wtc) | state, &wdt_reg);
+}
+
+static void rc32434_wdt_reset(void)
+{
+ ticks = rc32434_wdt_device.default_ticks;
+}
+
+static void rc32434_wdt_update(unsigned long unused)
+{
+ if (rc32434_wdt_device.running)
+ ticks--;
+
+ writel(0, &wdt_reg->wtcount);
+
+ if (rc32434_wdt_device.queue && ticks)
+ mod_timer(&rc32434_wdt_device.timer,
+ jiffies + RC32434_WDT_INTERVAL);
+ else
+ complete(&rc32434_wdt_device.stop);
+}
+
+static int rc32434_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(0, &rc32434_wdt_device.inuse))
+ return -EBUSY;
+
+ if (nowayout)
+ __module_get(THIS_MODULE);
+
+ return nonseekable_open(inode, file);
+}
+
+static int rc32434_wdt_release(struct inode *inode, struct file *file)
+{
+ if (expect_close && nowayout == 0) {
+ rc32434_wdt_stop();
+ printk(KERN_INFO KBUILD_MODNAME ": disabling watchdog timer\n");
+ module_put(THIS_MODULE);
+ } else
+ printk(KERN_CRIT KBUILD_MODNAME
+ ": device closed unexpectedly. WDT will not stop !\n");
+
+ clear_bit(0, &rc32434_wdt_device.inuse);
+ return 0;
+}
+
+static ssize_t rc32434_wdt_write(struct file *file, const char *data,
+ size_t len, loff_t *ppos)
+{
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ /* In case it was set long ago */
+ expect_close = 0;
+
+ for (i = 0; i != len; i++) {
+ char c;
+ if (get_user(c, data + i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 1;
+ }
+ }
+ rc32434_wdt_update(0);
+ return len;
+ }
+ return 0;
+}
+
+static int rc32434_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int new_timeout;
+ unsigned int value;
+ static struct watchdog_info ident = {
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+ .identity = "RC32434_WDT Watchdog",
+ };
+ switch (cmd) {
+ case WDIOC_KEEPALIVE:
+ rc32434_wdt_reset();
+ break;
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ value = readl(&wdt_reg->wtcount);
+ if (copy_to_user(argp, &value, sizeof(int)))
+ return -EFAULT;
+ break;
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user(argp, &ident, sizeof(ident)))
+ return -EFAULT;
+ break;
+ case WDIOC_SETOPTIONS:
+ if (copy_from_user(&value, argp, sizeof(int)))
+ return -EFAULT;
+ switch (value) {
+ case WDIOS_ENABLECARD:
+ rc32434_wdt_start();
+ break;
+ case WDIOS_DISABLECARD:
+ rc32434_wdt_stop();
+ default:
+ return -EINVAL;
+ }
+ break;
+ case WDIOC_SETTIMEOUT:
+ if (copy_from_user(&new_timeout, argp, sizeof(int)))
+ return -EFAULT;
+ if (new_timeout < 1)
+ return -EINVAL;
+ if (new_timeout > MAX_TIMEOUT)
+ return -EINVAL;
+ rc32434_wdt_set(new_timeout);
+ case WDIOC_GETTIMEOUT:
+ return copy_to_user(argp, &timeout, sizeof(int));
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static struct file_operations rc32434_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = rc32434_wdt_write,
+ .ioctl = rc32434_wdt_ioctl,
+ .open = rc32434_wdt_open,
+ .release = rc32434_wdt_release,
+};
+
+static struct miscdevice rc32434_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &rc32434_wdt_fops,
+};
+
+static char banner[] = KERN_INFO KBUILD_MODNAME
+ ": Watchdog Timer version " VERSION ", timer margin: %d sec\n";
+
+static int rc32434_wdt_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct resource *r;
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb500_wdt_res");
+ if (!r) {
+ printk(KERN_ERR KBUILD_MODNAME
+ "failed to retrieve resources\n");
+ return -ENODEV;
+ }
+
+ wdt_reg = ioremap_nocache(r->start, r->end - r->start);
+ if (!wdt_reg) {
+ printk(KERN_ERR KBUILD_MODNAME
+ "failed to remap I/O resources\n");
+ return -ENXIO;
+ }
+
+ ret = misc_register(&rc32434_wdt_miscdev);
+
+ if (ret < 0) {
+ printk(KERN_ERR KBUILD_MODNAME
+ "failed to register watchdog device\n");
+ goto unmap;
+ }
+
+ init_completion(&rc32434_wdt_device.stop);
+ rc32434_wdt_device.queue = 0;
+
+ clear_bit(0, &rc32434_wdt_device.inuse);
+
+ setup_timer(&rc32434_wdt_device.timer, rc32434_wdt_update, 0L);
+
+ rc32434_wdt_device.default_ticks = ticks;
+
+ rc32434_wdt_start();
+
+ printk(banner, timeout);
+
+ return 0;
+
+unmap:
+ iounmap(wdt_reg);
+ return ret;
+}
+
+static int rc32434_wdt_remove(struct platform_device *pdev)
+{
+ if (rc32434_wdt_device.queue) {
+ rc32434_wdt_device.queue = 0;
+ wait_for_completion(&rc32434_wdt_device.stop);
+ }
+ misc_deregister(&rc32434_wdt_miscdev);
+
+ iounmap(wdt_reg);
+
+ return 0;
+}
+
+static struct platform_driver rc32434_wdt = {
+ .probe = rc32434_wdt_probe,
+ .remove = rc32434_wdt_remove,
+ .driver = {
+ .name = "rc32434_wdt",
+ }
+};
+
+static int __init rc32434_wdt_init(void)
+{
+ return platform_driver_register(&rc32434_wdt);
+}
+
+static void __exit rc32434_wdt_exit(void)
+{
+ platform_driver_unregister(&rc32434_wdt);
+}
+
+module_init(rc32434_wdt_init);
+module_exit(rc32434_wdt_exit);
+
+MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>,"
+ "Florian Fainelli <florian@openwrt.org>");
+MODULE_DESCRIPTION("Driver for the IDT RC32434 SoC watchdog");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
new file mode 100644
index 00000000000..9108efa73e7
--- /dev/null
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -0,0 +1,285 @@
+/*
+ * RDC321x watchdog driver
+ *
+ * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
+ *
+ * This driver is highly inspired from the cpu5_wdt driver
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <asm/mach-rdc321x/rdc321x_defs.h>
+
+#define RDC_WDT_MASK 0x80000000 /* Mask */
+#define RDC_WDT_EN 0x00800000 /* Enable bit */
+#define RDC_WDT_WTI 0x00200000 /* Generate CPU reset/NMI/WDT on timeout */
+#define RDC_WDT_RST 0x00100000 /* Reset bit */
+#define RDC_WDT_WIF 0x00040000 /* WDT IRQ Flag */
+#define RDC_WDT_IRT 0x00000100 /* IRQ Routing table */
+#define RDC_WDT_CNT 0x00000001 /* WDT count */
+
+#define RDC_CLS_TMR 0x80003844 /* Clear timer */
+
+#define RDC_WDT_INTERVAL (HZ/10+1)
+
+static int ticks = 1000;
+
+/* some device data */
+
+static struct {
+ struct completion stop;
+ int running;
+ struct timer_list timer;
+ int queue;
+ int default_ticks;
+ unsigned long inuse;
+ spinlock_t lock;
+} rdc321x_wdt_device;
+
+/* generic helper functions */
+
+static void rdc321x_wdt_trigger(unsigned long unused)
+{
+ unsigned long flags;
+
+ if (rdc321x_wdt_device.running)
+ ticks--;
+
+ /* keep watchdog alive */
+ spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
+ outl(RDC_WDT_EN | inl(RDC3210_CFGREG_DATA),
+ RDC3210_CFGREG_DATA);
+ spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
+
+ /* requeue?? */
+ if (rdc321x_wdt_device.queue && ticks)
+ mod_timer(&rdc321x_wdt_device.timer,
+ jiffies + RDC_WDT_INTERVAL);
+ else {
+ /* ticks doesn't matter anyway */
+ complete(&rdc321x_wdt_device.stop);
+ }
+
+}
+
+static void rdc321x_wdt_reset(void)
+{
+ ticks = rdc321x_wdt_device.default_ticks;
+}
+
+static void rdc321x_wdt_start(void)
+{
+ unsigned long flags;
+
+ if (!rdc321x_wdt_device.queue) {
+ rdc321x_wdt_device.queue = 1;
+
+ /* Clear the timer */
+ spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
+ outl(RDC_CLS_TMR, RDC3210_CFGREG_ADDR);
+
+ /* Enable watchdog and set the timeout to 81.92 us */
+ outl(RDC_WDT_EN | RDC_WDT_CNT, RDC3210_CFGREG_DATA);
+ spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
+
+ mod_timer(&rdc321x_wdt_device.timer,
+ jiffies + RDC_WDT_INTERVAL);
+ }
+
+ /* if process dies, counter is not decremented */
+ rdc321x_wdt_device.running++;
+}
+
+static int rdc321x_wdt_stop(void)
+{
+ if (rdc321x_wdt_device.running)
+ rdc321x_wdt_device.running = 0;
+
+ ticks = rdc321x_wdt_device.default_ticks;
+
+ return -EIO;
+}
+
+/* filesystem operations */
+static int rdc321x_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(0, &rdc321x_wdt_device.inuse))
+ return -EBUSY;
+
+ return nonseekable_open(inode, file);
+}
+
+static int rdc321x_wdt_release(struct inode *inode, struct file *file)
+{
+ clear_bit(0, &rdc321x_wdt_device.inuse);
+ return 0;
+}
+
+static int rdc321x_wdt_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ unsigned int value;
+ static struct watchdog_info ident = {
+ .options = WDIOF_CARDRESET,
+ .identity = "RDC321x WDT",
+ };
+ unsigned long flags;
+
+ switch (cmd) {
+ case WDIOC_KEEPALIVE:
+ rdc321x_wdt_reset();
+ break;
+ case WDIOC_GETSTATUS:
+ /* Read the value from the DATA register */
+ spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
+ value = inl(RDC3210_CFGREG_DATA);
+ spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
+ if (copy_to_user(argp, &value, sizeof(int)))
+ return -EFAULT;
+ break;
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user(argp, &ident, sizeof(ident)))
+ return -EFAULT;
+ break;
+ case WDIOC_SETOPTIONS:
+ if (copy_from_user(&value, argp, sizeof(int)))
+ return -EFAULT;
+ switch (value) {
+ case WDIOS_ENABLECARD:
+ rdc321x_wdt_start();
+ break;
+ case WDIOS_DISABLECARD:
+ return rdc321x_wdt_stop();
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ if (!count)
+ return -EIO;
+
+ rdc321x_wdt_reset();
+
+ return count;
+}
+
+static const struct file_operations rdc321x_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .ioctl = rdc321x_wdt_ioctl,
+ .open = rdc321x_wdt_open,
+ .write = rdc321x_wdt_write,
+ .release = rdc321x_wdt_release,
+};
+
+static struct miscdevice rdc321x_wdt_misc = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &rdc321x_wdt_fops,
+};
+
+static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
+{
+ int err;
+
+ err = misc_register(&rdc321x_wdt_misc);
+ if (err < 0) {
+ printk(KERN_ERR PFX "watchdog misc_register failed\n");
+ return err;
+ }
+
+ spin_lock_init(&rdc321x_wdt_device.lock);
+
+ /* Reset the watchdog */
+ outl(RDC_WDT_RST, RDC3210_CFGREG_DATA);
+
+ init_completion(&rdc321x_wdt_device.stop);
+ rdc321x_wdt_device.queue = 0;
+
+ clear_bit(0, &rdc321x_wdt_device.inuse);
+
+ setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0);
+
+ rdc321x_wdt_device.default_ticks = ticks;
+
+ printk(KERN_INFO PFX "watchdog init success\n");
+
+ return 0;
+}
+
+static int rdc321x_wdt_remove(struct platform_device *pdev)
+{
+ if (rdc321x_wdt_device.queue) {
+ rdc321x_wdt_device.queue = 0;
+ wait_for_completion(&rdc321x_wdt_device.stop);
+ }
+
+ misc_deregister(&rdc321x_wdt_misc);
+
+ return 0;
+}
+
+static struct platform_driver rdc321x_wdt_driver = {
+ .probe = rdc321x_wdt_probe,
+ .remove = rdc321x_wdt_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "rdc321x-wdt",
+ },
+};
+
+static int __init rdc321x_wdt_init(void)
+{
+ return platform_driver_register(&rdc321x_wdt_driver);
+}
+
+static void __exit rdc321x_wdt_exit(void)
+{
+ platform_driver_unregister(&rdc321x_wdt_driver);
+}
+
+module_init(rdc321x_wdt_init);
+module_exit(rdc321x_wdt_exit);
+
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
+MODULE_DESCRIPTION("RDC321x watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 22715e3be5e..86d42801de4 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -21,18 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Changelog:
- * 05-Oct-2004 BJD Added semaphore init to stop crashes on open
- * Fixed tmr_count / wdt_count confusion
- * Added configurable debug
- *
- * 11-Jan-2005 BJD Fixed divide-by-2 in timeout code
- *
- * 25-Jan-2005 DA Added suspend/resume support
- * Replaced reboot notifier with .shutdown method
- *
- * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
*/
#include <linux/module.h>
@@ -365,7 +353,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
return -ENOENT;
}
- size = (res->end-res->start)+1;
+ size = (res->end - res->start) + 1;
wdt_mem = request_mem_region(res->start, size, pdev->name);
if (wdt_mem == NULL) {
dev_err(dev, "failed to get memory region\n");
@@ -374,7 +362,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
}
wdt_base = ioremap(res->start, size);
- if (wdt_base == 0) {
+ if (wdt_base == NULL) {
dev_err(dev, "failed to ioremap() region\n");
ret = -EINVAL;
goto err_req;