Commit b91867f2 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'staging-3.3-rc3' into staging-next

This was done to resolve some merge issues with the following files that
had changed in both branches:
	drivers/staging/rtl8712/rtl871x_sta_mgt.c
	drivers/staging/tidspbridge/rmgr/drv_interface.c
	drivers/staging/zcache/zcache-main.c
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parents b05ee6bf 9196dc11
......@@ -40,8 +40,6 @@ source "drivers/net/Kconfig"
source "drivers/isdn/Kconfig"
source "drivers/telephony/Kconfig"
# input before char - char/joystick depends on it. As does USB.
source "drivers/input/Kconfig"
......
......@@ -86,7 +86,6 @@ obj-$(CONFIG_POWER_SUPPLY) += power/
obj-$(CONFIG_HWMON) += hwmon/
obj-$(CONFIG_THERMAL) += thermal/
obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_MD) += md/
obj-$(CONFIG_BT) += bluetooth/
obj-$(CONFIG_ACCESSIBILITY) += accessibility/
......
......@@ -88,6 +88,8 @@ source "drivers/staging/zram/Kconfig"
source "drivers/staging/zcache/Kconfig"
source "drivers/staging/zsmalloc/Kconfig"
source "drivers/staging/wlags49_h2/Kconfig"
source "drivers/staging/wlags49_h25/Kconfig"
......@@ -128,4 +130,6 @@ source "drivers/staging/omapdrm/Kconfig"
source "drivers/staging/android/Kconfig"
source "drivers/staging/telephony/Kconfig"
endif # STAGING
......@@ -34,8 +34,8 @@ obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_ZRAM) += zram/
obj-$(CONFIG_XVMALLOC) += zram/
obj-$(CONFIG_ZCACHE) += zcache/
obj-$(CONFIG_ZSMALLOC) += zsmalloc/
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
obj-$(CONFIG_FB_SM7XX) += sm7xx/
......@@ -55,3 +55,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/
obj-$(CONFIG_MFD_NVEC) += nvec/
obj-$(CONFIG_DRM_OMAP) += omapdrm/
obj-$(CONFIG_ANDROID) += android/
obj-$(CONFIG_PHONE) += telephony/
......@@ -102,6 +102,32 @@ config ANDROID_LOW_MEMORY_KILLER
source "drivers/staging/android/switch/Kconfig"
config ANDROID_INTF_ALARM
bool "Android alarm driver"
depends on RTC_CLASS
default n
help
Provides non-wakeup and rtc backed wakeup alarms based on rtc or
elapsed realtime, and a non-wakeup alarm on the monotonic clock.
Also provides an interface to set the wall time which must be used
for elapsed realtime to work.
config ANDROID_INTF_ALARM_DEV
bool "Android alarm device"
depends on ANDROID_INTF_ALARM
default y
help
Exports the alarm interface to user-space.
config ANDROID_ALARM_OLDDRV_COMPAT
bool "Android Alarm compatability with old drivers"
depends on ANDROID_INTF_ALARM
default n
help
Provides preprocessor alias to aid compatability with
older out-of-tree drivers that use the Android Alarm
in-kernel API. This will be removed eventually.
endif # if ANDROID
endmenu
......@@ -6,3 +6,5 @@ obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o
obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o
obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
obj-$(CONFIG_ANDROID_SWITCH) += switch/
obj-$(CONFIG_ANDROID_INTF_ALARM) += alarm.o
obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o
......@@ -3,7 +3,7 @@ TODO:
- sparse fixes
- rename files to be not so "generic"
- make sure things build as modules properly
- add proper arch dependancies as needed
- add proper arch dependencies as needed
- audit userspace interfaces to make sure they are sane
Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc:
......
/* drivers/rtc/alarm-dev.c
*
* Copyright (C) 2007-2009 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#include <linux/time.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include "android_alarm.h"
/* XXX - Hack out wakelocks, while they are out of tree */
struct wake_lock {
int i;
};
#define wake_lock(x)
#define wake_lock_timeout(x, y)
#define wake_unlock(x)
#define WAKE_LOCK_SUSPEND 0
#define wake_lock_init(x, y, z) ((x)->i = 1)
#define wake_lock_destroy(x)
#define ANDROID_ALARM_PRINT_INFO (1U << 0)
#define ANDROID_ALARM_PRINT_IO (1U << 1)
#define ANDROID_ALARM_PRINT_INT (1U << 2)
static int debug_mask = ANDROID_ALARM_PRINT_INFO;
module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
#define pr_alarm(debug_level_mask, args...) \
do { \
if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \
pr_info(args); \
} \
} while (0)
#define ANDROID_ALARM_WAKEUP_MASK ( \
ANDROID_ALARM_RTC_WAKEUP_MASK | \
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
/* support old usespace code */
#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */
#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t)
static int alarm_opened;
static DEFINE_SPINLOCK(alarm_slock);
static struct wake_lock alarm_wake_lock;
static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
static uint32_t alarm_pending;
static uint32_t alarm_enabled;
static uint32_t wait_pending;
static struct android_alarm alarms[ANDROID_ALARM_TYPE_COUNT];
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int rv = 0;
unsigned long flags;
struct timespec new_alarm_time;
struct timespec new_rtc_time;
struct timespec tmp_time;
enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
uint32_t alarm_type_mask = 1U << alarm_type;
if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)
return -EINVAL;
if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
return -EPERM;
if (file->private_data == NULL &&
cmd != ANDROID_ALARM_SET_RTC) {
spin_lock_irqsave(&alarm_slock, flags);
if (alarm_opened) {
spin_unlock_irqrestore(&alarm_slock, flags);
return -EBUSY;
}
alarm_opened = 1;
file->private_data = (void *)1;
spin_unlock_irqrestore(&alarm_slock, flags);
}
}
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
case ANDROID_ALARM_CLEAR(0):
spin_lock_irqsave(&alarm_slock, flags);
pr_alarm(IO, "alarm %d clear\n", alarm_type);
android_alarm_try_to_cancel(&alarms[alarm_type]);
if (alarm_pending) {
alarm_pending &= ~alarm_type_mask;
if (!alarm_pending && !wait_pending)
wake_unlock(&alarm_wake_lock);
}
alarm_enabled &= ~alarm_type_mask;
spin_unlock_irqrestore(&alarm_slock, flags);
break;
case ANDROID_ALARM_SET_OLD:
case ANDROID_ALARM_SET_AND_WAIT_OLD:
if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) {
rv = -EFAULT;
goto err1;
}
new_alarm_time.tv_nsec = 0;
goto from_old_alarm_set;
case ANDROID_ALARM_SET_AND_WAIT(0):
case ANDROID_ALARM_SET(0):
if (copy_from_user(&new_alarm_time, (void __user *)arg,
sizeof(new_alarm_time))) {
rv = -EFAULT;
goto err1;
}
from_old_alarm_set:
spin_lock_irqsave(&alarm_slock, flags);
pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type,
new_alarm_time.tv_sec, new_alarm_time.tv_nsec);
alarm_enabled |= alarm_type_mask;
android_alarm_start_range(&alarms[alarm_type],
timespec_to_ktime(new_alarm_time),
timespec_to_ktime(new_alarm_time));
spin_unlock_irqrestore(&alarm_slock, flags);
if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0)
&& cmd != ANDROID_ALARM_SET_AND_WAIT_OLD)
break;
/* fall though */
case ANDROID_ALARM_WAIT:
spin_lock_irqsave(&alarm_slock, flags);
pr_alarm(IO, "alarm wait\n");
if (!alarm_pending && wait_pending) {
wake_unlock(&alarm_wake_lock);
wait_pending = 0;
}
spin_unlock_irqrestore(&alarm_slock, flags);
rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
if (rv)
goto err1;
spin_lock_irqsave(&alarm_slock, flags);
rv = alarm_pending;
wait_pending = 1;
alarm_pending = 0;
spin_unlock_irqrestore(&alarm_slock, flags);
break;
case ANDROID_ALARM_SET_RTC:
if (copy_from_user(&new_rtc_time, (void __user *)arg,
sizeof(new_rtc_time))) {
rv = -EFAULT;
goto err1;
}
rv = android_alarm_set_rtc(new_rtc_time);
spin_lock_irqsave(&alarm_slock, flags);
alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
wake_up(&alarm_wait_queue);
spin_unlock_irqrestore(&alarm_slock, flags);
if (rv < 0)
goto err1;
break;
case ANDROID_ALARM_GET_TIME(0):
switch (alarm_type) {
case ANDROID_ALARM_RTC_WAKEUP:
case ANDROID_ALARM_RTC:
getnstimeofday(&tmp_time);
break;
case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
case ANDROID_ALARM_ELAPSED_REALTIME:
tmp_time =
ktime_to_timespec(alarm_get_elapsed_realtime());
break;
case ANDROID_ALARM_TYPE_COUNT:
case ANDROID_ALARM_SYSTEMTIME:
ktime_get_ts(&tmp_time);
break;
}
if (copy_to_user((void __user *)arg, &tmp_time,
sizeof(tmp_time))) {
rv = -EFAULT;
goto err1;
}
break;
default:
rv = -EINVAL;
goto err1;
}
err1:
return rv;
}
static int alarm_open(struct inode *inode, struct file *file)
{
file->private_data = NULL;
return 0;
}
static int alarm_release(struct inode *inode, struct file *file)
{
int i;
unsigned long flags;
spin_lock_irqsave(&alarm_slock, flags);
if (file->private_data != 0) {
for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
uint32_t alarm_type_mask = 1U << i;
if (alarm_enabled & alarm_type_mask) {
pr_alarm(INFO, "alarm_release: clear alarm, "
"pending %d\n",
!!(alarm_pending & alarm_type_mask));
alarm_enabled &= ~alarm_type_mask;
}
spin_unlock_irqrestore(&alarm_slock, flags);
android_alarm_cancel(&alarms[i]);
spin_lock_irqsave(&alarm_slock, flags);
}
if (alarm_pending | wait_pending) {
if (alarm_pending)
pr_alarm(INFO, "alarm_release: clear "
"pending alarms %x\n", alarm_pending);
wake_unlock(&alarm_wake_lock);
wait_pending = 0;
alarm_pending = 0;
}
alarm_opened = 0;
}
spin_unlock_irqrestore(&alarm_slock, flags);
return 0;
}
static void alarm_triggered(struct android_alarm *alarm)
{
unsigned long flags;
uint32_t alarm_type_mask = 1U << alarm->type;
pr_alarm(INT, "alarm_triggered type %d\n", alarm->type);
spin_lock_irqsave(&alarm_slock, flags);
if (alarm_enabled & alarm_type_mask) {
wake_lock_timeout(&alarm_wake_lock, 5 * HZ);
alarm_enabled &= ~alarm_type_mask;
alarm_pending |= alarm_type_mask;
wake_up(&alarm_wait_queue);
}
spin_unlock_irqrestore(&alarm_slock, flags);
}
static const struct file_operations alarm_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = alarm_ioctl,
.open = alarm_open,
.release = alarm_release,
};
static struct miscdevice alarm_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "alarm",
.fops = &alarm_fops,
};
static int __init alarm_dev_init(void)
{
int err;
int i;
err = misc_register(&alarm_device);
if (err)
return err;
for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++)
android_alarm_init(&alarms[i], i, alarm_triggered);
wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm");
return 0;
}
static void __exit alarm_dev_exit(void)
{
misc_deregister(&alarm_device);
wake_lock_destroy(&alarm_wake_lock);
}
module_init(alarm_dev_init);
module_exit(alarm_dev_exit);
This diff is collapsed.
/* include/linux/android_alarm.h
*
* Copyright (C) 2006-2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#ifndef _LINUX_ANDROID_ALARM_H
#define _LINUX_ANDROID_ALARM_H
#include <linux/ioctl.h>
#include <linux/time.h>
enum android_alarm_type {
/* return code bit numbers or set alarm arg */
ANDROID_ALARM_RTC_WAKEUP,
ANDROID_ALARM_RTC,
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
ANDROID_ALARM_ELAPSED_REALTIME,
ANDROID_ALARM_SYSTEMTIME,
ANDROID_ALARM_TYPE_COUNT,
/* return code bit numbers */
/* ANDROID_ALARM_TIME_CHANGE = 16 */
};
#ifdef __KERNEL__
#include <linux/ktime.h>
#include <linux/rbtree.h>
/*
* The alarm interface is similar to the hrtimer interface but adds support
* for wakeup from suspend. It also adds an elapsed realtime clock that can
* be used for periodic timers that need to keep runing while the system is
* suspended and not be disrupted when the wall time is set.
*/
/**
* struct alarm - the basic alarm structure
* @node: red black tree node for time ordered insertion
* @type: alarm type. rtc/elapsed-realtime/systemtime, wakeup/non-wakeup.
* @softexpires: the absolute earliest expiry time of the alarm.
* @expires: the absolute expiry time.
* @function: alarm expiry callback function
*
* The alarm structure must be initialized by alarm_init()
*
*/
struct android_alarm {
struct rb_node node;
enum android_alarm_type type;
ktime_t softexpires;
ktime_t expires;
void (*function)(struct android_alarm *);
};
void android_alarm_init(struct android_alarm *alarm,
enum android_alarm_type type, void (*function)(struct android_alarm *));
void android_alarm_start_range(struct android_alarm *alarm, ktime_t start,
ktime_t end);
int android_alarm_try_to_cancel(struct android_alarm *alarm);
int android_alarm_cancel(struct android_alarm *alarm);
ktime_t alarm_get_elapsed_realtime(void);
/* set rtc while preserving elapsed realtime */
int android_alarm_set_rtc(const struct timespec ts);
#ifdef CONFIG_ANDROID_ALARM_OLDDRV_COMPAT
/*
* Some older drivers depend on the old API,
* so provide compatability macros for now.
*/
#define alarm android_alarm
#define alarm_init(x, y, z) android_alarm_init(x, y, z)
#define alarm_start_range(x, y, z) android_alarm_start_range(x, y, z)
#define alarm_try_to_cancel(x) android_alarm_try_to_cancel(x)
#define alarm_cancel(x) android_alarm_cancel(x)
#define alarm_set_rtc(x) android_alarm_set_rtc(x)
#endif
#endif
enum android_alarm_return_flags {
ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
ANDROID_ALARM_ELAPSED_REALTIME_MASK =
1U << ANDROID_ALARM_ELAPSED_REALTIME,
ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
};
/* Disable alarm */
#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4))
/* Ack last alarm and wait for next */
#define ANDROID_ALARM_WAIT _IO('a', 1)
#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size)
/* Set alarm */
#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec)
#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec)
#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec)
#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec)
#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
#endif
......@@ -315,7 +315,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
get_file(asma->file);
/*
* XXX - Reworked to use shmem_zero_setup() instead of
* XXX - Reworked to use shmem_zero_setup() instead of
* shmem_set_file while we're in staging. -jstultz
*/
if (vma->vm_flags & VM_SHARED) {
......@@ -680,7 +680,7 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
}
static struct file_operations ashmem_fops = {
static const struct file_operations ashmem_fops = {
.owner = THIS_MODULE,
.open = ashmem_open,
.release = ashmem_release,
......
......@@ -258,7 +258,7 @@ struct binder_ref {
};
struct binder_buffer {
struct list_head entry; /* free and allocated entries by addesss */
struct list_head entry; /* free and allocated entries by address */
struct rb_node rb_node; /* free entry by size or allocated entry */
/* by address */
unsigned free:1;
......
......@@ -60,7 +60,11 @@ struct logger_reader {
};
/* logger_offset - returns index 'n' into the log via (optimized) modulus */
#define logger_offset(n) ((n) & (log->size - 1))
size_t logger_offset(struct logger_log *log, size_t n)
{
return n & (log->size-1);
}
/*
* file_get_log - Given a file structure, return the associated log
......@@ -89,20 +93,24 @@ static inline struct logger_log *file_get_log(struct file *file)
* get_entry_len - Grabs the length of the payload of the next entry starting
* from 'off'.
*
* An entry length is 2 bytes (16 bits) in host endian order.
* In the log, the length does not include the size of the log entry structure.
* This function returns the size including the log entry structure.
*
* Caller needs to hold log->mutex.
*/
static __u32 get_entry_len(struct logger_log *log, size_t off)
{
__u16 val;
switch (log->size - off) {
case 1:
memcpy(&val, log->buffer + off, 1);
memcpy(((char *) &val) + 1, log->buffer, 1);
break;
default:
memcpy(&val, log->buffer + off, 2);
}
/* copy 2 bytes from buffer, in memcpy order, */
/* handling possible wrap at end of buffer */
((__u8 *)&val)[0] = log->buffer[off];
if (likely(off+1 < log->size))
((__u8 *)&val)[1] = log->buffer[off+1];
else
((__u8 *)&val)[1] = log->buffer[0];
return sizeof(struct logger_entry) + val;
}
......@@ -137,7 +145,7 @@ static ssize_t do_read_log_to_user(struct logger_log *log,
if (copy_to_user(buf + len, log->buffer, count - len))
return -EFAULT;
reader->r_off = logger_offset(reader->r_off + count);
reader->r_off = logger_offset(log, reader->r_off + count);
return count;
}
......@@ -164,9 +172,10 @@ static ssize_t logger_read(struct file *file, char __user *buf,
start:
while (1) {
mutex_lock(&log->mutex);
prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE);
mutex_lock(&log->mutex);
ret = (log->w_off == reader->r_off);
mutex_unlock(&log->mutex);
if (!ret)
......@@ -225,7 +234,7 @@ static size_t get_next_entry(struct logger_log *log, size_t off, size_t len)
do {
size_t nr = get_entry_len(log, off);
off = logger_offset(off + nr);
off = logger_offset(log, off + nr);
count += nr;
} while (count < len);
......@@ -233,16 +242,28 @@ static size_t get_next_entry(struct logger_log *log, size_t off, size_t len)
}
/*
* clock_interval - is a < c < b in mod-space? Put another way, does the line
* from a to b cross c?
* is_between - is a < c < b, accounting for wrapping of a, b, and c
* positions in the buffer
*
* That is, if a<b, check for c between a and b
* and if a>b, check for c outside (not between) a and b
*
* |------- a xxxxxxxx b --------|
* c^
*
* |xxxxx b --------- a xxxxxxxxx|
* c^
* or c^
*/
static inline int clock_interval(size_t a, size_t b, size_t c)
static inline int is_between(size_t a, size_t b, size_t c)
{
if (b < a) {
if (a < c || b >= c)
if (a < b) {
/* is c between a and b? */
if (a < c && c <= b)
return 1;
} else {
if (a < c && b >= c)
/* is c outside of b through a? */
if (c <= b || a < c)
return 1;
}
......@@ -260,14 +281,14 @@ static inline int clock_interval(size_t a, size_t b, size_t c)
static void fix_up_readers(struct logger_log *log, size_t len)
{
size_t old = log->w_off;
size_t new = logger_offset(old + len);
size_t new = logger_offset(log, old + len);
struct logger_reader *reader;
if (clock_interval(old, new, log->head))
if (is_between(old, new, log->head))
log->head = get_next_entry(log, log->head, len);
list_for_each_entry(reader, &log->readers, list)
if (clock_interval(old, new, reader->r_off))
if (is_between(old, new, reader->r_off))
reader->r_off = get_next_entry(log, reader->r_off, len);
}
......@@ -286,7 +307,7 @@ static void do_write_log(struct logger_log *log, const void *buf, size_t count)
if (count != len)
memcpy(log->buffer, buf + len, count - len);
log->w_off = logger_offset(log->w_off + count);
log->w_off = logger_offset(log, log->w_off + count);
}
......@@ -309,9 +330,15 @@ static ssize_t do_write_log_from_user(struct logger_log *log,
if (count != len)
if (copy_from_user(log->buffer, buf + len, count - len))
/*
* Note that by not updating w_off, this abandons the
* portion of the new entry that *was* successfully
* copied, just above. This is intentional to avoid
* message corruption from missing fragments.
*/
return -EFAULT;
log->w_off = logger_offset(log->w_off + count);
log->w_off = logger_offset(log, log->w_off + count);
return count;
}
......
......@@ -34,6 +34,7 @@
#include <linux/mm.h>
#include <linux/oom.h>
#include <linux/sched.h>
#include <linux/rcupdate.h>
#include <linux/profile.h>
#include <linux/notifier.h>
......@@ -82,7 +83,7 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data)
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
{
struct task_struct *p;
struct task_struct *tsk;
struct task_struct *selected = NULL;
int rem = 0;
int tasksize;
......@@ -134,25 +135,24 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
}
selected_oom_adj = min_adj;
read_lock(&tasklist_lock);
for_each_process(p) {
struct mm_struct *mm;
struct signal_struct *sig;
rcu_read_lock();
for_each_process(tsk) {
struct task_struct *p;
int oom_adj;
task_lock(p);
mm = p->mm;
sig = p->signal;
if (!mm || !sig) {
task_unlock(p);
if (tsk->flags & PF_KTHREAD)
continue;
}
oom_adj = sig->oom_adj;
p = find_lock_task_mm(tsk);
if (!p)
continue;
oom_adj = p->signal->oom_adj;
if (oom_adj < min_adj) {
task_unlock(p);
continue;
}
tasksize = get_mm_rss(mm);
tasksize = get_mm_rss(p->mm);
task_unlock(p);
if (tasksize <= 0)
continue;
......@@ -183,12 +183,12 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
lowmem_deathpending_timeout = jiffies + HZ;
task_handoff_register(&task_nb);
#endif
force_sig(SIGKILL, selected);
send_sig(SIGKILL, selected, 0);
rem -= selected_tasksize;
}
lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n",
sc->nr_to_scan, sc->gfp_mask, rem);
read_unlock(&tasklist_lock);
rcu_read_unlock();
return rem;
}
......
......@@ -351,7 +351,7 @@ static int ram_console_driver_probe(struct platform_device *pdev)
"%lx\n", res, pdev->num_resources, res ? res->flags : 0);
return -ENXIO;
}
buffer_size = res->end - res->start + 1;
buffer_size = resource_size(res);
start = res->start;
printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
start, buffer_size);
......@@ -411,15 +411,14 @@ static int __init ram_console_late_init(void)
if (ram_console_old_log == NULL)
return 0;
#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL);
ram_console_old_log = kmemdup(ram_console_old_log_init_buffer,
ram_console_old_log_size, GFP_KERNEL);
if (ram_console_old_log == NULL) {
printk(KERN_ERR
"ram_console: failed to allocate buffer for old log\n");
ram_console_old_log_size = 0;
return 0;
}
memcpy(ram_console_old_log,
ram_console_old_log_init_buffer, ram_console_old_log_size);
#endif
entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL);
if (!entry) {
......
......@@ -29,9 +29,9 @@ struct timed_gpio_data {
struct timed_output_dev dev;
struct hrtimer timer;
spinlock_t lock;
unsigned gpio;
int max_timeout;
u8 active_low;
unsigned gpio;
int max_timeout;
u8 active_low;
};
static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
......
......@@ -728,14 +728,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE)
return -EINVAL;
pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
if (!pvBuffer)
return -ENOMEM;
if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
kfree(pvBuffer);
return -EFAULT;
}
pvBuffer = memdup_user(IoBuffer.InputBuffer,
IoBuffer.InputLength);
if (IS_ERR(pvBuffer))
return PTR_ERR(pvBuffer);
down(&Adapter->LowPowerModeSync);
Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
......@@ -1140,15 +1136,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
if (IoBuffer.InputLength < sizeof(ULONG) * 2)
return -EINVAL;
pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
if (!pvBuffer)
return -ENOMEM;
/* Get WrmBuffer structure */
if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
kfree(pvBuffer);
return -EFAULT;
}
pvBuffer = memdup_user(IoBuffer.InputBuffer,
IoBuffer.InputLength);
if (IS_ERR(pvBuffer))
return PTR_ERR(pvBuffer);
pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
......@@ -1302,20 +1293,18 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
/*
* Deny the access if the offset crosses the cal area limit.
*/
if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize)
return STATUS_FAILURE;
if ((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) {
if (stNVMReadWrite.uiOffset > Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes) {
/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */
return STATUS_FAILURE;
}
pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
if (!pReadData)
return -ENOMEM;
if (copy_from_user(pReadData, stNVMReadWrite.pBuffer, stNVMReadWrite.uiNumBytes)) {
kfree(pReadData);
return -EFAULT;
}
pReadData = memdup_user(stNVMReadWrite.pBuffer,
stNVMReadWrite.uiNumBytes);
if (IS_ERR(pReadData))
return PTR_ERR(pReadData);
do_gettimeofday(&tv0);
if (IOCTL_BCM_NVM_READ == cmd) {
......
This diff is collapsed.
......@@ -4,11 +4,11 @@
/*************************TYPE DEF**********************/
#define NUM_OF_LEDS 4
#define DSD_START_OFFSET 0x0200
#define EEPROM_VERSION_OFFSET 0x020E
#define EEPROM_HW_PARAM_POINTER_ADDRESS 0x0218
#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220
#define GPIO_SECTION_START_OFFSET 0x03
#define DSD_START_OFFSET 0x0200
#define EEPROM_VERSION_OFFSET 0x020E
#define EEPROM_HW_PARAM_POINTER_ADDRESS 0x0218
#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220
#define GPIO_SECTION_START_OFFSET 0x03
#define COMPATIBILITY_SECTION_LENGTH 42
#define COMPATIBILITY_SECTION_LENGTH_MAP5 84
......@@ -18,27 +18,27 @@
#define EEPROM_MAP5_MINORVERSION 0
#define MAX_NUM_OF_BLINKS 10
#define NUM_OF_GPIO_PINS 16
#define MAX_NUM_OF_BLINKS 10
#define NUM_OF_GPIO_PINS 16
#define DISABLE_GPIO_NUM 0xFF
#define EVENT_SIGNALED 1
#define DISABLE_GPIO_NUM 0xFF
#define EVENT_SIGNALED 1
#define MAX_FILE_NAME_BUFFER_SIZE 100
#define MAX_FILE_NAME_BUFFER_SIZE 100
#define TURN_ON_LED(GPIO, index) do{ \
#define TURN_ON_LED(GPIO, index) do { \
UINT gpio_val = GPIO; \
(Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \
wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG, &gpio_val ,sizeof(gpio_val)) : \
wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \
}while(0);
wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)) : \
wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \
} while (0);
#define TURN_OFF_LED(GPIO, index) do { \
UINT gpio_val = GPIO; \
(Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \
wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG,&gpio_val ,sizeof(gpio_val)) : \
wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG,&gpio_val ,sizeof(gpio_val)); \
}while(0);
wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)) : \
wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)); \
} while (0);
#define B_ULONG32 unsigned long
......@@ -50,7 +50,7 @@ typedef enum _LEDColors{
BLUE_LED = 2,
YELLOW_LED = 3,
GREEN_LED = 4
} LEDColors; /*Enumerated values of different LED types*/
} LEDColors; /*Enumerated values of different LED types*/
typedef enum LedEvents {
SHUTDOWN_EXIT = 0x00,
......@@ -62,43 +62,41 @@ typedef enum LedEvents {
LOWPOWER_MODE_ENTER = 0x20,
IDLEMODE_CONTINUE = 0x40,
IDLEMODE_EXIT = 0x80,
LED_THREAD_INACTIVE = 0x100, //Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold.
LED_THREAD_ACTIVE = 0x200 //Makes the LED Thread Active back.
} LedEventInfo_t; /*Enumerated values of different driver states*/
LED_THREAD_INACTIVE = 0x100, /* Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold. */
LED_THREAD_ACTIVE = 0x200 /* Makes the LED Thread Active back. */
} LedEventInfo_t; /* Enumerated values of different driver states */
#define DRIVER_HALT 0xff
/*Structure which stores the information of different LED types
* and corresponding LED state information of driver states*/
typedef struct LedStateInfo_t
{
/*
* Structure which stores the information of different LED types
* and corresponding LED state information of driver states
*/
typedef struct LedStateInfo_t {
UCHAR LED_Type; /* specify GPIO number - use 0xFF if not used */
UCHAR LED_On_State; /* Bits set or reset for different states */
UCHAR LED_Blink_State; /* Bits set or reset for blinking LEDs for different states */
UCHAR GPIO_Num;
UCHAR BitPolarity; /*To represent whether H/W is normal polarity or reverse
polarity*/
}LEDStateInfo, *pLEDStateInfo;
UCHAR BitPolarity; /* To represent whether H/W is normal polarity or reverse polarity */
} LEDStateInfo, *pLEDStateInfo;
typedef struct _LED_INFO_STRUCT
{
typedef struct _LED_INFO_STRUCT {
LEDStateInfo LEDState[NUM_OF_LEDS];
BOOLEAN bIdleMode_tx_from_host; /*Variable to notify whether driver came out
from idlemode due to Host or target*/
BOOLEAN bIdleMode_tx_from_host; /* Variable to notify whether driver came out from idlemode due to Host or target*/
BOOLEAN bIdle_led_off;
wait_queue_head_t notify_led_event;
wait_queue_head_t idleModeSyncEvent;
struct task_struct *led_cntrl_threadid;
int led_thread_running;
struct task_struct *led_cntrl_threadid;
int led_thread_running;
BOOLEAN bLedInitDone;
} LED_INFO_STRUCT, *PLED_INFO_STRUCT;
//LED Thread state.
#define BCM_LED_THREAD_DISABLED 0 //LED Thread is not running.
#define BCM_LED_THREAD_RUNNING_ACTIVELY 1 //LED thread is running.
#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 //LED thread has been put on hold
/* LED Thread state. */
#define BCM_LED_THREAD_DISABLED 0 /* LED Thread is not running. */
#define BCM_LED_THREAD_RUNNING_ACTIVELY 1 /* LED thread is running. */
#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 /*LED thread has been put on hold*/
......
......@@ -765,8 +765,9 @@ config COMEDI_ADV_PCI_DIO
default N
---help---
Enable support for Advantech PCI DIO cards
PCI-1730, PCI-1733, PCI-1734, PCI-1736UP, PCI-1750, PCI-1751,
PCI-1752, PCI-1753/E, PCI-1754, PCI-1756 and PCI-1762
PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U,
PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756,
PCI-1760 and PCI-1762
To compile this driver as a module, choose M here: the module will be
called adv_pci_dio.
......
......@@ -8,16 +8,16 @@
/*
Driver: adv_pci_dio
Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E,
PCI-1754, PCI-1756, PCI-1762
PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752,
PCI-1753/E, PCI-1754, PCI-1756, PCI-1760, PCI-1762
Author: Michal Dobes <dobes@tesnet.cz>
Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
PCI-1734, PCI-1735U, PCI-1736UP, PCI-1750,
PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750,
PCI-1751, PCI-1752, PCI-1753,
PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
PCI-1760, PCI-1762
Status: untested
Updated: Tue, 04 May 2010 13:00:00 +0000
Updated: Mon, 09 Jan 2012 12:40:46 +0000
This driver supports now only insn interface for DI/DO/DIO.
......@@ -51,6 +51,7 @@ Configuration options:
/* hardware types of the cards */
enum hw_cards_id {
TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736,
TYPE_PCI1739,
TYPE_PCI1750,
TYPE_PCI1751,
TYPE_PCI1752,
......@@ -109,6 +110,12 @@ enum hw_io_access {
#define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */
#define PCI1736_MAINREG 0 /* Normal register (2) doesn't work */
/* Advantech PCI-1739U */
#define PCI1739_DIO 0 /* R/W: begin of 8255 registers block */
#define PCI1739_ICR 32 /* W: Interrupt control register */
#define PCI1739_ISR 32 /* R: Interrupt status register */
#define PCI1739_BOARDID 8 /* R: Board I/D switch for 1739U */
/* Advantech PCI-1750 */
#define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */
#define PCI1750_IDO 0 /* W: Isolated digital output 0-15 */
......@@ -262,6 +269,7 @@ static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1734) },
{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1735) },
{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1736) },
{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1739) },
{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1750) },
{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1751) },
{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1752) },
......@@ -316,6 +324,14 @@ static const struct dio_boardtype boardtypes[] = {
{4, PCI1736_BOARDID, 1, SDF_INTERNAL},
{ {0, 0, 0, 0} },
IO_8b},
{"pci1739", PCI_VENDOR_ID_ADVANTECH, 0x1739, PCIDIO_MAINREG,
TYPE_PCI1739,
{ {0, 0, 0, 0}, {0, 0, 0, 0} },
{ {0, 0, 0, 0}, {0, 0, 0, 0} },
{ {48, PCI1739_DIO, 2, 0}, {0, 0, 0, 0} },
{0, 0, 0, 0},
{ {0, 0, 0, 0} },
IO_8b},
{"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
TYPE_PCI1750,
{ {0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0} },
......@@ -883,6 +899,11 @@ static int pci_dio_reset(struct comedi_device *dev)
outb(0, dev->iobase + PCI1736_3_INT_RF);
break;
case TYPE_PCI1739:
/* disable & clear interrupts */
outb(0x88, dev->iobase + PCI1739_ICR);
break;
case TYPE_PCI1750:
case TYPE_PCI1751:
/* disable & clear interrupts */
......
......@@ -720,12 +720,20 @@ static int dt2801_dio_insn_config(struct comedi_device *dev,
which = 1;
/* configure */
if (data[0]) {
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
s->io_bits = 0xff;
dt2801_writecmd(dev, DT_C_SET_DIGOUT);
} else {
break;
case INSN_CONFIG_DIO_INPUT:
s->io_bits = 0;
dt2801_writecmd(dev, DT_C_SET_DIGIN);
break;
case INSN_CONFIG_DIO_QUERY:
data[1] = s->io_bits ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
default:
return -EINVAL;
}
dt2801_writedata(dev, which);
......
......@@ -527,7 +527,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
* 11x -> Gain = 0.5
*/
case DT9812_GAIN_0PT5:
rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 ||
rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 |
F020_MASK_ADC0CF_AMP0GN1;
break;
case DT9812_GAIN_1:
......@@ -540,7 +540,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
rmw->or_value = F020_MASK_ADC0CF_AMP0GN1;
break;
case DT9812_GAIN_8:
rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 ||
rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 |
F020_MASK_ADC0CF_AMP0GN0;
break;
case DT9812_GAIN_16:
......
......@@ -2098,23 +2098,29 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
CALL_PDEBUG("In me4000_dio_insn_config()\n");
if (data[0] == INSN_CONFIG_DIO_QUERY) {
switch (data[0]) {
default:
return -EINVAL;
case INSN_CONFIG_DIO_QUERY:
data[1] =
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
case INSN_CONFIG_DIO_INPUT:
case INSN_CONFIG_DIO_OUTPUT:
break;
}
/*
* The input or output configuration of each digital line is
* configured by a special insn_config instruction. chanspec
* contains the channel to be changed, and data[0] contains the
* value COMEDI_INPUT or COMEDI_OUTPUT.
* value INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_OUTPUT.
* On the ME-4000 it is only possible to switch port wise (8 bit)
*/
tmp = me4000_inl(dev, info->dio_context.ctrl_reg);
if (data[0] == COMEDI_OUTPUT) {
if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
if (chan < 8) {
s->io_bits |= 0xFF;
tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
......
......@@ -30,7 +30,7 @@ Status: works
Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
PXI-6503, PCI-6533, PCI-6534
Updated: Sun, 21 Apr 2002 21:03:38 -0700
Updated: Mon, 09 Jan 2012 14:27:23 +0000
The DIO-96 appears as four 8255 subdevices. See the 8255
driver notes for details.
......@@ -42,6 +42,11 @@ supports simple digital I/O; no handshaking is supported.
DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting
scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the
trailing edge.
This driver could be easily modified to support AT-MIO32HS and
AT-MIO96.
......@@ -436,6 +441,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
comedi_error(dev, "failed to reserve mite dma channel.");
return -EBUSY;
}
devpriv->di_mite_chan->dir = COMEDI_INPUT;
writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
......@@ -482,6 +488,21 @@ void ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s)
comedi_event(dev, s);
}
static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
{
unsigned long irq_flags;
int count;
spin_lock_irqsave(&dev->spinlock, irq_flags);
spin_lock(&devpriv->mite_channel_lock);
if (devpriv->di_mite_chan)
mite_sync_input_dma(devpriv->di_mite_chan, s->async);
spin_unlock(&devpriv->mite_channel_lock);
count = s->async->buf_write_count - s->async->buf_read_count;
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
return count;
}
static irqreturn_t nidio_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
......@@ -497,7 +518,6 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
int status;
int work = 0;
unsigned int m_status = 0;
unsigned long irq_flags;
/* interrupcions parasites */
if (dev->attached == 0) {
......@@ -505,6 +525,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
return IRQ_NONE;
}
/* Lock to avoid race with comedi_poll */
spin_lock(&dev->spinlock);
status = readb(devpriv->mite->daq_io_addr +
Interrupt_And_Window_Status);
flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
......@@ -518,7 +541,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
/* printk("buf[4096]=%08x\n",
*(unsigned int *)(async->prealloc_buf+4096)); */
spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
spin_lock(&devpriv->mite_channel_lock);
if (devpriv->di_mite_chan)
m_status = mite_get_status(devpriv->di_mite_chan);
#ifdef MITE_DEBUG
......@@ -543,7 +566,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
disable_irq(dev->irq);
}
}
spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
spin_unlock(&devpriv->mite_channel_lock);
while (status & DataLeft) {
work++;
......@@ -645,6 +668,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
Master_DMA_And_Interrupt_Control);
}
#endif
spin_unlock(&dev->spinlock);
return IRQ_HANDLED;
}
......@@ -825,8 +850,8 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
} else {
/* TRIG_EXT */
/* should be level/edge, hi/lo specification here */
if (cmd->scan_begin_arg != 0) {
cmd->scan_begin_arg = 0;
if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) {
cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
err++;
}
}
......@@ -941,7 +966,13 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
writeb(0, devpriv->mite->daq_io_addr + Sequence);
writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
writeb(4, devpriv->mite->daq_io_addr + BlockMode);
writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
if (!(cmd->scan_begin_arg & CR_INVERT)) {
/* Leading Edge pulse mode */
writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
} else {
/* Trailing Edge pulse mode */
writeb(2, devpriv->mite->daq_io_addr + LinePolarities);
}
writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
writel(1, devpriv->mite->daq_io_addr + StartDelay);
writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
......@@ -1005,17 +1036,24 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
{
int retval;
unsigned long flags;
retval = ni_pcidio_request_di_mite_channel(dev);
if (retval)
return retval;
devpriv->di_mite_chan->dir = COMEDI_INPUT;
/* write alloc the entire buffer */
comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
mite_prep_dma(devpriv->di_mite_chan, 32, 32);
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
if (devpriv->di_mite_chan) {
mite_prep_dma(devpriv->di_mite_chan, 32, 32);
mite_dma_arm(devpriv->di_mite_chan);
} else
retval = -EIO;
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
mite_dma_arm(devpriv->di_mite_chan);
return 0;
return retval;
}
static int ni_pcidio_inttrig(struct comedi_device *dev,
......@@ -1244,6 +1282,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->len_chanlist = 32; /* XXX */
s->buf_change = &ni_pcidio_change;
s->async_dma_dir = DMA_BIDIRECTIONAL;
s->poll = &ni_pcidio_poll;
writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
......
......@@ -29,14 +29,15 @@ Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E,
PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E,
PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E,
PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225,
PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259,
PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224,
PCI-6225, PXI-6225, PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PXIe-6251,
PCI-6254, PCI-6259, PCIe-6259,
PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
PCI-6711, PXI-6711, PCI-6713, PXI-6713,
PXI-6071E, PCI-6070E, PXI-6070E,
PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
PCI-6143, PXI-6143
Updated: Wed, 03 Dec 2008 10:51:47 +0000
Updated: Mon, 09 Jan 2012 14:52:48 +0000
These boards are almost identical to the AT-MIO E series, except that
they use the PCI bus instead of ISA (i.e., AT). See the notes for
......@@ -182,6 +183,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = {
{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717f)},
{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71bc)},
{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717d)},
{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x72e8)},
{0}
};
......@@ -1045,6 +1047,25 @@ static const struct ni_board_struct ni_boards[] = {
.caldac = {caldac_none},
.has_8255 = 0,
},
{
.device_id = 0x72e8,
.name = "pxie-6251",
.n_adchan = 16,
.adbits = 16,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 2,
.aobits = 16,
.ao_fifo_depth = 8191,
.ao_range_table = &range_ni_M_625x_ao,
.reg_type = ni_reg_625x,
.ao_unipolar = 0,
.ao_speed = 357,
.num_p0_dio_channels = 8,
.caldac = {caldac_none},
.has_8255 = 0,
},
{
.device_id = 0x70b7,
.name = "pci-6254",
......
......@@ -868,8 +868,7 @@ static enum BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw)
BCMLOG(BCMLOG_DBG, "Stopping TX DMA Engine..\n");
/* FIXME: jarod: invert dma_ctrl and check bit? or are there missing parens? */
if (!dma_cntrl & DMA_START_BIT) {
if (!(dma_cntrl & DMA_START_BIT)) {
BCMLOG(BCMLOG_DBG, "Already Stopped\n");
return BC_STS_SUCCESS;
}
......
......@@ -29,10 +29,10 @@
#define FT1000_PROC "ft1000"
#define MAX_FILE_LEN 255
#define PUTM_TO_PAGE(len,page,args...) \
#define PUTM_TO_PAGE(len, page, args...) \
len += snprintf(page+len, PAGE_SIZE - len, args)
#define PUTX_TO_PAGE(len,page,message,size,var) \
#define PUTX_TO_PAGE(len, page, message, size, var) \
len += snprintf(page+len, PAGE_SIZE - len, message); \
for(i = 0; i < (size - 1); i++) \
{ \
......@@ -40,7 +40,7 @@
} \
len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i])
#define PUTD_TO_PAGE(len,page,message,size,var) \
#define PUTD_TO_PAGE(len, page, message, size, var) \
len += snprintf(page+len, PAGE_SIZE - len, message); \
for(i = 0; i < (size - 1); i++) \
{ \
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
#
obj-$(CONFIG_IIO) += industrialio.o
industrialio-y := industrialio-core.o
industrialio-y := industrialio-core.o industrialio-event.o
industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
......
......@@ -115,9 +115,7 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
return ret;
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->scan_timestamp = true;
ring->access = &ring_sw_access_funcs;
indio_dev->setup_ops = &adis16201_ring_setup_ops;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
......
......@@ -117,9 +117,7 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
return ret;
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->scan_timestamp = true;
ring->access = &ring_sw_access_funcs;
indio_dev->setup_ops = &adis16203_ring_setup_ops;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
......
......@@ -112,8 +112,6 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
return ret;
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
indio_dev->setup_ops = &adis16204_ring_setup_ops;
......
......@@ -113,8 +113,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
return ret;
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
indio_dev->setup_ops = &adis16209_ring_setup_ops;
......
......@@ -110,8 +110,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
return ret;
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
indio_dev->setup_ops = &adis16240_ring_setup_ops;
......
......@@ -187,12 +187,10 @@ void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev);
#ifdef CONFIG_LIS3L02DQ_BUF_RING_SW
#define lis3l02dq_free_buf iio_sw_rb_free
#define lis3l02dq_alloc_buf iio_sw_rb_allocate
#define lis3l02dq_access_funcs ring_sw_access_funcs
#endif
#ifdef CONFIG_LIS3L02DQ_BUF_KFIFO
#define lis3l02dq_free_buf iio_kfifo_free
#define lis3l02dq_alloc_buf iio_kfifo_allocate
#define lis3l02dq_access_funcs kfifo_access_funcs
#endif
irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
#define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
......
......@@ -406,8 +406,6 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
return -ENOMEM;
indio_dev->buffer = buffer;
/* Effectively select the buffer implementation */
indio_dev->buffer->access = &lis3l02dq_access_funcs;
buffer->scan_timestamp = true;
indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
......
......@@ -561,8 +561,6 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev)
ret = -ENOMEM;
goto error_ret;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
&ad7192_trigger_handler,
IRQF_ONESHOT,
......@@ -824,25 +822,20 @@ static struct attribute *ad7192_attributes[] = {
NULL
};
static umode_t ad7192_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad7192_state *st = iio_priv(indio_dev);
umode_t mode = attr->mode;
if ((st->devid != ID_AD7195) &&
(attr == &iio_dev_attr_ac_excitation_en.dev_attr.attr))
mode = 0;
return mode;
}
static const struct attribute_group ad7192_attribute_group = {
.attrs = ad7192_attributes,
.is_visible = ad7192_attr_is_visible,
};
static struct attribute *ad7195_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr,
&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
&iio_dev_attr_bridge_switch_en.dev_attr.attr,
NULL
};
static const struct attribute_group ad7195_attribute_group = {
.attrs = ad7195_attributes,
};
static int ad7192_read_raw(struct iio_dev *indio_dev,
......@@ -972,6 +965,15 @@ static const struct iio_info ad7192_info = {
.driver_module = THIS_MODULE,
};
static const struct iio_info ad7195_info = {
.read_raw = &ad7192_read_raw,
.write_raw = &ad7192_write_raw,
.write_raw_get_fmt = &ad7192_write_raw_get_fmt,
.attrs = &ad7195_attribute_group,
.validate_trigger = ad7192_validate_trigger,
.driver_module = THIS_MODULE,
};
#define AD7192_CHAN_DIFF(_chan, _chan2, _name, _address, _si) \
{ .type = IIO_VOLTAGE, \
.differential = 1, \
......@@ -1064,7 +1066,10 @@ static int __devinit ad7192_probe(struct spi_device *spi)
indio_dev->channels = ad7192_channels;
indio_dev->num_channels = ARRAY_SIZE(ad7192_channels);
indio_dev->available_scan_masks = st->available_scan_masks;
indio_dev->info = &ad7192_info;
if (st->devid == ID_AD7195)
indio_dev->info = &ad7195_info;
else
indio_dev->info = &ad7192_info;
for (i = 0; i < indio_dev->num_channels; i++)
st->available_scan_masks[i] = (1 << i) | (1 <<
......
......@@ -131,9 +131,6 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
ret = -ENOMEM;
goto error_ret;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
&ad7298_trigger_handler,
IRQF_ONESHOT,
......
......@@ -98,8 +98,6 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
ret = -ENOMEM;
goto error_ret;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
indio_dev->pollfunc
= iio_alloc_pollfunc(NULL,
&ad7476_trigger_handler,
......
......@@ -197,7 +197,7 @@ static IIO_DEVICE_ATTR(oversampling_ratio, S_IRUGO | S_IWUSR,
ad7606_store_oversampling_ratio, 0);
static IIO_CONST_ATTR(oversampling_ratio_available, "0 2 4 8 16 32 64");
static struct attribute *ad7606_attributes[] = {
static struct attribute *ad7606_attributes_os_and_range[] = {
&iio_dev_attr_in_voltage_range.dev_attr.attr,
&iio_const_attr_in_voltage_range_available.dev_attr.attr,
&iio_dev_attr_oversampling_ratio.dev_attr.attr,
......@@ -205,34 +205,28 @@ static struct attribute *ad7606_attributes[] = {
NULL,
};
static umode_t ad7606_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad7606_state *st = iio_priv(indio_dev);
static const struct attribute_group ad7606_attribute_group_os_and_range = {
.attrs = ad7606_attributes_os_and_range,
};
umode_t mode = attr->mode;
if (!(gpio_is_valid(st->pdata->gpio_os0) &&
gpio_is_valid(st->pdata->gpio_os1) &&
gpio_is_valid(st->pdata->gpio_os2)) &&
(attr == &iio_dev_attr_oversampling_ratio.dev_attr.attr ||
attr ==
&iio_const_attr_oversampling_ratio_available.dev_attr.attr))
mode = 0;
else if (!gpio_is_valid(st->pdata->gpio_range) &&
(attr == &iio_dev_attr_in_voltage_range.dev_attr.attr ||
attr ==
&iio_const_attr_in_voltage_range_available.dev_attr.attr))
mode = 0;
return mode;
}
static struct attribute *ad7606_attributes_os[] = {
&iio_dev_attr_oversampling_ratio.dev_attr.attr,
&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
NULL,
};
static const struct attribute_group ad7606_attribute_group = {
.attrs = ad7606_attributes,
.is_visible = ad7606_attr_is_visible,
static const struct attribute_group ad7606_attribute_group_os = {
.attrs = ad7606_attributes_os,
};
static struct attribute *ad7606_attributes_range[] = {
&iio_dev_attr_in_voltage_range.dev_attr.attr,
&iio_const_attr_in_voltage_range_available.dev_attr.attr,
NULL,
};
static const struct attribute_group ad7606_attribute_group_range = {
.attrs = ad7606_attributes_range,
};
#define AD7606_CHANNEL(num) \
......@@ -435,10 +429,27 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
};
static const struct iio_info ad7606_info = {
static const struct iio_info ad7606_info_no_os_or_range = {
.driver_module = THIS_MODULE,
.read_raw = &ad7606_read_raw,
.attrs = &ad7606_attribute_group,
};
static const struct iio_info ad7606_info_os_and_range = {
.driver_module = THIS_MODULE,
.read_raw = &ad7606_read_raw,
.attrs = &ad7606_attribute_group_os_and_range,
};
static const struct iio_info ad7606_info_os = {
.driver_module = THIS_MODULE,
.read_raw = &ad7606_read_raw,
.attrs = &ad7606_attribute_group_os,
};
static const struct iio_info ad7606_info_range = {
.driver_module = THIS_MODULE,
.read_raw = &ad7606_read_raw,
.attrs = &ad7606_attribute_group_range,
};
struct iio_dev *ad7606_probe(struct device *dev, int irq,
......@@ -483,7 +494,19 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
st->chip_info = &ad7606_chip_info_tbl[id];
indio_dev->dev.parent = dev;
indio_dev->info = &ad7606_info;
if (gpio_is_valid(st->pdata->gpio_os0) &&
gpio_is_valid(st->pdata->gpio_os1) &&
gpio_is_valid(st->pdata->gpio_os2)) {
if (gpio_is_valid(st->pdata->gpio_range))
indio_dev->info = &ad7606_info_os_and_range;
else
indio_dev->info = &ad7606_info_os;
} else {
if (gpio_is_valid(st->pdata->gpio_range))
indio_dev->info = &ad7606_info_range;
else
indio_dev->info = &ad7606_info_no_os_or_range;
}
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->name = st->chip_info->name;
indio_dev->channels = st->chip_info->channels;
......
......@@ -110,8 +110,6 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
goto error_ret;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh,
&ad7606_trigger_handler_th_bh,
0,
......
......@@ -427,8 +427,6 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev)
ret = -ENOMEM;
goto error_ret;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
&ad7793_trigger_handler,
IRQF_ONESHOT,
......
......@@ -131,8 +131,6 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
ret = -ENOMEM;
goto error_ret;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
&ad7887_trigger_handler,
IRQF_ONESHOT,
......
......@@ -141,8 +141,6 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
ret = -ENOMEM;
goto error_ret;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
&ad799x_trigger_handler,
IRQF_ONESHOT,
......
......@@ -725,32 +725,19 @@ static struct attribute *adt7310_event_int_attributes[] = {
&iio_dev_attr_fault_queue.dev_attr.attr,
&iio_dev_attr_t_alarm_high.dev_attr.attr,
&iio_dev_attr_t_alarm_low.dev_attr.attr,
&iio_dev_attr_t_hyst.dev_attr.attr,
NULL,
};
static struct attribute *adt7310_event_ct_attributes[] = {
&iio_dev_attr_event_mode.dev_attr.attr,
&iio_dev_attr_available_event_modes.dev_attr.attr,
&iio_dev_attr_fault_queue.dev_attr.attr,
&iio_dev_attr_t_crit.dev_attr.attr,
&iio_dev_attr_t_hyst.dev_attr.attr,
NULL,
};
static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = {
{
.attrs = adt7310_event_int_attributes,
.name = "events",
}, {
.attrs = adt7310_event_ct_attributes,
.name = "events",
}
static struct attribute_group adt7310_event_attribute_group = {
.attrs = adt7310_event_int_attributes,
.name = "events",
};
static const struct iio_info adt7310_info = {
.attrs = &adt7310_attribute_group,
.event_attrs = adt7310_event_attribute_group,
.event_attrs = &adt7310_event_attribute_group,
.driver_module = THIS_MODULE,
};
......
......@@ -693,32 +693,19 @@ static struct attribute *adt7410_event_int_attributes[] = {
&iio_dev_attr_fault_queue.dev_attr.attr,
&iio_dev_attr_t_alarm_high.dev_attr.attr,
&iio_dev_attr_t_alarm_low.dev_attr.attr,
&iio_dev_attr_t_hyst.dev_attr.attr,
NULL,
};
static struct attribute *adt7410_event_ct_attributes[] = {
&iio_dev_attr_event_mode.dev_attr.attr,
&iio_dev_attr_available_event_modes.dev_attr.attr,
&iio_dev_attr_fault_queue.dev_attr.attr,
&iio_dev_attr_t_crit.dev_attr.attr,
&iio_dev_attr_t_hyst.dev_attr.attr,
NULL,
};
static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = {
{
.attrs = adt7410_event_int_attributes,
.name = "events",
}, {
.attrs = adt7410_event_ct_attributes,
.name = "events",
}
static struct attribute_group adt7410_event_attribute_group = {
.attrs = adt7410_event_int_attributes,
.name = "events",
};
static const struct iio_info adt7410_info = {
.attrs = &adt7410_attribute_group,
.event_attrs = adt7410_event_attribute_group,
.event_attrs = &adt7410_event_attribute_group,
.driver_module = THIS_MODULE,
};
......
......@@ -116,8 +116,6 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
ret = -ENOMEM;
goto error_deallocate_sw_rb;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
/* Ring buffer functions - here trigger setup related */
indio_dev->setup_ops = &max1363_ring_setup_ops;
......
......@@ -149,30 +149,8 @@ static struct attribute *ad5446_attributes[] = {
NULL,
};
static umode_t ad5446_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad5446_state *st = iio_priv(indio_dev);
umode_t mode = attr->mode;
if (!st->chip_info->store_pwr_down &&
(attr == &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr ||
attr == &iio_dev_attr_out_voltage_powerdown_mode.
dev_attr.attr ||
attr ==
&iio_const_attr_out_voltage_powerdown_mode_available.
dev_attr.attr))
mode = 0;
return mode;
}
static const struct attribute_group ad5446_attribute_group = {
.attrs = ad5446_attributes,
.is_visible = ad5446_attr_is_visible,
};
#define AD5446_CHANNEL(bits, storage, shift) { \
......@@ -321,6 +299,12 @@ static const struct iio_info ad5446_info = {
.driver_module = THIS_MODULE,
};
static const struct iio_info ad5446_info_no_pwr_down = {
.read_raw = ad5446_read_raw,
.write_raw = ad5446_write_raw,
.driver_module = THIS_MODULE,
};
static int __devinit ad5446_probe(struct spi_device *spi)
{
struct ad5446_state *st;
......@@ -353,7 +337,10 @@ static int __devinit ad5446_probe(struct spi_device *spi)
/* Estabilish that the iio_dev is a child of the spi device */
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->info = &ad5446_info;
if (st->chip_info->store_pwr_down)
indio_dev->info = &ad5446_info;
else
indio_dev->info = &ad5446_info_no_pwr_down;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = &st->chip_info->channel;
indio_dev->num_channels = 1;
......
......@@ -281,29 +281,27 @@ static struct attribute *ad9834_attributes[] = {
NULL,
};
static umode_t ad9834_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
struct device *dev = container_of(kobj, struct device, kobj);
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ad9834_state *st = iio_priv(indio_dev);
umode_t mode = attr->mode;
if (((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) &&
((attr == &iio_dev_attr_dds0_out1_enable.dev_attr.attr) ||
(attr == &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr) ||
(attr ==
&iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr) ||
(attr == &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr)))
mode = 0;
return mode;
}
static struct attribute *ad9833_attributes[] = {
&iio_dev_attr_dds0_freq0.dev_attr.attr,
&iio_dev_attr_dds0_freq1.dev_attr.attr,
&iio_const_attr_dds0_freq_scale.dev_attr.attr,
&iio_dev_attr_dds0_phase0.dev_attr.attr,
&iio_dev_attr_dds0_phase1.dev_attr.attr,
&iio_const_attr_dds0_phase_scale.dev_attr.attr,
&iio_dev_attr_dds0_freqsymbol.dev_attr.attr,
&iio_dev_attr_dds0_phasesymbol.dev_attr.attr,
&iio_dev_attr_dds0_out_enable.dev_attr.attr,
&iio_dev_attr_dds0_out0_wavetype.dev_attr.attr,
&iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr,
NULL,
};
static const struct attribute_group ad9834_attribute_group = {
.attrs = ad9834_attributes,
.is_visible = ad9834_attr_is_visible,
};
static const struct attribute_group ad9833_attribute_group = {
.attrs = ad9833_attributes,
};
static const struct iio_info ad9834_info = {
......@@ -311,6 +309,11 @@ static const struct iio_info ad9834_info = {
.driver_module = THIS_MODULE,
};
static const struct iio_info ad9833_info = {
.attrs = &ad9833_attribute_group,
.driver_module = THIS_MODULE,
};
static int __devinit ad9834_probe(struct spi_device *spi)
{
struct ad9834_platform_data *pdata = spi->dev.platform_data;
......@@ -344,7 +347,15 @@ static int __devinit ad9834_probe(struct spi_device *spi)
st->reg = reg;
indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->info = &ad9834_info;
switch (st->devid) {
case ID_AD9833:
case ID_AD9837:
indio_dev->info = &ad9833_info;
break;
default:
indio_dev->info = &ad9834_info;
break;
}
indio_dev->modes = INDIO_DIRECT_MODE;
/* Setup default messages */
......
......@@ -115,8 +115,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
return ret;
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
indio_dev->setup_ops = &adis16260_ring_setup_ops;
......
......@@ -49,4 +49,8 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
#endif
int iio_device_register_eventset(struct iio_dev *indio_dev);
void iio_device_unregister_eventset(struct iio_dev *indio_dev);
int iio_event_getfd(struct iio_dev *indio_dev);
#endif
......@@ -142,8 +142,6 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
}
indio_dev->buffer = buffer;
/* Tell the core how to access the buffer */
buffer->access = &kfifo_access_funcs;
/* Enable timestamps by default */
buffer->scan_timestamp = true;
......
......@@ -607,9 +607,6 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
if (!indio_dev->buffer)
return -ENOMEM;
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
/* Ring buffer functions - here trigger setup related */
indio_dev->setup_ops = &ad5933_ring_setup_ops;
......
......@@ -187,8 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
return ret;
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
indio_dev->setup_ops = &adis16400_ring_setup_ops;
......
This diff is collapsed.
This diff is collapsed.
......@@ -59,21 +59,6 @@ static struct attribute_group iio_kfifo_attribute_group = {
.name = "buffer",
};
struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
{
struct iio_kfifo *kf;
kf = kzalloc(sizeof *kf, GFP_KERNEL);
if (!kf)
return NULL;
kf->update_needed = true;
iio_buffer_init(&kf->buffer);
kf->buffer.attrs = &iio_kfifo_attribute_group;
return &kf->buffer;
}
EXPORT_SYMBOL(iio_kfifo_allocate);
static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r)
{
return r->bytes_per_datum;
......@@ -104,12 +89,6 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length)
return 0;
}
void iio_kfifo_free(struct iio_buffer *r)
{
kfree(iio_to_kfifo(r));
}
EXPORT_SYMBOL(iio_kfifo_free);
static int iio_store_to_kfifo(struct iio_buffer *r,
u8 *data,
s64 timestamp)
......@@ -137,7 +116,7 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r,
return copied;
}
const struct iio_buffer_access_funcs kfifo_access_funcs = {
static const struct iio_buffer_access_funcs kfifo_access_funcs = {
.store_to = &iio_store_to_kfifo,
.read_first_n = &iio_read_first_n_kfifo,
.request_update = &iio_request_update_kfifo,
......@@ -146,6 +125,27 @@ const struct iio_buffer_access_funcs kfifo_access_funcs = {
.get_length = &iio_get_length_kfifo,
.set_length = &iio_set_length_kfifo,
};
EXPORT_SYMBOL(kfifo_access_funcs);
struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
{
struct iio_kfifo *kf;
kf = kzalloc(sizeof *kf, GFP_KERNEL);
if (!kf)
return NULL;
kf->update_needed = true;
iio_buffer_init(&kf->buffer);
kf->buffer.attrs = &iio_kfifo_attribute_group;
kf->buffer.access = &kfifo_access_funcs;
return &kf->buffer;
}
EXPORT_SYMBOL(iio_kfifo_allocate);
void iio_kfifo_free(struct iio_buffer *r)
{
kfree(iio_to_kfifo(r));
}
EXPORT_SYMBOL(iio_kfifo_free);
MODULE_LICENSE("GPL");
......@@ -3,8 +3,6 @@
#include "iio.h"
#include "buffer.h"
extern const struct iio_buffer_access_funcs kfifo_access_funcs;
struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev);
void iio_kfifo_free(struct iio_buffer *r);
......@@ -592,11 +592,18 @@ static const struct i2c_device_id isl29018_id[] = {
MODULE_DEVICE_TABLE(i2c, isl29018_id);
static const struct of_device_id isl29018_of_match[] = {
{ .compatible = "invn,isl29018", },
{ },
};
MODULE_DEVICE_TABLE(of, isl29018_of_match);
static struct i2c_driver isl29018_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "isl29018",
.owner = THIS_MODULE,
.of_match_table = isl29018_of_match,
},
.probe = isl29018_probe,
.remove = __devexit_p(isl29018_remove),
......
......@@ -564,9 +564,17 @@ static const struct i2c_device_id ak8975_id[] = {
MODULE_DEVICE_TABLE(i2c, ak8975_id);
static const struct of_device_id ak8975_of_match[] = {
{ .compatible = "asahi-kasei,ak8975", },
{ .compatible = "ak8975", },
{ }
};
MODULE_DEVICE_TABLE(of, ak8975_of_match);
static struct i2c_driver ak8975_driver = {
.driver = {
.name = "ak8975",
.of_match_table = ak8975_of_match,
},
.probe = ak8975_probe,
.remove = __devexit_p(ak8975_remove),
......
......@@ -144,8 +144,6 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
return ret;
}
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
indio_dev->setup_ops = &ade7758_ring_setup_ops;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
......
......@@ -329,6 +329,16 @@ static struct attribute_group iio_ring_attribute_group = {
.name = "buffer",
};
static const struct iio_buffer_access_funcs ring_sw_access_funcs = {
.store_to = &iio_store_to_sw_rb,
.read_first_n = &iio_read_first_n_sw_rb,
.request_update = &iio_request_update_sw_rb,
.get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb,
.set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb,
.get_length = &iio_get_length_sw_rb,
.set_length = &iio_set_length_sw_rb,
};
struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
{
struct iio_buffer *buf;
......@@ -341,6 +351,7 @@ struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
buf = &ring->buf;
iio_buffer_init(buf);
buf->attrs = &iio_ring_attribute_group;
buf->access = &ring_sw_access_funcs;
return buf;
}
......@@ -352,16 +363,5 @@ void iio_sw_rb_free(struct iio_buffer *r)
}
EXPORT_SYMBOL(iio_sw_rb_free);
const struct iio_buffer_access_funcs ring_sw_access_funcs = {
.store_to = &iio_store_to_sw_rb,
.read_first_n = &iio_read_first_n_sw_rb,
.request_update = &iio_request_update_sw_rb,
.get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb,
.set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb,
.get_length = &iio_get_length_sw_rb,
.set_length = &iio_set_length_sw_rb,
};
EXPORT_SYMBOL(ring_sw_access_funcs);
MODULE_DESCRIPTION("Industrialio I/O software ring buffer");
MODULE_LICENSE("GPL");
......@@ -25,11 +25,6 @@
#define _IIO_RING_SW_H_
#include "buffer.h"
/**
* ring_sw_access_funcs - access functions for a software ring buffer
**/
extern const struct iio_buffer_access_funcs ring_sw_access_funcs;
struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
void iio_sw_rb_free(struct iio_buffer *ring);
#endif /* _IIO_RING_SW_H_ */
......@@ -107,7 +107,7 @@ void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
Wait until unlinking of all currently active capture URBs has been
finished.
*/
static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
{
int timeout = HZ;
unsigned int i;
......@@ -134,7 +134,7 @@ static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
{
line6_unlink_audio_in_urbs(line6pcm);
wait_clear_audio_in_urbs(line6pcm);
line6_wait_clear_audio_in_urbs(line6pcm);
}
/*
......@@ -193,25 +193,6 @@ void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
}
}
int line6_alloc_capture_buffer(struct snd_line6_pcm *line6pcm)
{
/* We may be invoked multiple times in a row so allocate once only */
if (line6pcm->buffer_in)
return 0;
line6pcm->buffer_in =
kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
line6pcm->max_packet_size, GFP_KERNEL);
if (!line6pcm->buffer_in) {
dev_err(line6pcm->line6->ifcdev,
"cannot malloc capture buffer\n");
return -ENOMEM;
}
return 0;
}
void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm)
{
kfree(line6pcm->buffer_in);
......@@ -273,9 +254,9 @@ static void audio_in_callback(struct urb *urb)
line6pcm->prev_fsize = fsize;
#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
if (!(line6pcm->flags & MASK_PCM_IMPULSE))
if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
#endif
if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags)
if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags)
&& (fsize > 0))
line6_capture_copy(line6pcm, fbuf, fsize);
}
......@@ -291,9 +272,9 @@ static void audio_in_callback(struct urb *urb)
submit_audio_in_urb(line6pcm);
#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
if (!(line6pcm->flags & MASK_PCM_IMPULSE))
if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
#endif
if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags))
if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags))
line6_capture_check_period(line6pcm, length);
}
}
......@@ -341,17 +322,17 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
}
/* -- [FD] end */
if ((line6pcm->flags & MASK_CAPTURE) == 0) {
ret = line6_alloc_capture_buffer(line6pcm);
ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
if (ret < 0)
return ret;
}
if (ret < 0)
return ret;
ret = snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params));
if (ret < 0)
if (ret < 0) {
line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
return ret;
}
line6pcm->period_in = params_period_bytes(hw_params);
return 0;
......@@ -361,12 +342,7 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
{
struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
if ((line6pcm->flags & MASK_CAPTURE) == 0) {
line6_unlink_wait_clear_audio_in_urbs(line6pcm);
line6_free_capture_buffer(line6pcm);
}
line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
return snd_pcm_lib_free_pages(substream);
}
......@@ -380,7 +356,7 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
#ifdef CONFIG_PM
case SNDRV_PCM_TRIGGER_RESUME:
#endif
err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_CAPTURE);
err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
if (err < 0)
return err;
......@@ -391,7 +367,7 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
#ifdef CONFIG_PM
case SNDRV_PCM_TRIGGER_SUSPEND:
#endif
err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_CAPTURE);
err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
if (err < 0)
return err;
......
......@@ -19,7 +19,6 @@
extern struct snd_pcm_ops snd_line6_capture_ops;
extern int line6_alloc_capture_buffer(struct snd_line6_pcm *line6pcm);
extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
int fsize);
extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
......@@ -30,6 +29,7 @@ extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);
extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm
*line6pcm);
extern void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd);
#endif
......@@ -1346,7 +1346,7 @@ static void __exit line6_exit(void)
if (line6pcm == NULL)
continue;
line6_pcm_stop(line6pcm, ~0);
line6_pcm_release(line6pcm, ~0);
}
usb_deregister(&line6_driver);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -29,13 +29,13 @@
extern struct snd_pcm_ops snd_line6_playback_ops;
extern int line6_alloc_playback_buffer(struct snd_line6_pcm *line6pcm);
extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm);
extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm);
extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm
*line6pcm);
extern void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd);
#endif
......@@ -207,9 +207,9 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
line6pcm->volume_monitor = ucontrol->value.integer.value[0];
if (line6pcm->volume_monitor > 0)
line6_pcm_start(line6pcm, MASK_PCM_MONITOR);
line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR);
else
line6_pcm_stop(line6pcm, MASK_PCM_MONITOR);
line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
return 1;
}
......@@ -264,7 +264,7 @@ static void toneport_start_pcm(unsigned long arg)
{
struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
struct usb_line6 *line6 = &toneport->line6;
line6_pcm_start(line6->line6pcm, MASK_PCM_MONITOR);
line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR);
}
/* control definition */
......@@ -320,7 +320,9 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
/* initialize source select: */
switch (usbdev->descriptor.idProduct) {
case LINE6_DEVID_TONEPORT_UX1:
case LINE6_DEVID_TONEPORT_UX2:
case LINE6_DEVID_PODSTUDIO_UX1:
case LINE6_DEVID_PODSTUDIO_UX2:
toneport_send_cmd(usbdev,
toneport_source_info[toneport->source].code,
0x0000);
......@@ -363,7 +365,9 @@ static int toneport_try_init(struct usb_interface *interface,
/* register source select control: */
switch (usbdev->descriptor.idProduct) {
case LINE6_DEVID_TONEPORT_UX1:
case LINE6_DEVID_TONEPORT_UX2:
case LINE6_DEVID_PODSTUDIO_UX1:
case LINE6_DEVID_PODSTUDIO_UX2:
err =
snd_ctl_add(line6->card,
snd_ctl_new1(&toneport_control_source,
......@@ -442,7 +446,7 @@ void line6_toneport_disconnect(struct usb_interface *interface)
struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
if (line6pcm != NULL) {
line6_pcm_stop(line6pcm, MASK_PCM_MONITOR);
line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
line6_pcm_disconnect(line6pcm);
}
}
......
This diff is collapsed.
......@@ -3825,6 +3825,7 @@ static int easycap_usb_probe(struct usb_interface *intf,
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
if (!pdata_urb) {
usb_free_urb(purb);
SAM("ERROR: Could not allocate struct data_urb.\n");
return -ENOMEM;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment