Merge git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (25 commits)
powerpc: Fix config dependency problem with MPIC_U3_HT_IRQS
via-pmu: Add compat_pmu_ioctl
powerpc: Wire up fanotify_init, fanotify_mark, prlimit64 syscalls
powerpc/pci: Fix checking for child bridges in PCI code.
powerpc: Fix typo in uImage target
powerpc: Initialise paca->kstack before early_setup_secondary
powerpc: Fix bogus it_blocksize in VIO iommu code
powerpc: Inline ppc64_runlatch_off
powerpc: Correct smt_enabled=X boot option for > 2 threads per core
powerpc: Silence xics_migrate_irqs_away() during cpu offline
powerpc: Silence __cpu_up() under normal operation
powerpc: Re-enable preemption before cpu_die()
powerpc/pci: Drop unnecessary null test
powerpc/powermac: Drop unnecessary null test
powerpc/powermac: Drop unnecessary of_node_put
powerpc/kdump: Stop all other CPUs before running crash handlers
powerpc/mm: Fix vsid_scrample typo
powerpc: Use is_32bit_task() helper to test 32 bit binary
powerpc: Export memstart_addr and kernstart_addr on ppc64
powerpc: Make rwsem use "long" type
...
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
index 575ff1a..339150a 100644
--- a/arch/arm/mach-imx/mach-cpuimx27.c
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -279,13 +279,13 @@
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
#endif
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index a389d11..23c9e1f 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -419,13 +419,13 @@
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
#endif
diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c
index 56b2e26..a5f0174 100644
--- a/arch/arm/mach-mx25/mach-cpuimx25.c
+++ b/arch/arm/mach-mx25/mach-cpuimx25.c
@@ -138,7 +138,7 @@
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_otg, &otg_pdata);
}
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c
index 63f970f..9770a6a 100644
--- a/arch/arm/mach-mx3/mach-cpuimx35.c
+++ b/arch/arm/mach-mx3/mach-cpuimx35.c
@@ -192,7 +192,7 @@
#if defined(CONFIG_USB_ULPI)
if (otg_mode_host) {
otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
- USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
mxc_register_device(&mxc_otg_host, &otg_pdata);
}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index c8a44f5..40af43e 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -568,7 +568,7 @@
out:
if (retval) {
release_firmware(firmware);
- firmware_p = NULL;
+ *firmware_p = NULL;
}
return retval;
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 07f3ea3..d4b71e8 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -1650,7 +1650,7 @@
/* disable DSS reporting */
i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
- if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
+ if (tty->termios->c_cflag & HUPCL) {
i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
@@ -2930,6 +2930,8 @@
if ( pCh )
{
rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
+ if (rc)
+ rc = -EFAULT;
} else {
rc = -ENODEV;
}
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 79c3bc6..7c79d24 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -1244,6 +1244,7 @@
}
info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
configure_r_port(tty, info, NULL);
+ mutex_unlock(&info->port.mutex);
return 0;
}
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index fef80cf..e63b830 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -691,8 +691,10 @@
if (info->port.count == 1) {
/* 1st open on this device, init hardware */
retval = startup(info);
- if (retval < 0)
+ if (retval < 0) {
+ mutex_unlock(&info->port.mutex);
goto cleanup;
+ }
}
mutex_unlock(&info->port.mutex);
retval = block_til_ready(tty, filp, info);
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 7356a56a..be0ebce 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -869,7 +869,9 @@
tmp.close_delay = info->close_delay;
tmp.closing_wait = info->closing_wait;
tmp.custom_divisor = info->custom_divisor;
- copy_to_user(retinfo,&tmp,sizeof(*retinfo));
+ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+ return -EFAULT;
+
return 0;
}
@@ -882,7 +884,8 @@
if (!new_info)
return -EFAULT;
- copy_from_user(&new_serial,new_info,sizeof(new_serial));
+ if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+ return -EFAULT;
old_info = *info;
if (!capable(CAP_SYS_ADMIN)) {
@@ -943,8 +946,7 @@
status = 0;
#endif
local_irq_restore(flags);
- put_user(status,value);
- return 0;
+ return put_user(status, value);
}
/*
@@ -999,27 +1001,18 @@
send_break(info, arg ? arg*(100) : 250);
return 0;
case TIOCGSERIAL:
- if (access_ok(VERIFY_WRITE, (void *) arg,
- sizeof(struct serial_struct)))
- return get_serial_info(info,
- (struct serial_struct *) arg);
- return -EFAULT;
+ return get_serial_info(info,
+ (struct serial_struct *) arg);
case TIOCSSERIAL:
return set_serial_info(info,
(struct serial_struct *) arg);
case TIOCSERGETLSR: /* Get line status register */
- if (access_ok(VERIFY_WRITE, (void *) arg,
- sizeof(unsigned int)))
- return get_lsr_info(info, (unsigned int *) arg);
- return -EFAULT;
+ return get_lsr_info(info, (unsigned int *) arg);
case TIOCSERGSTRUCT:
- if (!access_ok(VERIFY_WRITE, (void *) arg,
- sizeof(struct m68k_serial)))
+ if (copy_to_user((struct m68k_serial *) arg,
+ info, sizeof(struct m68k_serial)))
return -EFAULT;
- copy_to_user((struct m68k_serial *) arg,
- info, sizeof(struct m68k_serial));
return 0;
-
default:
return -ENOIOCTLCMD;
}
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c
index b745792..eaafb98 100644
--- a/drivers/serial/8250_early.c
+++ b/drivers/serial/8250_early.c
@@ -203,13 +203,13 @@
if (mmio || mmio32)
printk(KERN_INFO
- "Early serial console at MMIO%s 0x%llu (options '%s')\n",
+ "Early serial console at MMIO%s 0x%llx (options '%s')\n",
mmio32 ? "32" : "",
(unsigned long long)port->mapbase,
device->options);
else
printk(KERN_INFO
- "Early serial console at I/O port 0x%lu (options '%s')\n",
+ "Early serial console at I/O port 0x%lx (options '%s')\n",
port->iobase,
device->options);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 4a7a7a7..335311a 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -113,8 +113,6 @@
source "drivers/staging/memrar/Kconfig"
-source "drivers/staging/sep/Kconfig"
-
source "drivers/staging/iio/Kconfig"
source "drivers/staging/zram/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index ca5c03e..e3f1e1b 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -38,7 +38,6 @@
obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
-obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_ZRAM) += zram/
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c
index b4a8d5e..05ca15a 100644
--- a/drivers/staging/batman-adv/bat_sysfs.c
+++ b/drivers/staging/batman-adv/bat_sysfs.c
@@ -267,6 +267,10 @@
if (atomic_read(&bat_priv->log_level) == log_level_tmp)
return count;
+ bat_info(net_dev, "Changing log level from: %i to: %li\n",
+ atomic_read(&bat_priv->log_level),
+ log_level_tmp);
+
atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp);
return count;
}
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index 92c216a..baa8b05 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -129,6 +129,9 @@
static void update_mac_addresses(struct batman_if *batman_if)
{
+ if (!batman_if || !batman_if->packet_buff)
+ return;
+
addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
@@ -194,8 +197,6 @@
if (batman_if->if_status != IF_INACTIVE)
return;
- dev_hold(batman_if->net_dev);
-
update_mac_addresses(batman_if);
batman_if->if_status = IF_TO_BE_ACTIVATED;
@@ -222,8 +223,6 @@
(batman_if->if_status != IF_TO_BE_ACTIVATED))
return;
- dev_put(batman_if->net_dev);
-
batman_if->if_status = IF_INACTIVE;
bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
@@ -318,11 +317,13 @@
if (ret != 1)
goto out;
+ dev_hold(net_dev);
+
batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
if (!batman_if) {
pr_err("Can't add interface (%s): out of memory\n",
net_dev->name);
- goto out;
+ goto release_dev;
}
batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
@@ -336,6 +337,7 @@
batman_if->if_num = -1;
batman_if->net_dev = net_dev;
batman_if->if_status = IF_NOT_IN_USE;
+ batman_if->packet_buff = NULL;
INIT_LIST_HEAD(&batman_if->list);
check_known_mac_addr(batman_if->net_dev->dev_addr);
@@ -346,6 +348,8 @@
kfree(batman_if->dev);
free_if:
kfree(batman_if);
+release_dev:
+ dev_put(net_dev);
out:
return NULL;
}
@@ -374,6 +378,7 @@
batman_if->if_status = IF_TO_BE_REMOVED;
list_del_rcu(&batman_if->list);
sysfs_del_hardif(&batman_if->hardif_obj);
+ dev_put(batman_if->net_dev);
call_rcu(&batman_if->rcu, hardif_free_interface);
}
@@ -393,15 +398,13 @@
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
- if (!batman_if)
- batman_if = hardif_add_interface(net_dev);
+ if (!batman_if && event == NETDEV_REGISTER)
+ batman_if = hardif_add_interface(net_dev);
if (!batman_if)
goto out;
switch (event) {
- case NETDEV_REGISTER:
- break;
case NETDEV_UP:
hardif_activate_interface(soft_device, bat_priv, batman_if);
break;
@@ -442,8 +445,6 @@
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct batman_packet *batman_packet;
struct batman_if *batman_if;
- struct net_device_stats *stats;
- struct rtnl_link_stats64 temp;
int ret;
skb = skb_share_check(skb, GFP_ATOMIC);
@@ -479,12 +480,6 @@
if (batman_if->if_status != IF_ACTIVE)
goto err_free;
- stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp);
- if (stats) {
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
- }
-
batman_packet = (struct batman_packet *)skb->data;
if (batman_packet->version != COMPAT_VERSION) {
diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c
index fc3d32c..3ae7dd2 100644
--- a/drivers/staging/batman-adv/icmp_socket.c
+++ b/drivers/staging/batman-adv/icmp_socket.c
@@ -67,6 +67,7 @@
INIT_LIST_HEAD(&socket_client->queue_list);
socket_client->queue_len = 0;
socket_client->index = i;
+ socket_client->bat_priv = inode->i_private;
spin_lock_init(&socket_client->lock);
init_waitqueue_head(&socket_client->queue_wait);
@@ -151,9 +152,8 @@
static ssize_t bat_socket_write(struct file *file, const char __user *buff,
size_t len, loff_t *off)
{
- /* FIXME: each orig_node->batman_if will be attached to a softif */
- struct bat_priv *bat_priv = netdev_priv(soft_device);
struct socket_client *socket_client = file->private_data;
+ struct bat_priv *bat_priv = socket_client->bat_priv;
struct icmp_packet_rr icmp_packet;
struct orig_node *orig_node;
struct batman_if *batman_if;
@@ -168,6 +168,9 @@
return -EINVAL;
}
+ if (!bat_priv->primary_if)
+ return -EFAULT;
+
if (len >= sizeof(struct icmp_packet_rr))
packet_len = sizeof(struct icmp_packet_rr);
@@ -223,7 +226,8 @@
if (batman_if->if_status != IF_ACTIVE)
goto dst_unreach;
- memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN);
+ memcpy(icmp_packet.orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
if (packet_len == sizeof(struct icmp_packet_rr))
memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN);
@@ -271,7 +275,7 @@
goto err;
d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR,
- bat_priv->debug_dir, NULL, &fops);
+ bat_priv->debug_dir, bat_priv, &fops);
if (d)
goto err;
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c
index 2686019..ef7c20a 100644
--- a/drivers/staging/batman-adv/main.c
+++ b/drivers/staging/batman-adv/main.c
@@ -250,10 +250,13 @@
int is_my_mac(uint8_t *addr)
{
struct batman_if *batman_if;
+
rcu_read_lock();
list_for_each_entry_rcu(batman_if, &if_list, list) {
- if ((batman_if->net_dev) &&
- (compare_orig(batman_if->net_dev->dev_addr, addr))) {
+ if (batman_if->if_status != IF_ACTIVE)
+ continue;
+
+ if (compare_orig(batman_if->net_dev->dev_addr, addr)) {
rcu_read_unlock();
return 1;
}
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c
index 28bb627..de5a8c1 100644
--- a/drivers/staging/batman-adv/originator.c
+++ b/drivers/staging/batman-adv/originator.c
@@ -391,11 +391,12 @@
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
{
struct orig_node *orig_node;
+ unsigned long flags;
HASHIT(hashit);
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@@ -404,11 +405,11 @@
goto err;
}
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return 0;
err:
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return -ENOMEM;
}
@@ -468,12 +469,13 @@
{
struct batman_if *batman_if_tmp;
struct orig_node *orig_node;
+ unsigned long flags;
HASHIT(hashit);
int ret;
/* resize all orig nodes because orig_node->bcast_own(_sum) depend on
* if_num */
- spin_lock(&orig_hash_lock);
+ spin_lock_irqsave(&orig_hash_lock, flags);
while (hash_iterate(orig_hash, &hashit)) {
orig_node = hashit.bucket->data;
@@ -500,10 +502,10 @@
rcu_read_unlock();
batman_if->if_num = -1;
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return 0;
err:
- spin_unlock(&orig_hash_lock);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
return -ENOMEM;
}
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c
index 066cc91..032195e 100644
--- a/drivers/staging/batman-adv/routing.c
+++ b/drivers/staging/batman-adv/routing.c
@@ -783,6 +783,8 @@
static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len)
{
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct icmp_packet_rr *icmp_packet;
struct ethhdr *ethhdr;
@@ -801,6 +803,9 @@
return NET_RX_DROP;
}
+ if (!bat_priv->primary_if)
+ return NET_RX_DROP;
+
/* answer echo request (ping) */
/* get routing information */
spin_lock_irqsave(&orig_hash_lock, flags);
@@ -830,7 +835,8 @@
}
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
+ memcpy(icmp_packet->orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = ECHO_REPLY;
icmp_packet->ttl = TTL;
@@ -845,6 +851,8 @@
static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len)
{
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
struct orig_node *orig_node;
struct icmp_packet *icmp_packet;
struct ethhdr *ethhdr;
@@ -865,6 +873,9 @@
return NET_RX_DROP;
}
+ if (!bat_priv->primary_if)
+ return NET_RX_DROP;
+
/* get routing information */
spin_lock_irqsave(&orig_hash_lock, flags);
orig_node = ((struct orig_node *)
@@ -892,7 +903,8 @@
}
memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
- memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
+ memcpy(icmp_packet->orig,
+ bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN);
icmp_packet->msg_type = TTL_EXCEEDED;
icmp_packet->ttl = TTL;
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h
index 21d0717..9aa9d36 100644
--- a/drivers/staging/batman-adv/types.h
+++ b/drivers/staging/batman-adv/types.h
@@ -126,6 +126,7 @@
unsigned char index;
spinlock_t lock;
wait_queue_head_t queue_wait;
+ struct bat_priv *bat_priv;
};
struct socket_packet {
diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig
deleted file mode 100644
index 0a9c39c..0000000
--- a/drivers/staging/sep/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config DX_SEP
- tristate "Discretix SEP driver"
-# depends on MRST
- depends on RAR_REGISTER && PCI
- default y
- help
- Discretix SEP driver
-
- If unsure say M. The compiled module will be
- called sep_driver.ko
diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile
deleted file mode 100644
index 628d5f9..0000000
--- a/drivers/staging/sep/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_DX_SEP) := sep_driver.o
-
diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO
deleted file mode 100644
index ff0e931..0000000
--- a/drivers/staging/sep/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
-Todo's so far (from Alan Cox)
-- Fix firmware loading
-- Get firmware into firmware git tree
-- Review and tidy each algorithm function
-- Check whether it can be plugged into any of the kernel crypto API
- interfaces
-- Do something about the magic shared memory interface and replace it
- with something saner (in Linux terms)
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h
deleted file mode 100644
index 9200524..0000000
--- a/drivers/staging/sep/sep_dev.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef __SEP_DEV_H__
-#define __SEP_DEV_H__
-
-/*
- *
- * sep_dev.h - Security Processor Device Structures
- *
- * Copyright(c) 2009 Intel Corporation. All rights reserved.
- * Copyright(c) 2009 Discretix. 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.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Alan Cox alan@linux.intel.com
- *
- */
-
-struct sep_device {
- /* pointer to pci dev */
- struct pci_dev *pdev;
-
- unsigned long in_use;
-
- /* address of the shared memory allocated during init for SEP driver
- (coherent alloc) */
- void *shared_addr;
- /* the physical address of the shared area */
- dma_addr_t shared_bus;
-
- /* restricted access region (coherent alloc) */
- dma_addr_t rar_bus;
- void *rar_addr;
- /* firmware regions: cache is at rar_addr */
- unsigned long cache_size;
-
- /* follows the cache */
- dma_addr_t resident_bus;
- unsigned long resident_size;
- void *resident_addr;
-
- /* start address of the access to the SEP registers from driver */
- void __iomem *reg_addr;
- /* transaction counter that coordinates the transactions between SEP and HOST */
- unsigned long send_ct;
- /* counter for the messages from sep */
- unsigned long reply_ct;
- /* counter for the number of bytes allocated in the pool for the current
- transaction */
- unsigned long data_pool_bytes_allocated;
-
- /* array of pointers to the pages that represent input data for the synchronic
- DMA action */
- struct page **in_page_array;
-
- /* array of pointers to the pages that represent out data for the synchronic
- DMA action */
- struct page **out_page_array;
-
- /* number of pages in the sep_in_page_array */
- unsigned long in_num_pages;
-
- /* number of pages in the sep_out_page_array */
- unsigned long out_num_pages;
-
- /* global data for every flow */
- struct sep_flow_context_t flows[SEP_DRIVER_NUM_FLOWS];
-
- /* pointer to the workqueue that handles the flow done interrupts */
- struct workqueue_struct *flow_wq;
-
-};
-
-static struct sep_device *sep_dev;
-
-static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value)
-{
- void __iomem *addr = dev->reg_addr + reg;
- writel(value, addr);
-}
-
-static inline u32 sep_read_reg(struct sep_device *dev, int reg)
-{
- void __iomem *addr = dev->reg_addr + reg;
- return readl(addr);
-}
-
-/* wait for SRAM write complete(indirect write */
-static inline void sep_wait_sram_write(struct sep_device *dev)
-{
- u32 reg_val;
- do
- reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR);
- while (!(reg_val & 1));
-}
-
-
-#endif
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
deleted file mode 100644
index ecbde34..0000000
--- a/drivers/staging/sep/sep_driver.c
+++ /dev/null
@@ -1,2742 +0,0 @@
-/*
- *
- * sep_driver.c - Security Processor Driver main group of functions
- *
- * Copyright(c) 2009 Intel Corporation. All rights reserved.
- * Copyright(c) 2009 Discretix. 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.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- *
- * CHANGES:
- *
- * 2009.06.26 Initial publish
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/kdev_t.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <asm/ioctl.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <linux/interrupt.h>
-#include <linux/pagemap.h>
-#include <asm/cacheflush.h>
-#include "sep_driver_hw_defs.h"
-#include "sep_driver_config.h"
-#include "sep_driver_api.h"
-#include "sep_dev.h"
-
-#if SEP_DRIVER_ARM_DEBUG_MODE
-
-#define CRYS_SEP_ROM_length 0x4000
-#define CRYS_SEP_ROM_start_address 0x8000C000UL
-#define CRYS_SEP_ROM_start_address_offset 0xC000UL
-#define SEP_ROM_BANK_register 0x80008420UL
-#define SEP_ROM_BANK_register_offset 0x8420UL
-#define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0x82000000
-
-/*
- * THESE 2 definitions are specific to the board - must be
- * defined during integration
- */
-#define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0xFF0D0000
-
-/* 2M size */
-
-static void sep_load_rom_code(struct sep_device *sep)
-{
- /* Index variables */
- unsigned long i, k, j;
- u32 reg;
- u32 error;
- u32 warning;
-
- /* Loading ROM from SEP_ROM_image.h file */
- k = sizeof(CRYS_SEP_ROM);
-
- edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n");
-
- edbg("SEP Driver: k is %lu\n", k);
- edbg("SEP Driver: sep->reg_addr is %p\n", sep->reg_addr);
- edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset);
-
- for (i = 0; i < 4; i++) {
- /* write bank */
- sep_write_reg(sep, SEP_ROM_BANK_register_offset, i);
-
- for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) {
- sep_write_reg(sep, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]);
-
- k = k - 4;
-
- if (k == 0) {
- j = CRYS_SEP_ROM_length;
- i = 4;
- }
- }
- }
-
- /* reset the SEP */
- sep_write_reg(sep, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1);
-
- /* poll for SEP ROM boot finish */
- do
- reg = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
- while (!reg);
-
- edbg("SEP Driver: ROM polling ended\n");
-
- switch (reg) {
- case 0x1:
- /* fatal error - read erro status from GPRO */
- error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
- edbg("SEP Driver: ROM polling case 1\n");
- break;
- case 0x4:
- /* Cold boot ended successfully */
- case 0x8:
- /* Warmboot ended successfully */
- case 0x10:
- /* ColdWarm boot ended successfully */
- error = 0;
- case 0x2:
- /* Boot First Phase ended */
- warning = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
- case 0x20:
- edbg("SEP Driver: ROM polling case %d\n", reg);
- break;
- }
-
-}
-
-#else
-static void sep_load_rom_code(struct sep_device *sep) { }
-#endif /* SEP_DRIVER_ARM_DEBUG_MODE */
-
-
-
-/*----------------------------------------
- DEFINES
------------------------------------------*/
-
-#define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000
-#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
-
-/*--------------------------------------------
- GLOBAL variables
---------------------------------------------*/
-
-/* debug messages level */
-static int debug;
-module_param(debug, int , 0);
-MODULE_PARM_DESC(debug, "Flag to enable SEP debug messages");
-
-/* Keep this a single static object for now to keep the conversion easy */
-
-static struct sep_device sep_instance;
-static struct sep_device *sep_dev = &sep_instance;
-
-/*
- mutex for the access to the internals of the sep driver
-*/
-static DEFINE_MUTEX(sep_mutex);
-
-
-/* wait queue head (event) of the driver */
-static DECLARE_WAIT_QUEUE_HEAD(sep_event);
-
-/**
- * sep_load_firmware - copy firmware cache/resident
- * @sep: device we are loading
- *
- * This functions copies the cache and resident from their source
- * location into destination shared memory.
- */
-
-static int sep_load_firmware(struct sep_device *sep)
-{
- const struct firmware *fw;
- char *cache_name = "sep/cache.image.bin";
- char *res_name = "sep/resident.image.bin";
- int error;
-
- edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
- edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
-
- /* load cache */
- error = request_firmware(&fw, cache_name, &sep->pdev->dev);
- if (error) {
- edbg("SEP Driver:cant request cache fw\n");
- return error;
- }
- edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data);
-
- memcpy(sep->rar_addr, (void *)fw->data, fw->size);
- sep->cache_size = fw->size;
- release_firmware(fw);
-
- sep->resident_bus = sep->rar_bus + sep->cache_size;
- sep->resident_addr = sep->rar_addr + sep->cache_size;
-
- /* load resident */
- error = request_firmware(&fw, res_name, &sep->pdev->dev);
- if (error) {
- edbg("SEP Driver:cant request res fw\n");
- return error;
- }
- edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data);
-
- memcpy(sep->resident_addr, (void *) fw->data, fw->size);
- sep->resident_size = fw->size;
- release_firmware(fw);
-
- edbg("sep: resident v %p b %08llx cache v %p b %08llx\n",
- sep->resident_addr, (unsigned long long)sep->resident_bus,
- sep->rar_addr, (unsigned long long)sep->rar_bus);
- return 0;
-}
-
-MODULE_FIRMWARE("sep/cache.image.bin");
-MODULE_FIRMWARE("sep/resident.image.bin");
-
-/**
- * sep_map_and_alloc_shared_area - allocate shared block
- * @sep: security processor
- * @size: size of shared area
- *
- * Allocate a shared buffer in host memory that can be used by both the
- * kernel and also the hardware interface via DMA.
- */
-
-static int sep_map_and_alloc_shared_area(struct sep_device *sep,
- unsigned long size)
-{
- /* shared_addr = ioremap_nocache(0xda00000,shared_area_size); */
- sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, size,
- &sep->shared_bus, GFP_KERNEL);
-
- if (!sep->shared_addr) {
- edbg("sep_driver :shared memory dma_alloc_coherent failed\n");
- return -ENOMEM;
- }
- /* set the bus address of the shared area */
- edbg("sep: shared_addr %ld bytes @%p (bus %08llx)\n",
- size, sep->shared_addr, (unsigned long long)sep->shared_bus);
- return 0;
-}
-
-/**
- * sep_unmap_and_free_shared_area - free shared block
- * @sep: security processor
- *
- * Free the shared area allocated to the security processor. The
- * processor must have finished with this and any final posted
- * writes cleared before we do so.
- */
-static void sep_unmap_and_free_shared_area(struct sep_device *sep, int size)
-{
- dma_free_coherent(&sep->pdev->dev, size,
- sep->shared_addr, sep->shared_bus);
-}
-
-/**
- * sep_shared_virt_to_bus - convert bus/virt addresses
- *
- * Returns the bus address inside the shared area according
- * to the virtual address.
- */
-
-static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep,
- void *virt_address)
-{
- dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
- edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa,
- virt_address);
- return pa;
-}
-
-/**
- * sep_shared_bus_to_virt - convert bus/virt addresses
- *
- * Returns virtual address inside the shared area according
- * to the bus address.
- */
-
-static void *sep_shared_bus_to_virt(struct sep_device *sep,
- dma_addr_t bus_address)
-{
- return sep->shared_addr + (bus_address - sep->shared_bus);
-}
-
-
-/**
- * sep_try_open - attempt to open a SEP device
- * @sep: device to attempt to open
- *
- * Atomically attempt to get ownership of a SEP device.
- * Returns 1 if the device was opened, 0 on failure.
- */
-
-static int sep_try_open(struct sep_device *sep)
-{
- if (!test_and_set_bit(0, &sep->in_use))
- return 1;
- return 0;
-}
-
-/**
- * sep_open - device open method
- * @inode: inode of sep device
- * @filp: file handle to sep device
- *
- * Open method for the SEP device. Called when userspace opens
- * the SEP device node. Must also release the memory data pool
- * allocations.
- *
- * Returns zero on success otherwise an error code.
- */
-
-static int sep_open(struct inode *inode, struct file *filp)
-{
- if (sep_dev == NULL)
- return -ENODEV;
-
- /* check the blocking mode */
- if (filp->f_flags & O_NDELAY) {
- if (sep_try_open(sep_dev) == 0)
- return -EAGAIN;
- } else
- if (wait_event_interruptible(sep_event, sep_try_open(sep_dev)) < 0)
- return -EINTR;
-
- /* Bind to the device, we only have one which makes it easy */
- filp->private_data = sep_dev;
- /* release data pool allocations */
- sep_dev->data_pool_bytes_allocated = 0;
- return 0;
-}
-
-
-/**
- * sep_release - close a SEP device
- * @inode: inode of SEP device
- * @filp: file handle being closed
- *
- * Called on the final close of a SEP device. As the open protects against
- * multiple simultaenous opens that means this method is called when the
- * final reference to the open handle is dropped.
- */
-
-static int sep_release(struct inode *inode, struct file *filp)
-{
- struct sep_device *sep = filp->private_data;
-#if 0 /*!SEP_DRIVER_POLLING_MODE */
- /* close IMR */
- sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
- /* release IRQ line */
- free_irq(SEP_DIRVER_IRQ_NUM, sep);
-
-#endif
- /* Ensure any blocked open progresses */
- clear_bit(0, &sep->in_use);
- wake_up(&sep_event);
- return 0;
-}
-
-/*---------------------------------------------------------------
- map function - this functions maps the message shared area
------------------------------------------------------------------*/
-static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- dma_addr_t bus_addr;
- struct sep_device *sep = filp->private_data;
-
- dbg("-------->SEP Driver: mmap start\n");
-
- /* check that the size of the mapped range is as the size of the message
- shared area */
- if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
- edbg("SEP Driver mmap requested size is more than allowed\n");
- printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n");
- printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
- printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
- return -EAGAIN;
- }
-
- edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
-
- /* get bus address */
- bus_addr = sep->shared_bus;
-
- edbg("SEP Driver: phys_addr is %08llx\n", (unsigned long long)bus_addr);
-
- if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
- edbg("SEP Driver remap_page_range failed\n");
- printk(KERN_WARNING "SEP Driver remap_page_range failed\n");
- return -EAGAIN;
- }
-
- dbg("SEP Driver:<-------- mmap end\n");
-
- return 0;
-}
-
-
-/*-----------------------------------------------
- poll function
-*----------------------------------------------*/
-static unsigned int sep_poll(struct file *filp, poll_table * wait)
-{
- unsigned long count;
- unsigned int mask = 0;
- unsigned long retval = 0; /* flow id */
- struct sep_device *sep = filp->private_data;
-
- dbg("---------->SEP Driver poll: start\n");
-
-
-#if SEP_DRIVER_POLLING_MODE
-
- while (sep->send_ct != (retval & 0x7FFFFFFF)) {
- retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
-
- for (count = 0; count < 10 * 4; count += 4)
- edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count)));
- }
-
- sep->reply_ct++;
-#else
- /* add the event to the polling wait table */
- poll_wait(filp, &sep_event, wait);
-
-#endif
-
- edbg("sep->send_ct is %lu\n", sep->send_ct);
- edbg("sep->reply_ct is %lu\n", sep->reply_ct);
-
- /* check if the data is ready */
- if (sep->send_ct == sep->reply_ct) {
- for (count = 0; count < 12 * 4; count += 4)
- edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count)));
-
- for (count = 0; count < 10 * 4; count += 4)
- edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + 0x1800 + count)));
-
- retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
- edbg("retval is %lu\n", retval);
- /* check if the this is sep reply or request */
- if (retval >> 31) {
- edbg("SEP Driver: sep request in\n");
- /* request */
- mask |= POLLOUT | POLLWRNORM;
- } else {
- edbg("SEP Driver: sep reply in\n");
- mask |= POLLIN | POLLRDNORM;
- }
- }
- dbg("SEP Driver:<-------- poll exit\n");
- return mask;
-}
-
-/**
- * sep_time_address - address in SEP memory of time
- * @sep: SEP device we want the address from
- *
- * Return the address of the two dwords in memory used for time
- * setting.
- */
-
-static u32 *sep_time_address(struct sep_device *sep)
-{
- return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
-}
-
-/**
- * sep_set_time - set the SEP time
- * @sep: the SEP we are setting the time for
- *
- * Calculates time and sets it at the predefined address.
- * Called with the sep mutex held.
- */
-static unsigned long sep_set_time(struct sep_device *sep)
-{
- struct timeval time;
- u32 *time_addr; /* address of time as seen by the kernel */
-
-
- dbg("sep:sep_set_time start\n");
-
- do_gettimeofday(&time);
-
- /* set value in the SYSTEM MEMORY offset */
- time_addr = sep_time_address(sep);
-
- time_addr[0] = SEP_TIME_VAL_TOKEN;
- time_addr[1] = time.tv_sec;
-
- edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec);
- edbg("SEP Driver:time_addr is %p\n", time_addr);
- edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
-
- return time.tv_sec;
-}
-
-/**
- * sep_dump_message - dump the message that is pending
- * @sep: sep device
- *
- * Dump out the message pending in the shared message area
- */
-
-static void sep_dump_message(struct sep_device *sep)
-{
- int count;
- for (count = 0; count < 12 * 4; count += 4)
- edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count)));
-}
-
-/**
- * sep_send_command_handler - kick off a command
- * @sep: sep being signalled
- *
- * This function raises interrupt to SEP that signals that is has a new
- * command from the host
- */
-
-static void sep_send_command_handler(struct sep_device *sep)
-{
- dbg("sep:sep_send_command_handler start\n");
-
- mutex_lock(&sep_mutex);
- sep_set_time(sep);
-
- /* FIXME: flush cache */
- flush_cache_all();
-
- sep_dump_message(sep);
- /* update counter */
- sep->send_ct++;
- /* send interrupt to SEP */
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
- dbg("SEP Driver:<-------- sep_send_command_handler end\n");
- mutex_unlock(&sep_mutex);
- return;
-}
-
-/**
- * sep_send_reply_command_handler - kick off a command reply
- * @sep: sep being signalled
- *
- * This function raises interrupt to SEP that signals that is has a new
- * command from the host
- */
-
-static void sep_send_reply_command_handler(struct sep_device *sep)
-{
- dbg("sep:sep_send_reply_command_handler start\n");
-
- /* flash cache */
- flush_cache_all();
-
- sep_dump_message(sep);
-
- mutex_lock(&sep_mutex);
- sep->send_ct++; /* update counter */
- /* send the interrupt to SEP */
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct);
- /* update both counters */
- sep->send_ct++;
- sep->reply_ct++;
- mutex_unlock(&sep_mutex);
- dbg("sep: sep_send_reply_command_handler end\n");
-}
-
-/*
- This function handles the allocate data pool memory request
- This function returns calculates the bus address of the
- allocated memory, and the offset of this area from the mapped address.
- Therefore, the FVOs in user space can calculate the exact virtual
- address of this allocated memory
-*/
-static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
- unsigned long arg)
-{
- int error;
- struct sep_driver_alloc_t command_args;
-
- dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n");
-
- error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t));
- if (error) {
- error = -EFAULT;
- goto end_function;
- }
-
- /* allocate memory */
- if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
- error = -ENOMEM;
- goto end_function;
- }
-
- /* set the virtual and bus address */
- command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
- command_args.phys_address = sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
-
- /* write the memory back to the user space */
- error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t));
- if (error) {
- error = -EFAULT;
- goto end_function;
- }
-
- /* set the allocation */
- sep->data_pool_bytes_allocated += command_args.num_bytes;
-
-end_function:
- dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n");
- return error;
-}
-
-/*
- This function handles write into allocated data pool command
-*/
-static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned long arg)
-{
- int error;
- void *virt_address;
- unsigned long va;
- unsigned long app_in_address;
- unsigned long num_bytes;
- void *data_pool_area_addr;
-
- dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n");
-
- /* get the application address */
- error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address));
- if (error)
- goto end_function;
-
- /* get the virtual kernel address address */
- error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
- if (error)
- goto end_function;
- virt_address = (void *)va;
-
- /* get the number of bytes */
- error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
- if (error)
- goto end_function;
-
- /* calculate the start of the data pool */
- data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
-
-
- /* check that the range of the virtual kernel address is correct */
- if (virt_address < data_pool_area_addr || virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)) {
- error = -EINVAL;
- goto end_function;
- }
- /* copy the application data */
- error = copy_from_user(virt_address, (void *) app_in_address, num_bytes);
- if (error)
- error = -EFAULT;
-end_function:
- dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n");
- return error;
-}
-
-/*
- this function handles the read from data pool command
-*/
-static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long arg)
-{
- int error;
- /* virtual address of dest application buffer */
- unsigned long app_out_address;
- /* virtual address of the data pool */
- unsigned long va;
- void *virt_address;
- unsigned long num_bytes;
- void *data_pool_area_addr;
-
- dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n");
-
- /* get the application address */
- error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address));
- if (error)
- goto end_function;
-
- /* get the virtual kernel address address */
- error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
- if (error)
- goto end_function;
- virt_address = (void *)va;
-
- /* get the number of bytes */
- error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
- if (error)
- goto end_function;
-
- /* calculate the start of the data pool */
- data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
-
- /* FIXME: These are incomplete all over the driver: what about + len
- and when doing that also overflows */
- /* check that the range of the virtual kernel address is correct */
- if (virt_address < data_pool_area_addr || virt_address > data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
- error = -EINVAL;
- goto end_function;
- }
-
- /* copy the application data */
- error = copy_to_user((void *) app_out_address, virt_address, num_bytes);
- if (error)
- error = -EFAULT;
-end_function:
- dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n");
- return error;
-}
-
-/*
- This function releases all the application virtual buffer physical pages,
- that were previously locked
-*/
-static int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag)
-{
- unsigned long count;
-
- if (dirtyFlag) {
- for (count = 0; count < num_pages; count++) {
- /* the out array was written, therefore the data was changed */
- if (!PageReserved(page_array_ptr[count]))
- SetPageDirty(page_array_ptr[count]);
- page_cache_release(page_array_ptr[count]);
- }
- } else {
- /* free in pages - the data was only read, therefore no update was done
- on those pages */
- for (count = 0; count < num_pages; count++)
- page_cache_release(page_array_ptr[count]);
- }
-
- if (page_array_ptr)
- /* free the array */
- kfree(page_array_ptr);
-
- return 0;
-}
-
-/*
- This function locks all the physical pages of the kernel virtual buffer
- and construct a basic lli array, where each entry holds the physical
- page address and the size that application data holds in this physical pages
-*/
-static int sep_lock_kernel_pages(struct sep_device *sep,
- unsigned long kernel_virt_addr,
- unsigned long data_size,
- unsigned long *num_pages_ptr,
- struct sep_lli_entry_t **lli_array_ptr,
- struct page ***page_array_ptr)
-{
- int error = 0;
- /* the the page of the end address of the user space buffer */
- unsigned long end_page;
- /* the page of the start address of the user space buffer */
- unsigned long start_page;
- /* the range in pages */
- unsigned long num_pages;
- struct sep_lli_entry_t *lli_array;
- /* next kernel address to map */
- unsigned long next_kernel_address;
- unsigned long count;
-
- dbg("SEP Driver:--------> sep_lock_kernel_pages start\n");
-
- /* set start and end pages and num pages */
- end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT;
- start_page = kernel_virt_addr >> PAGE_SHIFT;
- num_pages = end_page - start_page + 1;
-
- edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr);
- edbg("SEP Driver: data_size is %lu\n", data_size);
- edbg("SEP Driver: start_page is %lx\n", start_page);
- edbg("SEP Driver: end_page is %lx\n", end_page);
- edbg("SEP Driver: num_pages is %lu\n", num_pages);
-
- lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
- if (!lli_array) {
- edbg("SEP Driver: kmalloc for lli_array failed\n");
- error = -ENOMEM;
- goto end_function;
- }
-
- /* set the start address of the first page - app data may start not at
- the beginning of the page */
- lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr);
-
- /* check that not all the data is in the first page only */
- if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size)
- lli_array[0].block_size = data_size;
- else
- lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK));
-
- /* debug print */
- dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
-
- /* advance the address to the start of the next page */
- next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE;
-
- /* go from the second page to the prev before last */
- for (count = 1; count < (num_pages - 1); count++) {
- lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
- lli_array[count].block_size = PAGE_SIZE;
-
- edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
- next_kernel_address += PAGE_SIZE;
- }
-
- /* if more then 1 pages locked - then update for the last page size needed */
- if (num_pages > 1) {
- /* update the address of the last page */
- lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
-
- /* set the size of the last page */
- lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK);
-
- if (lli_array[count].block_size == 0) {
- dbg("app_virt_addr is %08lx\n", kernel_virt_addr);
- dbg("data_size is %lu\n", data_size);
- while (1);
- }
-
- edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
- }
- /* set output params */
- *lli_array_ptr = lli_array;
- *num_pages_ptr = num_pages;
- *page_array_ptr = 0;
-end_function:
- dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n");
- return 0;
-}
-
-/*
- This function locks all the physical pages of the application virtual buffer
- and construct a basic lli array, where each entry holds the physical page
- address and the size that application data holds in this physical pages
-*/
-static int sep_lock_user_pages(struct sep_device *sep,
- unsigned long app_virt_addr,
- unsigned long data_size,
- unsigned long *num_pages_ptr,
- struct sep_lli_entry_t **lli_array_ptr,
- struct page ***page_array_ptr)
-{
- int error = 0;
- /* the the page of the end address of the user space buffer */
- unsigned long end_page;
- /* the page of the start address of the user space buffer */
- unsigned long start_page;
- /* the range in pages */
- unsigned long num_pages;
- struct page **page_array;
- struct sep_lli_entry_t *lli_array;
- unsigned long count;
- int result;
-
- dbg("SEP Driver:--------> sep_lock_user_pages start\n");
-
- /* set start and end pages and num pages */
- end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
- start_page = app_virt_addr >> PAGE_SHIFT;
- num_pages = end_page - start_page + 1;
-
- edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr);
- edbg("SEP Driver: data_size is %lu\n", data_size);
- edbg("SEP Driver: start_page is %lu\n", start_page);
- edbg("SEP Driver: end_page is %lu\n", end_page);
- edbg("SEP Driver: num_pages is %lu\n", num_pages);
-
- /* allocate array of pages structure pointers */
- page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
- if (!page_array) {
- edbg("SEP Driver: kmalloc for page_array failed\n");
-
- error = -ENOMEM;
- goto end_function;
- }
-
- lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
- if (!lli_array) {
- edbg("SEP Driver: kmalloc for lli_array failed\n");
-
- error = -ENOMEM;
- goto end_function_with_error1;
- }
-
- /* convert the application virtual address into a set of physical */
- down_read(¤t->mm->mmap_sem);
- result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0);
- up_read(¤t->mm->mmap_sem);
-
- /* check the number of pages locked - if not all then exit with error */
- if (result != num_pages) {
- dbg("SEP Driver: not all pages locked by get_user_pages\n");
-
- error = -ENOMEM;
- goto end_function_with_error2;
- }
-
- /* flush the cache */
- for (count = 0; count < num_pages; count++)
- flush_dcache_page(page_array[count]);
-
- /* set the start address of the first page - app data may start not at
- the beginning of the page */
- lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK));
-
- /* check that not all the data is in the first page only */
- if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
- lli_array[0].block_size = data_size;
- else
- lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
-
- /* debug print */
- dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
-
- /* go from the second page to the prev before last */
- for (count = 1; count < (num_pages - 1); count++) {
- lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
- lli_array[count].block_size = PAGE_SIZE;
-
- edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
- }
-
- /* if more then 1 pages locked - then update for the last page size needed */
- if (num_pages > 1) {
- /* update the address of the last page */
- lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
-
- /* set the size of the last page */
- lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK);
-
- if (lli_array[count].block_size == 0) {
- dbg("app_virt_addr is %08lx\n", app_virt_addr);
- dbg("data_size is %lu\n", data_size);
- while (1);
- }
- edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n",
- count, lli_array[count].physical_address,
- count, lli_array[count].block_size);
- }
-
- /* set output params */
- *lli_array_ptr = lli_array;
- *num_pages_ptr = num_pages;
- *page_array_ptr = page_array;
- goto end_function;
-
-end_function_with_error2:
- /* release the cache */
- for (count = 0; count < num_pages; count++)
- page_cache_release(page_array[count]);
- kfree(lli_array);
-end_function_with_error1:
- kfree(page_array);
-end_function:
- dbg("SEP Driver:<-------- sep_lock_user_pages end\n");
- return 0;
-}
-
-
-/*
- this function calculates the size of data that can be inserted into the lli
- table from this array the condition is that either the table is full
- (all etnries are entered), or there are no more entries in the lli array
-*/
-static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries)
-{
- unsigned long table_data_size = 0;
- unsigned long counter;
-
- /* calculate the data in the out lli table if till we fill the whole
- table or till the data has ended */
- for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++)
- table_data_size += lli_in_array_ptr[counter].block_size;
- return table_data_size;
-}
-
-/*
- this functions builds ont lli table from the lli_array according to
- the given size of data
-*/
-static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size)
-{
- unsigned long curr_table_data_size;
- /* counter of lli array entry */
- unsigned long array_counter;
-
- dbg("SEP Driver:--------> sep_build_lli_table start\n");
-
- /* init currrent table data size and lli array entry counter */
- curr_table_data_size = 0;
- array_counter = 0;
- *num_table_entries_ptr = 1;
-
- edbg("SEP Driver:table_data_size is %lu\n", table_data_size);
-
- /* fill the table till table size reaches the needed amount */
- while (curr_table_data_size < table_data_size) {
- /* update the number of entries in table */
- (*num_table_entries_ptr)++;
-
- lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address;
- lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size;
- curr_table_data_size += lli_table_ptr->block_size;
-
- edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
- edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
- edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
-
- /* check for overflow of the table data */
- if (curr_table_data_size > table_data_size) {
- edbg("SEP Driver:curr_table_data_size > table_data_size\n");
-
- /* update the size of block in the table */
- lli_table_ptr->block_size -= (curr_table_data_size - table_data_size);
-
- /* update the physical address in the lli array */
- lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size;
-
- /* update the block size left in the lli array */
- lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size);
- } else
- /* advance to the next entry in the lli_array */
- array_counter++;
-
- edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
- edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
-
- /* move to the next entry in table */
- lli_table_ptr++;
- }
-
- /* set the info entry to default */
- lli_table_ptr->physical_address = 0xffffffff;
- lli_table_ptr->block_size = 0;
-
- edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
- edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
- edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
-
- /* set the output parameter */
- *num_processed_entries_ptr += array_counter;
-
- edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr);
- dbg("SEP Driver:<-------- sep_build_lli_table end\n");
- return;
-}
-
-/*
- this function goes over the list of the print created tables and
- prints all the data
-*/
-static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size)
-{
- unsigned long table_count;
- unsigned long entries_count;
-
- dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n");
-
- table_count = 1;
- while ((unsigned long) lli_table_ptr != 0xffffffff) {
- edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size);
- edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries);
-
- /* print entries of the table (without info entry) */
- for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) {
- edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr);
- edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size);
- }
-
- /* point to the info entry */
- lli_table_ptr--;
-
- edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
- edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
-
-
- table_data_size = lli_table_ptr->block_size & 0xffffff;
- num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
- lli_table_ptr = (struct sep_lli_entry_t *)
- (lli_table_ptr->physical_address);
-
- edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr);
-
- if ((unsigned long) lli_table_ptr != 0xffffffff)
- lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_bus_to_virt(sep, (unsigned long) lli_table_ptr);
-
- table_count++;
- }
- dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n");
-}
-
-
-/*
- This function prepares only input DMA table for synhronic symmetric
- operations (HASH)
-*/
-static int sep_prepare_input_dma_table(struct sep_device *sep,
- unsigned long app_virt_addr,
- unsigned long data_size,
- unsigned long block_size,
- unsigned long *lli_table_ptr,
- unsigned long *num_entries_ptr,
- unsigned long *table_data_size_ptr,
- bool isKernelVirtualAddress)
-{
- /* pointer to the info entry of the table - the last entry */
- struct sep_lli_entry_t *info_entry_ptr;
- /* array of pointers ot page */
- struct sep_lli_entry_t *lli_array_ptr;
- /* points to the first entry to be processed in the lli_in_array */
- unsigned long current_entry;
- /* num entries in the virtual buffer */
- unsigned long sep_lli_entries;
- /* lli table pointer */
- struct sep_lli_entry_t *in_lli_table_ptr;
- /* the total data in one table */
- unsigned long table_data_size;
- /* number of entries in lli table */
- unsigned long num_entries_in_table;
- /* next table address */
- void *lli_table_alloc_addr;
- unsigned long result;
-
- dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n");
-
- edbg("SEP Driver:data_size is %lu\n", data_size);
- edbg("SEP Driver:block_size is %lu\n", block_size);
-
- /* initialize the pages pointers */
- sep->in_page_array = 0;
- sep->in_num_pages = 0;
-
- if (data_size == 0) {
- /* special case - created 2 entries table with zero data */
- in_lli_table_ptr = (struct sep_lli_entry_t *) (sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES);
- /* FIXME: Should the entry below not be for _bus */
- in_lli_table_ptr->physical_address = (unsigned long)sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
- in_lli_table_ptr->block_size = 0;
-
- in_lli_table_ptr++;
- in_lli_table_ptr->physical_address = 0xFFFFFFFF;
- in_lli_table_ptr->block_size = 0;
-
- *lli_table_ptr = sep->shared_bus + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
- *num_entries_ptr = 2;
- *table_data_size_ptr = 0;
-
- goto end_function;
- }
-
- /* check if the pages are in Kernel Virtual Address layout */
- if (isKernelVirtualAddress == true)
- /* lock the pages of the kernel buffer and translate them to pages */
- result = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
- else
- /* lock the pages of the user buffer and translate them to pages */
- result = sep_lock_user_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
-
- if (result)
- return result;
-
- edbg("SEP Driver:output sep->in_num_pages is %lu\n", sep->in_num_pages);
-
- current_entry = 0;
- info_entry_ptr = 0;
- sep_lli_entries = sep->in_num_pages;
-
- /* initiate to point after the message area */
- lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
-
- /* loop till all the entries in in array are not processed */
- while (current_entry < sep_lli_entries) {
- /* set the new input and output tables */
- in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
-
- lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
- /* calculate the maximum size of data for input table */
- table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry));
-
- /* now calculate the table size so that it will be module block size */
- table_data_size = (table_data_size / block_size) * block_size;
-
- edbg("SEP Driver:output table_data_size is %lu\n", table_data_size);
-
- /* construct input lli table */
- sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, ¤t_entry, &num_entries_in_table, table_data_size);
-
- if (info_entry_ptr == 0) {
- /* set the output parameters to physical addresses */
- *lli_table_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
- *num_entries_ptr = num_entries_in_table;
- *table_data_size_ptr = table_data_size;
-
- edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr);
- } else {
- /* update the info entry of the previous in table */
- info_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
- info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
- }
-
- /* save the pointer to the info entry of the current tables */
- info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
- }
-
- /* print input tables */
- sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
- sep_shared_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr);
-
- /* the array of the pages */
- kfree(lli_array_ptr);
-end_function:
- dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n");
- return 0;
-
-}
-
-/*
- This function creates the input and output dma tables for
- symmetric operations (AES/DES) according to the block size from LLI arays
-*/
-static int sep_construct_dma_tables_from_lli(struct sep_device *sep,
- struct sep_lli_entry_t *lli_in_array,
- unsigned long sep_in_lli_entries,
- struct sep_lli_entry_t *lli_out_array,
- unsigned long sep_out_lli_entries,
- unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr)
-{
- /* points to the area where next lli table can be allocated: keep void *
- as there is pointer scaling to fix otherwise */
- void *lli_table_alloc_addr;
- /* input lli table */
- struct sep_lli_entry_t *in_lli_table_ptr;
- /* output lli table */
- struct sep_lli_entry_t *out_lli_table_ptr;
- /* pointer to the info entry of the table - the last entry */
- struct sep_lli_entry_t *info_in_entry_ptr;
- /* pointer to the info entry of the table - the last entry */
- struct sep_lli_entry_t *info_out_entry_ptr;
- /* points to the first entry to be processed in the lli_in_array */
- unsigned long current_in_entry;
- /* points to the first entry to be processed in the lli_out_array */
- unsigned long current_out_entry;
- /* max size of the input table */
- unsigned long in_table_data_size;
- /* max size of the output table */
- unsigned long out_table_data_size;
- /* flag te signifies if this is the first tables build from the arrays */
- unsigned long first_table_flag;
- /* the data size that should be in table */
- unsigned long table_data_size;
- /* number of etnries in the input table */
- unsigned long num_entries_in_table;
- /* number of etnries in the output table */
- unsigned long num_entries_out_table;
-
- dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n");
-
- /* initiate to pint after the message area */
- lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
-
- current_in_entry = 0;
- current_out_entry = 0;
- first_table_flag = 1;
- info_in_entry_ptr = 0;
- info_out_entry_ptr = 0;
-
- /* loop till all the entries in in array are not processed */
- while (current_in_entry < sep_in_lli_entries) {
- /* set the new input and output tables */
- in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
-
- lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
- /* set the first output tables */
- out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
-
- lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
- /* calculate the maximum size of data for input table */
- in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry));
-
- /* calculate the maximum size of data for output table */
- out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry));
-
- edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size);
- edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size);
-
- /* check where the data is smallest */
- table_data_size = in_table_data_size;
- if (table_data_size > out_table_data_size)
- table_data_size = out_table_data_size;
-
- /* now calculate the table size so that it will be module block size */
- table_data_size = (table_data_size / block_size) * block_size;
-
- dbg("SEP Driver:table_data_size is %lu\n", table_data_size);
-
- /* construct input lli table */
- sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, ¤t_in_entry, &num_entries_in_table, table_data_size);
-
- /* construct output lli table */
- sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, ¤t_out_entry, &num_entries_out_table, table_data_size);
-
- /* if info entry is null - this is the first table built */
- if (info_in_entry_ptr == 0) {
- /* set the output parameters to physical addresses */
- *lli_table_in_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
- *in_num_entries_ptr = num_entries_in_table;
- *lli_table_out_ptr = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
- *out_num_entries_ptr = num_entries_out_table;
- *table_data_size_ptr = table_data_size;
-
- edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr);
- edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr);
- } else {
- /* update the info entry of the previous in table */
- info_in_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
- info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
-
- /* update the info entry of the previous in table */
- info_out_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
- info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size);
- }
-
- /* save the pointer to the info entry of the current tables */
- info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
- info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1;
-
- edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table);
- edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr);
- edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr);
- }
-
- /* print input tables */
- sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
- sep_shared_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr);
- /* print output tables */
- sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
- sep_shared_bus_to_virt(sep, *lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr);
- dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n");
- return 0;
-}
-
-
-/*
- This function builds input and output DMA tables for synhronic
- symmetric operations (AES, DES). It also checks that each table
- is of the modular block size
-*/
-static int sep_prepare_input_output_dma_table(struct sep_device *sep,
- unsigned long app_virt_in_addr,
- unsigned long app_virt_out_addr,
- unsigned long data_size,
- unsigned long block_size,
- unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress)
-{
- /* array of pointers of page */
- struct sep_lli_entry_t *lli_in_array;
- /* array of pointers of page */
- struct sep_lli_entry_t *lli_out_array;
- int result = 0;
-
- dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n");
-
- /* initialize the pages pointers */
- sep->in_page_array = 0;
- sep->out_page_array = 0;
-
- /* check if the pages are in Kernel Virtual Address layout */
- if (isKernelVirtualAddress == true) {
- /* lock the pages of the kernel buffer and translate them to pages */
- result = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
- if (result) {
- edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n");
- goto end_function;
- }
- } else {
- /* lock the pages of the user buffer and translate them to pages */
- result = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
- if (result) {
- edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n");
- goto end_function;
- }
- }
-
- if (isKernelVirtualAddress == true) {
- result = sep_lock_kernel_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
- if (result) {
- edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n");
- goto end_function_with_error1;
- }
- } else {
- result = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
- if (result) {
- edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n");
- goto end_function_with_error1;
- }
- }
- edbg("sep->in_num_pages is %lu\n", sep->in_num_pages);
- edbg("sep->out_num_pages is %lu\n", sep->out_num_pages);
- edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
-
-
- /* call the fucntion that creates table from the lli arrays */
- result = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->in_num_pages, lli_out_array, sep->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr);
- if (result) {
- edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n");
- goto end_function_with_error2;
- }
-
- /* fall through - free the lli entry arrays */
- dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr);
- dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr);
- dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr);
-end_function_with_error2:
- kfree(lli_out_array);
-end_function_with_error1:
- kfree(lli_in_array);
-end_function:
- dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result);
- return result;
-
-}
-
-/*
- this function handles tha request for creation of the DMA table
- for the synchronic symmetric operations (AES,DES)
-*/
-static int sep_create_sync_dma_tables_handler(struct sep_device *sep,
- unsigned long arg)
-{
- int error;
- /* command arguments */
- struct sep_driver_build_sync_table_t command_args;
-
- dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n");
-
- error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t));
- if (error) {
- error = -EFAULT;
- goto end_function;
- }
-
- edbg("app_in_address is %08lx\n", command_args.app_in_address);
- edbg("app_out_address is %08lx\n", command_args.app_out_address);
- edbg("data_size is %lu\n", command_args.data_in_size);
- edbg("block_size is %lu\n", command_args.block_size);
-
- /* check if we need to build only input table or input/output */
- if (command_args.app_out_address)
- /* prepare input and output tables */
- error = sep_prepare_input_output_dma_table(sep,
- command_args.app_in_address,
- command_args.app_out_address,
- command_args.data_in_size,
- command_args.block_size,
- &command_args.in_table_address,
- &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
- else
- /* prepare input tables */
- error = sep_prepare_input_dma_table(sep,
- command_args.app_in_address,
- command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
-
- if (error)
- goto end_function;
- /* copy to user */
- if (copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t)))
- error = -EFAULT;
-end_function:
- dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n");
- return error;
-}
-
-/*
- this function handles the request for freeing dma table for synhronic actions
-*/
-static int sep_free_dma_table_data_handler(struct sep_device *sep)
-{
- dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n");
-
- /* free input pages array */
- sep_free_dma_pages(sep->in_page_array, sep->in_num_pages, 0);
-
- /* free output pages array if needed */
- if (sep->out_page_array)
- sep_free_dma_pages(sep->out_page_array, sep->out_num_pages, 1);
-
- /* reset all the values */
- sep->in_page_array = 0;
- sep->out_page_array = 0;
- sep->in_num_pages = 0;
- sep->out_num_pages = 0;
- dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n");
- return 0;
-}
-
-/*
- this function find a space for the new flow dma table
-*/
-static int sep_find_free_flow_dma_table_space(struct sep_device *sep,
- unsigned long **table_address_ptr)
-{
- int error = 0;
- /* pointer to the id field of the flow dma table */
- unsigned long *start_table_ptr;
- /* Do not make start_addr unsigned long * unless fixing the offset
- computations ! */
- void *flow_dma_area_start_addr;
- unsigned long *flow_dma_area_end_addr;
- /* maximum table size in words */
- unsigned long table_size_in_words;
-
- /* find the start address of the flow DMA table area */
- flow_dma_area_start_addr = sep->shared_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES;
-
- /* set end address of the flow table area */
- flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES;
-
- /* set table size in words */
- table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2;
-
- /* set the pointer to the start address of DMA area */
- start_table_ptr = flow_dma_area_start_addr;
-
- /* find the space for the next table */
- while (((*start_table_ptr & 0x7FFFFFFF) != 0) && start_table_ptr < flow_dma_area_end_addr)
- start_table_ptr += table_size_in_words;
-
- /* check if we reached the end of floa tables area */
- if (start_table_ptr >= flow_dma_area_end_addr)
- error = -1;
- else
- *table_address_ptr = start_table_ptr;
-
- return error;
-}
-
-/*
- This function creates one DMA table for flow and returns its data,
- and pointer to its info entry
-*/
-static int sep_prepare_one_flow_dma_table(struct sep_device *sep,
- unsigned long virt_buff_addr,
- unsigned long virt_buff_size,
- struct sep_lli_entry_t *table_data,
- struct sep_lli_entry_t **info_entry_ptr,
- struct sep_flow_context_t *flow_data_ptr,
- bool isKernelVirtualAddress)
-{
- int error;
- /* the range in pages */
- unsigned long lli_array_size;
- struct sep_lli_entry_t *lli_array;
- struct sep_lli_entry_t *flow_dma_table_entry_ptr;
- unsigned long *start_dma_table_ptr;
- /* total table data counter */
- unsigned long dma_table_data_count;
- /* pointer that will keep the pointer to the pages of the virtual buffer */
- struct page **page_array_ptr;
- unsigned long entry_count;
-
- /* find the space for the new table */
- error = sep_find_free_flow_dma_table_space(sep, &start_dma_table_ptr);
- if (error)
- goto end_function;
-
- /* check if the pages are in Kernel Virtual Address layout */
- if (isKernelVirtualAddress == true)
- /* lock kernel buffer in the memory */
- error = sep_lock_kernel_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
- else
- /* lock user buffer in the memory */
- error = sep_lock_user_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
-
- if (error)
- goto end_function;
-
- /* set the pointer to page array at the beginning of table - this table is
- now considered taken */
- *start_dma_table_ptr = lli_array_size;
-
- /* point to the place of the pages pointers of the table */
- start_dma_table_ptr++;
-
- /* set the pages pointer */
- *start_dma_table_ptr = (unsigned long) page_array_ptr;
-
- /* set the pointer to the first entry */
- flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr);
-
- /* now create the entries for table */
- for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) {
- flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address;
-
- flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size;
-
- /* set the total data of a table */
- dma_table_data_count += lli_array[entry_count].block_size;
-
- flow_dma_table_entry_ptr++;
- }
-
- /* set the physical address */
- table_data->physical_address = virt_to_phys(start_dma_table_ptr);
-
- /* set the num_entries and total data size */
- table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count);
-
- /* set the info entry */
- flow_dma_table_entry_ptr->physical_address = 0xffffffff;
- flow_dma_table_entry_ptr->block_size = 0;
-
- /* set the pointer to info entry */
- *info_entry_ptr = flow_dma_table_entry_ptr;
-
- /* the array of the lli entries */
- kfree(lli_array);
-end_function:
- return error;
-}
-
-
-
-/*
- This function creates a list of tables for flow and returns the data for
- the first and last tables of the list
-*/
-static int sep_prepare_flow_dma_tables(struct sep_device *sep,
- unsigned long num_virtual_buffers,
- unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress)
-{
- int error;
- unsigned long virt_buff_addr;
- unsigned long virt_buff_size;
- struct sep_lli_entry_t table_data;
- struct sep_lli_entry_t *info_entry_ptr;
- struct sep_lli_entry_t *prev_info_entry_ptr;
- unsigned long i;
-
- /* init vars */
- error = 0;
- prev_info_entry_ptr = 0;
-
- /* init the first table to default */
- table_data.physical_address = 0xffffffff;
- first_table_data_ptr->physical_address = 0xffffffff;
- table_data.block_size = 0;
-
- for (i = 0; i < num_virtual_buffers; i++) {
- /* get the virtual buffer address */
- error = get_user(virt_buff_addr, &first_buff_addr);
- if (error)
- goto end_function;
-
- /* get the virtual buffer size */
- first_buff_addr++;
- error = get_user(virt_buff_size, &first_buff_addr);
- if (error)
- goto end_function;
-
- /* advance the address to point to the next pair of address|size */
- first_buff_addr++;
-
- /* now prepare the one flow LLI table from the data */
- error = sep_prepare_one_flow_dma_table(sep, virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress);
- if (error)
- goto end_function;
-
- if (i == 0) {
- /* if this is the first table - save it to return to the user
- application */
- *first_table_data_ptr = table_data;
-
- /* set the pointer to info entry */
- prev_info_entry_ptr = info_entry_ptr;
- } else {
- /* not first table - the previous table info entry should
- be updated */
- prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size);
-
- /* set the pointer to info entry */
- prev_info_entry_ptr = info_entry_ptr;
- }
- }
-
- /* set the last table data */
- *last_table_data_ptr = table_data;
-end_function:
- return error;
-}
-
-/*
- this function goes over all the flow tables connected to the given
- table and deallocate them
-*/
-static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr)
-{
- /* id pointer */
- unsigned long *table_ptr;
- /* end address of the flow dma area */
- unsigned long num_entries;
- unsigned long num_pages;
- struct page **pages_ptr;
- /* maximum table size in words */
- struct sep_lli_entry_t *info_entry_ptr;
-
- /* set the pointer to the first table */
- table_ptr = (unsigned long *) first_table_ptr->physical_address;
-
- /* set the num of entries */
- num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS)
- & SEP_NUM_ENTRIES_MASK;
-
- /* go over all the connected tables */
- while (*table_ptr != 0xffffffff) {
- /* get number of pages */
- num_pages = *(table_ptr - 2);
-
- /* get the pointer to the pages */
- pages_ptr = (struct page **) (*(table_ptr - 1));
-
- /* free the pages */
- sep_free_dma_pages(pages_ptr, num_pages, 1);
-
- /* goto to the info entry */
- info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1);
-
- table_ptr = (unsigned long *) info_entry_ptr->physical_address;
- num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
- }
-
- return;
-}
-
-/**
- * sep_find_flow_context - find a flow
- * @sep: the SEP we are working with
- * @flow_id: flow identifier
- *
- * Returns a pointer the matching flow, or NULL if the flow does not
- * exist.
- */
-
-static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep,
- unsigned long flow_id)
-{
- int count;
- /*
- * always search for flow with id default first - in case we
- * already started working on the flow there can be no situation
- * when 2 flows are with default flag
- */
- for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) {
- if (sep->flows[count].flow_id == flow_id)
- return &sep->flows[count];
- }
- return NULL;
-}
-
-
-/*
- this function handles the request to create the DMA tables for flow
-*/
-static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
- unsigned long arg)
-{
- int error = -ENOENT;
- struct sep_driver_build_flow_table_t command_args;
- /* first table - output */
- struct sep_lli_entry_t first_table_data;
- /* dma table data */
- struct sep_lli_entry_t last_table_data;
- /* pointer to the info entry of the previuos DMA table */
- struct sep_lli_entry_t *prev_info_entry_ptr;
- /* pointer to the flow data strucutre */
- struct sep_flow_context_t *flow_context_ptr;
-
- dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n");
-
- /* init variables */
- prev_info_entry_ptr = 0;
- first_table_data.physical_address = 0xffffffff;
-
- /* find the free structure for flow data */
- error = -EINVAL;
- flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID);
- if (flow_context_ptr == NULL)
- goto end_function;
-
- error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t));
- if (error) {
- error = -EFAULT;
- goto end_function;
- }
-
- /* create flow tables */
- error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
- if (error)
- goto end_function_with_error;
-
- /* check if flow is static */
- if (!command_args.flow_type)
- /* point the info entry of the last to the info entry of the first */
- last_table_data = first_table_data;
-
- /* set output params */
- command_args.first_table_addr = first_table_data.physical_address;
- command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
- command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
-
- /* send the parameters to user application */
- error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t));
- if (error) {
- error = -EFAULT;
- goto end_function_with_error;
- }
-
- /* all the flow created - update the flow entry with temp id */
- flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID;
-
- /* set the processing tables data in the context */
- if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG)
- flow_context_ptr->input_tables_in_process = first_table_data;
- else
- flow_context_ptr->output_tables_in_process = first_table_data;
-
- goto end_function;
-
-end_function_with_error:
- /* free the allocated tables */
- sep_deallocated_flow_tables(&first_table_data);
-end_function:
- dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n");
- return error;
-}
-
-/*
- this function handles add tables to flow
-*/
-static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg)
-{
- int error;
- unsigned long num_entries;
- struct sep_driver_add_flow_table_t command_args;
- struct sep_flow_context_t *flow_context_ptr;
- /* first dma table data */
- struct sep_lli_entry_t first_table_data;
- /* last dma table data */
- struct sep_lli_entry_t last_table_data;
- /* pointer to the info entry of the current DMA table */
- struct sep_lli_entry_t *info_entry_ptr;
-
- dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n");
-
- /* get input parameters */
- error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t));
- if (error) {
- error = -EFAULT;
- goto end_function;
- }
-
- /* find the flow structure for the flow id */
- flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
- if (flow_context_ptr == NULL)
- goto end_function;
-
- /* prepare the flow dma tables */
- error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
- if (error)
- goto end_function_with_error;
-
- /* now check if there is already an existing add table for this flow */
- if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) {
- /* this buffer was for input buffers */
- if (flow_context_ptr->input_tables_flag) {
- /* add table already exists - add the new tables to the end
- of the previous */
- num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
-
- info_entry_ptr = (struct sep_lli_entry_t *)
- (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
-
- /* connect to list of tables */
- *info_entry_ptr = first_table_data;
-
- /* set the first table data */
- first_table_data = flow_context_ptr->first_input_table;
- } else {
- /* set the input flag */
- flow_context_ptr->input_tables_flag = 1;
-
- /* set the first table data */
- flow_context_ptr->first_input_table = first_table_data;
- }
- /* set the last table data */
- flow_context_ptr->last_input_table = last_table_data;
- } else { /* this is output tables */
-
- /* this buffer was for input buffers */
- if (flow_context_ptr->output_tables_flag) {
- /* add table already exists - add the new tables to
- the end of the previous */
- num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
-
- info_entry_ptr = (struct sep_lli_entry_t *)
- (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
-
- /* connect to list of tables */
- *info_entry_ptr = first_table_data;
-
- /* set the first table data */
- first_table_data = flow_context_ptr->first_output_table;
- } else {
- /* set the input flag */
- flow_context_ptr->output_tables_flag = 1;
-
- /* set the first table data */
- flow_context_ptr->first_output_table = first_table_data;
- }
- /* set the last table data */
- flow_context_ptr->last_output_table = last_table_data;
- }
-
- /* set output params */
- command_args.first_table_addr = first_table_data.physical_address;
- command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
- command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
-
- /* send the parameters to user application */
- error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t));
- if (error)
- error = -EFAULT;
-end_function_with_error:
- /* free the allocated tables */
- sep_deallocated_flow_tables(&first_table_data);
-end_function:
- dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n");
- return error;
-}
-
-/*
- this function add the flow add message to the specific flow
-*/
-static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned long arg)
-{
- int error;
- struct sep_driver_add_message_t command_args;
- struct sep_flow_context_t *flow_context_ptr;
-
- dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n");
-
- error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t));
- if (error) {
- error = -EFAULT;
- goto end_function;
- }
-
- /* check input */
- if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) {
- error = -ENOMEM;
- goto end_function;
- }
-
- /* find the flow context */
- flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
- if (flow_context_ptr == NULL)
- goto end_function;
-
- /* copy the message into context */
- flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes;
- error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes);
- if (error)
- error = -EFAULT;
-end_function:
- dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n");
- return error;
-}
-
-
-/*
- this function returns the bus and virtual addresses of the static pool
-*/
-static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg)
-{
- int error;
- struct sep_driver_static_pool_addr_t command_args;
-
- dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n");
-
- /*prepare the output parameters in the struct */
- command_args.physical_static_address = sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
- command_args.virtual_static_address = (unsigned long)sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
-
- edbg("SEP Driver:bus_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address);
-
- /* send the parameters to user application */
- error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t));
- if (error)
- error = -EFAULT;
- dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n");
- return error;
-}
-
-/*
- this address gets the offset of the physical address from the start
- of the mapped area
-*/
-static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsigned long arg)
-{
- int error;
- struct sep_driver_get_mapped_offset_t command_args;
-
- dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n");
-
- error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t));
- if (error) {
- error = -EFAULT;
- goto end_function;
- }
-
- if (command_args.physical_address < sep->shared_bus) {
- error = -EINVAL;
- goto end_function;
- }
-
- /*prepare the output parameters in the struct */
- command_args.offset = command_args.physical_address - sep->shared_bus;
-
- edbg("SEP Driver:bus_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset);
-
- /* send the parameters to user application */
- error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t));
- if (error)
- error = -EFAULT;
-end_function:
- dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n");
- return error;
-}
-
-
-/*
- ?
-*/
-static int sep_start_handler(struct sep_device *sep)
-{
- unsigned long reg_val;
- unsigned long error = 0;
-
- dbg("SEP Driver:--------> sep_start_handler start\n");
-
- /* wait in polling for message from SEP */
- do
- reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
- while (!reg_val);
-
- /* check the value */
- if (reg_val == 0x1)
- /* fatal error - read error status from GPRO */
- error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
- dbg("SEP Driver:<-------- sep_start_handler end\n");
- return error;
-}
-
-/*
- this function handles the request for SEP initialization
-*/
-static int sep_init_handler(struct sep_device *sep, unsigned long arg)
-{
- unsigned long message_word;
- unsigned long *message_ptr;
- struct sep_driver_init_t command_args;
- unsigned long counter;
- unsigned long error;
- unsigned long reg_val;
-
- dbg("SEP Driver:--------> sep_init_handler start\n");
- error = 0;
-
- error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t));
- if (error) {
- error = -EFAULT;
- goto end_function;
- }
- dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user\n");
-
- /* PATCH - configure the DMA to single -burst instead of multi-burst */
- /*sep_configure_dma_burst(); */
-
- dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n");
-
- message_ptr = (unsigned long *) command_args.message_addr;
-
- /* set the base address of the SRAM */
- sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS);
-
- for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) {
- get_user(message_word, message_ptr);
- /* write data to SRAM */
- sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word);
- edbg("SEP Driver:message_word is %lu\n", message_word);
- /* wait for write complete */
- sep_wait_sram_write(sep);
- }
- dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n");
- /* signal SEP */
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1);
-
- do
- reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
- while (!(reg_val & 0xFFFFFFFD));
-
- dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n");
-
- /* check the value */
- if (reg_val == 0x1) {
- edbg("SEP Driver:init failed\n");
-
- error = sep_read_reg(sep, 0x8060);
- edbg("SEP Driver:sw monitor is %lu\n", error);
-
- /* fatal error - read erro status from GPRO */
- error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
- edbg("SEP Driver:error is %lu\n", error);
- }
-end_function:
- dbg("SEP Driver:<-------- sep_init_handler end\n");
- return error;
-
-}
-
-/*
- this function handles the request cache and resident reallocation
-*/
-static int sep_realloc_cache_resident_handler(struct sep_device *sep,
- unsigned long arg)
-{
- struct sep_driver_realloc_cache_resident_t command_args;
- int error;
-
- /* copy cache and resident to the their intended locations */
- error = sep_load_firmware(sep);
- if (error)
- return error;
-
- command_args.new_base_addr = sep->shared_bus;
-
- /* find the new base address according to the lowest address between
- cache, resident and shared area */
- if (sep->resident_bus < command_args.new_base_addr)
- command_args.new_base_addr = sep->resident_bus;
- if (sep->rar_bus < command_args.new_base_addr)
- command_args.new_base_addr = sep->rar_bus;
-
- /* set the return parameters */
- command_args.new_cache_addr = sep->rar_bus;
- command_args.new_resident_addr = sep->resident_bus;
-
- /* set the new shared area */
- command_args.new_shared_area_addr = sep->shared_bus;
-
- edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr);
- edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr);
- edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr);
- edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr);
-
- /* return to user */
- if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)))
- return -EFAULT;
- return 0;
-}
-
-/**
- * sep_get_time_handler - time request from user space
- * @sep: sep we are to set the time for
- * @arg: pointer to user space arg buffer
- *
- * This function reports back the time and the address in the SEP
- * shared buffer at which it has been placed. (Do we really need this!!!)
- */
-
-static int sep_get_time_handler(struct sep_device *sep, unsigned long arg)
-{
- struct sep_driver_get_time_t command_args;
-
- mutex_lock(&sep_mutex);
- command_args.time_value = sep_set_time(sep);
- command_args.time_physical_address = (unsigned long)sep_time_address(sep);
- mutex_unlock(&sep_mutex);
- if (copy_to_user((void __user *)arg,
- &command_args, sizeof(struct sep_driver_get_time_t)))
- return -EFAULT;
- return 0;
-
-}
-
-/*
- This API handles the end transaction request
-*/
-static int sep_end_transaction_handler(struct sep_device *sep, unsigned long arg)
-{
- dbg("SEP Driver:--------> sep_end_transaction_handler start\n");
-
-#if 0 /*!SEP_DRIVER_POLLING_MODE */
- /* close IMR */
- sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
-
- /* release IRQ line */
- free_irq(SEP_DIRVER_IRQ_NUM, sep);
-
- /* lock the sep mutex */
- mutex_unlock(&sep_mutex);
-#endif
-
- dbg("SEP Driver:<-------- sep_end_transaction_handler end\n");
-
- return 0;
-}
-
-
-/**
- * sep_set_flow_id_handler - handle flow setting
- * @sep: the SEP we are configuring
- * @flow_id: the flow we are setting
- *
- * This function handler the set flow id command
- */
-static int sep_set_flow_id_handler(struct sep_device *sep,
- unsigned long flow_id)
-{
- int error = 0;
- struct sep_flow_context_t *flow_data_ptr;
-
- /* find the flow data structure that was just used for creating new flow
- - its id should be default */
-
- mutex_lock(&sep_mutex);
- flow_data_ptr = sep_find_flow_context(sep, SEP_TEMP_FLOW_ID);
- if (flow_data_ptr)
- flow_data_ptr->flow_id = flow_id; /* set flow id */
- else
- error = -EINVAL;
- mutex_unlock(&sep_mutex);
- return error;
-}
-
-static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- int error = 0;
- struct sep_device *sep = filp->private_data;
-
- dbg("------------>SEP Driver: ioctl start\n");
-
- edbg("SEP Driver: cmd is %x\n", cmd);
-
- switch (cmd) {
- case SEP_IOCSENDSEPCOMMAND:
- /* send command to SEP */
- sep_send_command_handler(sep);
- edbg("SEP Driver: after sep_send_command_handler\n");
- break;
- case SEP_IOCSENDSEPRPLYCOMMAND:
- /* send reply command to SEP */
- sep_send_reply_command_handler(sep);
- break;
- case SEP_IOCALLOCDATAPOLL:
- /* allocate data pool */
- error = sep_allocate_data_pool_memory_handler(sep, arg);
- break;
- case SEP_IOCWRITEDATAPOLL:
- /* write data into memory pool */
- error = sep_write_into_data_pool_handler(sep, arg);
- break;
- case SEP_IOCREADDATAPOLL:
- /* read data from data pool into application memory */
- error = sep_read_from_data_pool_handler(sep, arg);
- break;
- case SEP_IOCCREATESYMDMATABLE:
- /* create dma table for synhronic operation */
- error = sep_create_sync_dma_tables_handler(sep, arg);
- break;
- case SEP_IOCCREATEFLOWDMATABLE:
- /* create flow dma tables */
- error = sep_create_flow_dma_tables_handler(sep, arg);
- break;
- case SEP_IOCFREEDMATABLEDATA:
- /* free the pages */
- error = sep_free_dma_table_data_handler(sep);
- break;
- case SEP_IOCSETFLOWID:
- /* set flow id */
- error = sep_set_flow_id_handler(sep, (unsigned long)arg);
- break;
- case SEP_IOCADDFLOWTABLE:
- /* add tables to the dynamic flow */
- error = sep_add_flow_tables_handler(sep, arg);
- break;
- case SEP_IOCADDFLOWMESSAGE:
- /* add message of add tables to flow */
- error = sep_add_flow_tables_message_handler(sep, arg);
- break;
- case SEP_IOCSEPSTART:
- /* start command to sep */
- error = sep_start_handler(sep);
- break;
- case SEP_IOCSEPINIT:
- /* init command to sep */
- error = sep_init_handler(sep, arg);
- break;
- case SEP_IOCGETSTATICPOOLADDR:
- /* get the physical and virtual addresses of the static pool */
- error = sep_get_static_pool_addr_handler(sep, arg);
- break;
- case SEP_IOCENDTRANSACTION:
- error = sep_end_transaction_handler(sep, arg);
- break;
- case SEP_IOCREALLOCCACHERES:
- error = sep_realloc_cache_resident_handler(sep, arg);
- break;
- case SEP_IOCGETMAPPEDADDROFFSET:
- error = sep_get_physical_mapped_offset_handler(sep, arg);
- break;
- case SEP_IOCGETIME:
- error = sep_get_time_handler(sep, arg);
- break;
- default:
- error = -ENOTTY;
- break;
- }
- dbg("SEP Driver:<-------- ioctl end\n");
- return error;
-}
-
-
-
-#if !SEP_DRIVER_POLLING_MODE
-
-/* handler for flow done interrupt */
-
-static void sep_flow_done_handler(struct work_struct *work)
-{
- struct sep_flow_context_t *flow_data_ptr;
-
- /* obtain the mutex */
- mutex_lock(&sep_mutex);
-
- /* get the pointer to context */
- flow_data_ptr = (struct sep_flow_context_t *) work;
-
- /* free all the current input tables in sep */
- sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process);
-
- /* free all the current tables output tables in SEP (if needed) */
- if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff)
- sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process);
-
- /* check if we have additional tables to be sent to SEP only input
- flag may be checked */
- if (flow_data_ptr->input_tables_flag) {
- /* copy the message to the shared RAM and signal SEP */
- memcpy((void *) flow_data_ptr->message, (void *) sep->shared_addr, flow_data_ptr->message_size_in_bytes);
-
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2);
- }
- mutex_unlock(&sep_mutex);
-}
-/*
- interrupt handler function
-*/
-static irqreturn_t sep_inthandler(int irq, void *dev_id)
-{
- irqreturn_t int_error;
- unsigned long reg_val;
- unsigned long flow_id;
- struct sep_flow_context_t *flow_context_ptr;
- struct sep_device *sep = dev_id;
-
- int_error = IRQ_HANDLED;
-
- /* read the IRR register to check if this is SEP interrupt */
- reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
- edbg("SEP Interrupt - reg is %08lx\n", reg_val);
-
- /* check if this is the flow interrupt */
- if (0 /*reg_val & (0x1 << 11) */ ) {
- /* read GPRO to find out the which flow is done */
- flow_id = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
-
- /* find the contex of the flow */
- flow_context_ptr = sep_find_flow_context(sep, flow_id >> 28);
- if (flow_context_ptr == NULL)
- goto end_function_with_error;
-
- /* queue the work */
- INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler);
- queue_work(sep->flow_wq, &flow_context_ptr->flow_wq);
-
- } else {
- /* check if this is reply interrupt from SEP */
- if (reg_val & (0x1 << 13)) {
- /* update the counter of reply messages */
- sep->reply_ct++;
- /* wake up the waiting process */
- wake_up(&sep_event);
- } else {
- int_error = IRQ_NONE;
- goto end_function;
- }
- }
-end_function_with_error:
- /* clear the interrupt */
- sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);
-end_function:
- return int_error;
-}
-
-#endif
-
-
-
-#if 0
-
-static void sep_wait_busy(struct sep_device *sep)
-{
- u32 reg;
-
- do {
- reg = sep_read_reg(sep, HW_HOST_SEP_BUSY_REG_ADDR);
- } while (reg);
-}
-
-/*
- PATCH for configuring the DMA to single burst instead of multi-burst
-*/
-static void sep_configure_dma_burst(struct sep_device *sep)
-{
-#define HW_AHB_RD_WR_BURSTS_REG_ADDR 0x0E10UL
-
- dbg("SEP Driver:<-------- sep_configure_dma_burst start \n");
-
- /* request access to registers from SEP */
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
-
- dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg) \n");
-
- sep_wait_busy(sep);
-
- dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop) \n");
-
- /* set the DMA burst register to single burst */
- sep_write_reg(sep, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL);
-
- /* release the sep busy */
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL);
- sep_wait_busy(sep);
-
- dbg("SEP Driver:<-------- sep_configure_dma_burst done \n");
-
-}
-
-#endif
-
-/*
- Function that is activated on the successful probe of the SEP device
-*/
-static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- int error = 0;
- struct sep_device *sep;
- int counter;
- int size; /* size of memory for allocation */
-
- edbg("Sep pci probe starting\n");
- if (sep_dev != NULL) {
- dev_warn(&pdev->dev, "only one SEP supported.\n");
- return -EBUSY;
- }
-
- /* enable the device */
- error = pci_enable_device(pdev);
- if (error) {
- edbg("error enabling pci device\n");
- goto end_function;
- }
-
- /* set the pci dev pointer */
- sep_dev = &sep_instance;
- sep = &sep_instance;
-
- edbg("sep->shared_addr = %p\n", sep->shared_addr);
- /* transaction counter that coordinates the transactions between SEP
- and HOST */
- sep->send_ct = 0;
- /* counter for the messages from sep */
- sep->reply_ct = 0;
- /* counter for the number of bytes allocated in the pool
- for the current transaction */
- sep->data_pool_bytes_allocated = 0;
-
- /* calculate the total size for allocation */
- size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
- SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
-
- /* allocate the shared area */
- if (sep_map_and_alloc_shared_area(sep, size)) {
- error = -ENOMEM;
- /* allocation failed */
- goto end_function_error;
- }
- /* now set the memory regions */
-#if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1)
- /* Note: this test section will need moving before it could ever
- work as the registers are not yet mapped ! */
- /* send the new SHARED MESSAGE AREA to the SEP */
- sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
-
- /* poll for SEP response */
- retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
- while (retval != 0xffffffff && retval != sep->shared_bus)
- retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
-
- /* check the return value (register) */
- if (retval != sep->shared_bus) {
- error = -ENOMEM;
- goto end_function_deallocate_sep_shared_area;
- }
-#endif
- /* init the flow contextes */
- for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++)
- sep->flows[counter].flow_id = SEP_FREE_FLOW_ID;
-
- sep->flow_wq = create_singlethread_workqueue("sepflowwq");
- if (sep->flow_wq == NULL) {
- error = -ENOMEM;
- edbg("sep_driver:flow queue creation failed\n");
- goto end_function_deallocate_sep_shared_area;
- }
- edbg("SEP Driver: create flow workqueue \n");
- sep->pdev = pci_dev_get(pdev);
-
- sep->reg_addr = pci_ioremap_bar(pdev, 0);
- if (!sep->reg_addr) {
- edbg("sep: ioremap of registers failed.\n");
- goto end_function_deallocate_sep_shared_area;
- }
- edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr);
-
- /* load the rom code */
- sep_load_rom_code(sep);
-
- /* set up system base address and shared memory location */
- sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev,
- 2 * SEP_RAR_IO_MEM_REGION_SIZE,
- &sep->rar_bus, GFP_KERNEL);
-
- if (!sep->rar_addr) {
- edbg("SEP Driver:can't allocate rar\n");
- goto end_function_uniomap;
- }
-
-
- edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
- edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
-
-#if !SEP_DRIVER_POLLING_MODE
-
- edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
-
- /* clear ICR register */
- sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
-
- /* set the IMR register - open only GPR 2 */
- sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
-
- edbg("SEP Driver: about to call request_irq\n");
- /* get the interrupt line */
- error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep);
- if (error)
- goto end_function_free_res;
- return 0;
- edbg("SEP Driver: about to write IMR REG_ADDR");
-
- /* set the IMR register - open only GPR 2 */
- sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
-
-end_function_free_res:
- dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE,
- sep->rar_addr, sep->rar_bus);
-#endif /* SEP_DRIVER_POLLING_MODE */
-end_function_uniomap:
- iounmap(sep->reg_addr);
-end_function_deallocate_sep_shared_area:
- /* de-allocate shared area */
- sep_unmap_and_free_shared_area(sep, size);
-end_function_error:
- sep_dev = NULL;
-end_function:
- return error;
-}
-
-static const struct pci_device_id sep_pci_id_tbl[] = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
-
-/* field for registering driver to PCI device */
-static struct pci_driver sep_pci_driver = {
- .name = "sep_sec_driver",
- .id_table = sep_pci_id_tbl,
- .probe = sep_probe
- /* FIXME: remove handler */
-};
-
-/* major and minor device numbers */
-static dev_t sep_devno;
-
-/* the files operations structure of the driver */
-static struct file_operations sep_file_operations = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = sep_ioctl,
- .poll = sep_poll,
- .open = sep_open,
- .release = sep_release,
- .mmap = sep_mmap,
-};
-
-
-/* cdev struct of the driver */
-static struct cdev sep_cdev;
-
-/*
- this function registers the driver to the file system
-*/
-static int sep_register_driver_to_fs(void)
-{
- int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver");
- if (ret_val) {
- edbg("sep: major number allocation failed, retval is %d\n",
- ret_val);
- return ret_val;
- }
- /* init cdev */
- cdev_init(&sep_cdev, &sep_file_operations);
- sep_cdev.owner = THIS_MODULE;
-
- /* register the driver with the kernel */
- ret_val = cdev_add(&sep_cdev, sep_devno, 1);
- if (ret_val) {
- edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val);
- /* unregister dev numbers */
- unregister_chrdev_region(sep_devno, 1);
- }
- return ret_val;
-}
-
-
-/*--------------------------------------------------------------
- init function
-----------------------------------------------------------------*/
-static int __init sep_init(void)
-{
- int ret_val = 0;
- dbg("SEP Driver:-------->Init start\n");
- /* FIXME: Probe can occur before we are ready to survive a probe */
- ret_val = pci_register_driver(&sep_pci_driver);
- if (ret_val) {
- edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val);
- goto end_function_unregister_from_fs;
- }
- /* register driver to fs */
- ret_val = sep_register_driver_to_fs();
- if (ret_val)
- goto end_function_unregister_pci;
- goto end_function;
-end_function_unregister_pci:
- pci_unregister_driver(&sep_pci_driver);
-end_function_unregister_from_fs:
- /* unregister from fs */
- cdev_del(&sep_cdev);
- /* unregister dev numbers */
- unregister_chrdev_region(sep_devno, 1);
-end_function:
- dbg("SEP Driver:<-------- Init end\n");
- return ret_val;
-}
-
-
-/*-------------------------------------------------------------
- exit function
---------------------------------------------------------------*/
-static void __exit sep_exit(void)
-{
- int size;
-
- dbg("SEP Driver:--------> Exit start\n");
-
- /* unregister from fs */
- cdev_del(&sep_cdev);
- /* unregister dev numbers */
- unregister_chrdev_region(sep_devno, 1);
- /* calculate the total size for de-allocation */
- size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
- SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
- /* FIXME: We need to do this in the unload for the device */
- /* free shared area */
- if (sep_dev) {
- sep_unmap_and_free_shared_area(sep_dev, size);
- edbg("SEP Driver: free pages SEP SHARED AREA \n");
- iounmap((void *) sep_dev->reg_addr);
- edbg("SEP Driver: iounmap \n");
- }
- edbg("SEP Driver: release_mem_region \n");
- dbg("SEP Driver:<-------- Exit end\n");
-}
-
-
-module_init(sep_init);
-module_exit(sep_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h
deleted file mode 100644
index 7ef16da..0000000
--- a/drivers/staging/sep/sep_driver_api.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- *
- * sep_driver_api.h - Security Processor Driver api definitions
- *
- * Copyright(c) 2009 Intel Corporation. All rights reserved.
- * Copyright(c) 2009 Discretix. 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.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- *
- * CHANGES:
- *
- * 2009.06.26 Initial publish
- *
- */
-
-#ifndef __SEP_DRIVER_API_H__
-#define __SEP_DRIVER_API_H__
-
-
-
-/*----------------------------------------------------------------
- IOCTL command defines
- -----------------------------------------------------------------*/
-
-/* magic number 1 of the sep IOCTL command */
-#define SEP_IOC_MAGIC_NUMBER 's'
-
-/* sends interrupt to sep that message is ready */
-#define SEP_IOCSENDSEPCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 0)
-
-/* sends interrupt to sep that message is ready */
-#define SEP_IOCSENDSEPRPLYCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 1)
-
-/* allocate memory in data pool */
-#define SEP_IOCALLOCDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 2)
-
-/* write to pre-allocated memory in data pool */
-#define SEP_IOCWRITEDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 3)
-
-/* read from pre-allocated memory in data pool */
-#define SEP_IOCREADDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 4)
-
-/* create sym dma lli tables */
-#define SEP_IOCCREATESYMDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 5)
-
-/* create flow dma lli tables */
-#define SEP_IOCCREATEFLOWDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 6)
-
-/* free dynamic data aalocated during table creation */
-#define SEP_IOCFREEDMATABLEDATA _IO(SEP_IOC_MAGIC_NUMBER , 7)
-
-/* get the static pool area addresses (physical and virtual) */
-#define SEP_IOCGETSTATICPOOLADDR _IO(SEP_IOC_MAGIC_NUMBER , 8)
-
-/* set flow id command */
-#define SEP_IOCSETFLOWID _IO(SEP_IOC_MAGIC_NUMBER , 9)
-
-/* add tables to the dynamic flow */
-#define SEP_IOCADDFLOWTABLE _IO(SEP_IOC_MAGIC_NUMBER , 10)
-
-/* add flow add tables message */
-#define SEP_IOCADDFLOWMESSAGE _IO(SEP_IOC_MAGIC_NUMBER , 11)
-
-/* start sep command */
-#define SEP_IOCSEPSTART _IO(SEP_IOC_MAGIC_NUMBER , 12)
-
-/* init sep command */
-#define SEP_IOCSEPINIT _IO(SEP_IOC_MAGIC_NUMBER , 13)
-
-/* end transaction command */
-#define SEP_IOCENDTRANSACTION _IO(SEP_IOC_MAGIC_NUMBER , 15)
-
-/* reallocate cache and resident */
-#define SEP_IOCREALLOCCACHERES _IO(SEP_IOC_MAGIC_NUMBER , 16)
-
-/* get the offset of the address starting from the beginnnig of the map area */
-#define SEP_IOCGETMAPPEDADDROFFSET _IO(SEP_IOC_MAGIC_NUMBER , 17)
-
-/* get time address and value */
-#define SEP_IOCGETIME _IO(SEP_IOC_MAGIC_NUMBER , 19)
-
-/*-------------------------------------------
- TYPEDEFS
-----------------------------------------------*/
-
-/*
- init command struct
-*/
-struct sep_driver_init_t {
- /* start of the 1G of the host memory address that SEP can access */
- unsigned long message_addr;
-
- /* start address of resident */
- unsigned long message_size_in_words;
-
-};
-
-
-/*
- realloc cache resident command
-*/
-struct sep_driver_realloc_cache_resident_t {
- /* new cache address */
- u64 new_cache_addr;
- /* new resident address */
- u64 new_resident_addr;
- /* new resident address */
- u64 new_shared_area_addr;
- /* new base address */
- u64 new_base_addr;
-};
-
-struct sep_driver_alloc_t {
- /* virtual address of allocated space */
- unsigned long offset;
-
- /* physical address of allocated space */
- unsigned long phys_address;
-
- /* number of bytes to allocate */
- unsigned long num_bytes;
-};
-
-/*
- */
-struct sep_driver_write_t {
- /* application space address */
- unsigned long app_address;
-
- /* address of the data pool */
- unsigned long datapool_address;
-
- /* number of bytes to write */
- unsigned long num_bytes;
-};
-
-/*
- */
-struct sep_driver_read_t {
- /* application space address */
- unsigned long app_address;
-
- /* address of the data pool */
- unsigned long datapool_address;
-
- /* number of bytes to read */
- unsigned long num_bytes;
-};
-
-/*
-*/
-struct sep_driver_build_sync_table_t {
- /* address value of the data in */
- unsigned long app_in_address;
-
- /* size of data in */
- unsigned long data_in_size;
-
- /* address of the data out */
- unsigned long app_out_address;
-
- /* the size of the block of the operation - if needed,
- every table will be modulo this parameter */
- unsigned long block_size;
-
- /* the physical address of the first input DMA table */
- unsigned long in_table_address;
-
- /* number of entries in the first input DMA table */
- unsigned long in_table_num_entries;
-
- /* the physical address of the first output DMA table */
- unsigned long out_table_address;
-
- /* number of entries in the first output DMA table */
- unsigned long out_table_num_entries;
-
- /* data in the first input table */
- unsigned long table_data_size;
-
- /* distinct user/kernel layout */
- bool isKernelVirtualAddress;
-
-};
-
-/*
-*/
-struct sep_driver_build_flow_table_t {
- /* flow type */
- unsigned long flow_type;
-
- /* flag for input output */
- unsigned long input_output_flag;
-
- /* address value of the data in */
- unsigned long virt_buff_data_addr;
-
- /* size of data in */
- unsigned long num_virtual_buffers;
-
- /* the physical address of the first input DMA table */
- unsigned long first_table_addr;
-
- /* number of entries in the first input DMA table */
- unsigned long first_table_num_entries;
-
- /* data in the first input table */
- unsigned long first_table_data_size;
-
- /* distinct user/kernel layout */
- bool isKernelVirtualAddress;
-};
-
-
-struct sep_driver_add_flow_table_t {
- /* flow id */
- unsigned long flow_id;
-
- /* flag for input output */
- unsigned long inputOutputFlag;
-
- /* address value of the data in */
- unsigned long virt_buff_data_addr;
-
- /* size of data in */
- unsigned long num_virtual_buffers;
-
- /* address of the first table */
- unsigned long first_table_addr;
-
- /* number of entries in the first table */
- unsigned long first_table_num_entries;
-
- /* data size of the first table */
- unsigned long first_table_data_size;
-
- /* distinct user/kernel layout */
- bool isKernelVirtualAddress;
-
-};
-
-/*
- command struct for set flow id
-*/
-struct sep_driver_set_flow_id_t {
- /* flow id to set */
- unsigned long flow_id;
-};
-
-
-/* command struct for add tables message */
-struct sep_driver_add_message_t {
- /* flow id to set */
- unsigned long flow_id;
-
- /* message size in bytes */
- unsigned long message_size_in_bytes;
-
- /* address of the message */
- unsigned long message_address;
-};
-
-/* command struct for static pool addresses */
-struct sep_driver_static_pool_addr_t {
- /* physical address of the static pool */
- unsigned long physical_static_address;
-
- /* virtual address of the static pool */
- unsigned long virtual_static_address;
-};
-
-/* command struct for getiing offset of the physical address from
- the start of the mapped area */
-struct sep_driver_get_mapped_offset_t {
- /* physical address of the static pool */
- unsigned long physical_address;
-
- /* virtual address of the static pool */
- unsigned long offset;
-};
-
-/* command struct for getting time value and address */
-struct sep_driver_get_time_t {
- /* physical address of stored time */
- unsigned long time_physical_address;
-
- /* value of the stored time */
- unsigned long time_value;
-};
-
-
-/*
- structure that represent one entry in the DMA LLI table
-*/
-struct sep_lli_entry_t {
- /* physical address */
- unsigned long physical_address;
-
- /* block size */
- unsigned long block_size;
-};
-
-/*
- structure that reperesents data needed for lli table construction
-*/
-struct sep_lli_prepare_table_data_t {
- /* pointer to the memory where the first lli entry to be built */
- struct sep_lli_entry_t *lli_entry_ptr;
-
- /* pointer to the array of lli entries from which the table is to be built */
- struct sep_lli_entry_t *lli_array_ptr;
-
- /* number of elements in lli array */
- int lli_array_size;
-
- /* number of entries in the created table */
- int num_table_entries;
-
- /* number of array entries processed during table creation */
- int num_array_entries_processed;
-
- /* the totatl data size in the created table */
- int lli_table_total_data_size;
-};
-
-/*
- structure that represent tone table - it is not used in code, jkust
- to show what table looks like
-*/
-struct sep_lli_table_t {
- /* number of pages mapped in this tables. If 0 - means that the table
- is not defined (used as a valid flag) */
- unsigned long num_pages;
- /*
- pointer to array of page pointers that represent the mapping of the
- virtual buffer defined by the table to the physical memory. If this
- pointer is NULL, it means that the table is not defined
- (used as a valid flag)
- */
- struct page **table_page_array_ptr;
-
- /* maximum flow entries in table */
- struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE];
-};
-
-
-/*
- structure for keeping the mapping of the virtual buffer into physical pages
-*/
-struct sep_flow_buffer_data {
- /* pointer to the array of page structs pointers to the pages of the
- virtual buffer */
- struct page **page_array_ptr;
-
- /* number of pages taken by the virtual buffer */
- unsigned long num_pages;
-
- /* this flag signals if this page_array is the last one among many that were
- sent in one setting to SEP */
- unsigned long last_page_array_flag;
-};
-
-/*
- struct that keeps all the data for one flow
-*/
-struct sep_flow_context_t {
- /*
- work struct for handling the flow done interrupt in the workqueue
- this structure must be in the first place, since it will be used
- forcasting to the containing flow context
- */
- struct work_struct flow_wq;
-
- /* flow id */
- unsigned long flow_id;
-
- /* additional input tables exists */
- unsigned long input_tables_flag;
-
- /* additional output tables exists */
- unsigned long output_tables_flag;
-
- /* data of the first input file */
- struct sep_lli_entry_t first_input_table;
-
- /* data of the first output table */
- struct sep_lli_entry_t first_output_table;
-
- /* last input table data */
- struct sep_lli_entry_t last_input_table;
-
- /* last output table data */
- struct sep_lli_entry_t last_output_table;
-
- /* first list of table */
- struct sep_lli_entry_t input_tables_in_process;
-
- /* output table in process (in sep) */
- struct sep_lli_entry_t output_tables_in_process;
-
- /* size of messages in bytes */
- unsigned long message_size_in_bytes;
-
- /* message */
- unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES];
-};
-
-
-#endif
diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h
deleted file mode 100644
index 6008fe5..0000000
--- a/drivers/staging/sep/sep_driver_config.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- *
- * sep_driver_config.h - Security Processor Driver configuration
- *
- * Copyright(c) 2009 Intel Corporation. All rights reserved.
- * Copyright(c) 2009 Discretix. 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.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- *
- * CHANGES:
- *
- * 2009.06.26 Initial publish
- *
- */
-
-#ifndef __SEP_DRIVER_CONFIG_H__
-#define __SEP_DRIVER_CONFIG_H__
-
-
-/*--------------------------------------
- DRIVER CONFIGURATION FLAGS
- -------------------------------------*/
-
-/* if flag is on , then the driver is running in polling and
- not interrupt mode */
-#define SEP_DRIVER_POLLING_MODE 1
-
-/* flag which defines if the shared area address should be
- reconfiged (send to SEP anew) during init of the driver */
-#define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0
-
-/* the mode for running on the ARM1172 Evaluation platform (flag is 1) */
-#define SEP_DRIVER_ARM_DEBUG_MODE 0
-
-/*-------------------------------------------
- INTERNAL DATA CONFIGURATION
- -------------------------------------------*/
-
-/* flag for the input array */
-#define SEP_DRIVER_IN_FLAG 0
-
-/* flag for output array */
-#define SEP_DRIVER_OUT_FLAG 1
-
-/* maximum number of entries in one LLI tables */
-#define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 8
-
-
-/*--------------------------------------------------------
- SHARED AREA memory total size is 36K
- it is divided is following:
-
- SHARED_MESSAGE_AREA 8K }
- }
- STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K)
- }
- DATA_POOL_AREA 12K }
-
- SYNCHRONIC_DMA_TABLES_AREA 5K
-
- FLOW_DMA_TABLES_AREA 4K
-
- SYSTEM_MEMORY_AREA 3k
-
- SYSTEM_MEMORY total size is 3k
- it is divided as following:
-
- TIME_MEMORY_AREA 8B
------------------------------------------------------------*/
-
-
-
-/*
- the maximum length of the message - the rest of the message shared
- area will be dedicated to the dma lli tables
-*/
-#define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024)
-
-/* the size of the message shared area in pages */
-#define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024)
-
-/* the size of the data pool static area in pages */
-#define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024)
-
-/* the size of the data pool shared area size in pages */
-#define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (12 * 1024)
-
-/* the size of the message shared area in pages */
-#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 5)
-
-
-/* the size of the data pool shared area size in pages */
-#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4)
-
-/* system data (time, caller id etc') pool */
-#define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES 100
-
-
-/* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and
- DATA POOL areas. area must be module 4k */
-#define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 24)
-
-
-/*-----------------------------------------------
- offsets of the areas starting from the shared area start address
-*/
-
-/* message area offset */
-#define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0
-
-/* static pool area offset */
-#define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \
- (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES)
-
-/* data pool area offset */
-#define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \
- (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \
- SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES)
-
-/* synhronic dma tables area offset */
-#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \
- (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \
- SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)
-
-/* sep driver flow dma tables area offset */
-#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \
- (SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
- SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES)
-
-/* system memory offset in bytes */
-#define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \
- (SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
- SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES)
-
-/* offset of the time area */
-#define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \
- (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES)
-
-
-
-/* start physical address of the SEP registers memory in HOST */
-#define SEP_IO_MEM_REGION_START_ADDRESS 0x80000000
-
-/* size of the SEP registers memory region in HOST (for now 100 registers) */
-#define SEP_IO_MEM_REGION_SIZE (2 * 0x100000)
-
-/* define the number of IRQ for SEP interrupts */
-#define SEP_DIRVER_IRQ_NUM 1
-
-/* maximum number of add buffers */
-#define SEP_MAX_NUM_ADD_BUFFERS 100
-
-/* number of flows */
-#define SEP_DRIVER_NUM_FLOWS 4
-
-/* maximum number of entries in flow table */
-#define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE 25
-
-/* offset of the num entries in the block length entry of the LLI */
-#define SEP_NUM_ENTRIES_OFFSET_IN_BITS 24
-
-/* offset of the interrupt flag in the block length entry of the LLI */
-#define SEP_INT_FLAG_OFFSET_IN_BITS 31
-
-/* mask for extracting data size from LLI */
-#define SEP_TABLE_DATA_SIZE_MASK 0xFFFFFF
-
-/* mask for entries after being shifted left */
-#define SEP_NUM_ENTRIES_MASK 0x7F
-
-/* default flow id */
-#define SEP_FREE_FLOW_ID 0xFFFFFFFF
-
-/* temp flow id used during cretiong of new flow until receiving
- real flow id from sep */
-#define SEP_TEMP_FLOW_ID (SEP_DRIVER_NUM_FLOWS + 1)
-
-/* maximum add buffers message length in bytes */
-#define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES (7 * 4)
-
-/* maximum number of concurrent virtual buffers */
-#define SEP_MAX_VIRT_BUFFERS_CONCURRENT 100
-
-/* the token that defines the start of time address */
-#define SEP_TIME_VAL_TOKEN 0x12345678
-
-/* DEBUG LEVEL MASKS */
-#define SEP_DEBUG_LEVEL_BASIC 0x1
-
-#define SEP_DEBUG_LEVEL_EXTENDED 0x4
-
-
-/* Debug helpers */
-
-#define dbg(fmt, args...) \
-do {\
- if (debug & SEP_DEBUG_LEVEL_BASIC) \
- printk(KERN_DEBUG fmt, ##args); \
-} while(0);
-
-#define edbg(fmt, args...) \
-do { \
- if (debug & SEP_DEBUG_LEVEL_EXTENDED) \
- printk(KERN_DEBUG fmt, ##args); \
-} while(0);
-
-
-
-#endif
diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h
deleted file mode 100644
index ea6abd8..0000000
--- a/drivers/staging/sep/sep_driver_hw_defs.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- *
- * sep_driver_hw_defs.h - Security Processor Driver hardware definitions
- *
- * Copyright(c) 2009 Intel Corporation. All rights reserved.
- * Copyright(c) 2009 Discretix. 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.
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * CONTACTS:
- *
- * Mark Allyn mark.a.allyn@intel.com
- *
- * CHANGES:
- *
- * 2009.06.26 Initial publish
- *
- */
-
-#ifndef SEP_DRIVER_HW_DEFS__H
-#define SEP_DRIVER_HW_DEFS__H
-
-/*--------------------------------------------------------------------------*/
-/* Abstract: HW Registers Defines. */
-/* */
-/* Note: This file was automatically created !!! */
-/* DO NOT EDIT THIS FILE !!! */
-/*--------------------------------------------------------------------------*/
-
-
-/* cf registers */
-#define HW_R0B_ADDR_0_REG_ADDR 0x0000UL
-#define HW_R0B_ADDR_1_REG_ADDR 0x0004UL
-#define HW_R0B_ADDR_2_REG_ADDR 0x0008UL
-#define HW_R0B_ADDR_3_REG_ADDR 0x000cUL
-#define HW_R0B_ADDR_4_REG_ADDR 0x0010UL
-#define HW_R0B_ADDR_5_REG_ADDR 0x0014UL
-#define HW_R0B_ADDR_6_REG_ADDR 0x0018UL
-#define HW_R0B_ADDR_7_REG_ADDR 0x001cUL
-#define HW_R0B_ADDR_8_REG_ADDR 0x0020UL
-#define HW_R2B_ADDR_0_REG_ADDR 0x0080UL
-#define HW_R2B_ADDR_1_REG_ADDR 0x0084UL
-#define HW_R2B_ADDR_2_REG_ADDR 0x0088UL
-#define HW_R2B_ADDR_3_REG_ADDR 0x008cUL
-#define HW_R2B_ADDR_4_REG_ADDR 0x0090UL
-#define HW_R2B_ADDR_5_REG_ADDR 0x0094UL
-#define HW_R2B_ADDR_6_REG_ADDR 0x0098UL
-#define HW_R2B_ADDR_7_REG_ADDR 0x009cUL
-#define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL
-#define HW_R3B_REG_ADDR 0x00C0UL
-#define HW_R4B_REG_ADDR 0x0100UL
-#define HW_CSA_ADDR_0_REG_ADDR 0x0140UL
-#define HW_CSA_ADDR_1_REG_ADDR 0x0144UL
-#define HW_CSA_ADDR_2_REG_ADDR 0x0148UL
-#define HW_CSA_ADDR_3_REG_ADDR 0x014cUL
-#define HW_CSA_ADDR_4_REG_ADDR 0x0150UL
-#define HW_CSA_ADDR_5_REG_ADDR 0x0154UL
-#define HW_CSA_ADDR_6_REG_ADDR 0x0158UL
-#define HW_CSA_ADDR_7_REG_ADDR 0x015cUL
-#define HW_CSA_ADDR_8_REG_ADDR 0x0160UL
-#define HW_CSA_REG_ADDR 0x0140UL
-#define HW_SINB_REG_ADDR 0x0180UL
-#define HW_SOUTB_REG_ADDR 0x0184UL
-#define HW_PKI_CONTROL_REG_ADDR 0x01C0UL
-#define HW_PKI_STATUS_REG_ADDR 0x01C4UL
-#define HW_PKI_BUSY_REG_ADDR 0x01C8UL
-#define HW_PKI_A_1025_REG_ADDR 0x01CCUL
-#define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL
-#define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL
-#define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL
-#define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL
-#define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL
-#define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL
-#define HW_PKI_CLR_REG_ADDR 0x01E8UL
-#define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL
-#define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL
-#define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL
-#define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL
-#define HW_DES_KEY_0_REG_ADDR 0x0208UL
-#define HW_DES_KEY_1_REG_ADDR 0x020CUL
-#define HW_DES_KEY_2_REG_ADDR 0x0210UL
-#define HW_DES_KEY_3_REG_ADDR 0x0214UL
-#define HW_DES_KEY_4_REG_ADDR 0x0218UL
-#define HW_DES_KEY_5_REG_ADDR 0x021CUL
-#define HW_DES_CONTROL_0_REG_ADDR 0x0220UL
-#define HW_DES_CONTROL_1_REG_ADDR 0x0224UL
-#define HW_DES_IV_0_REG_ADDR 0x0228UL
-#define HW_DES_IV_1_REG_ADDR 0x022CUL
-#define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL
-#define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL
-#define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL
-#define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL
-#define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL
-#define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL
-#define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL
-#define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL
-#define HW_AES_KEY_0_REG_ADDR 0x0400UL
-#define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL
-#define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL
-#define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL
-#define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL
-#define HW_AES_IV_0_REG_ADDR 0x0440UL
-#define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL
-#define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL
-#define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL
-#define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL
-#define HW_AES_CTR1_REG_ADDR 0x0460UL
-#define HW_AES_SK_REG_ADDR 0x0478UL
-#define HW_AES_MAC_OK_REG_ADDR 0x0480UL
-#define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL
-#define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL
-#define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL
-#define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL
-#define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL
-#define HW_AES_CONTROL_REG_ADDR 0x04C0UL
-#define HW_HASH_H0_REG_ADDR 0x0640UL
-#define HW_HASH_H1_REG_ADDR 0x0644UL
-#define HW_HASH_H2_REG_ADDR 0x0648UL
-#define HW_HASH_H3_REG_ADDR 0x064CUL
-#define HW_HASH_H4_REG_ADDR 0x0650UL
-#define HW_HASH_H5_REG_ADDR 0x0654UL
-#define HW_HASH_H6_REG_ADDR 0x0658UL
-#define HW_HASH_H7_REG_ADDR 0x065CUL
-#define HW_HASH_H8_REG_ADDR 0x0660UL
-#define HW_HASH_H9_REG_ADDR 0x0664UL
-#define HW_HASH_H10_REG_ADDR 0x0668UL
-#define HW_HASH_H11_REG_ADDR 0x066CUL
-#define HW_HASH_H12_REG_ADDR 0x0670UL
-#define HW_HASH_H13_REG_ADDR 0x0674UL
-#define HW_HASH_H14_REG_ADDR 0x0678UL
-#define HW_HASH_H15_REG_ADDR 0x067CUL
-#define HW_HASH_CONTROL_REG_ADDR 0x07C0UL
-#define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL
-#define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL
-#define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL
-#define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL
-#define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL
-#define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL
-#define HW_HASH_PARAM_REG_ADDR 0x07DCUL
-#define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL
-#define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL
-#define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL
-#define HW_HASH_DATA_REG_ADDR 0x07ECUL
-#define HW_DRNG_CONTROL_REG_ADDR 0x0800UL
-#define HW_DRNG_VALID_REG_ADDR 0x0804UL
-#define HW_DRNG_DATA_REG_ADDR 0x0808UL
-#define HW_RND_SRC_EN_REG_ADDR 0x080CUL
-#define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL
-#define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL
-#define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL
-#define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL
-#define HW_CLK_STATUS_REG_ADDR 0x0824UL
-#define HW_CLK_ENABLE_REG_ADDR 0x0828UL
-#define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL
-#define HW_RND_SRC_CTL_REG_ADDR 0x0858UL
-#define HW_CRYPTO_CTL_REG_ADDR 0x0900UL
-#define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL
-#define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL
-#define HW_AES_BUSY_REG_ADDR 0x0914UL
-#define HW_DES_BUSY_REG_ADDR 0x0918UL
-#define HW_HASH_BUSY_REG_ADDR 0x091CUL
-#define HW_CONTENT_REG_ADDR 0x0924UL
-#define HW_VERSION_REG_ADDR 0x0928UL
-#define HW_CONTEXT_ID_REG_ADDR 0x0930UL
-#define HW_DIN_BUFFER_REG_ADDR 0x0C00UL
-#define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL
-#define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL
-#define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL
-#define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL
-#define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL
-#define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL
-#define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL
-#define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL
-#define HW_OLD_DATA_REG_ADDR 0x0C48UL
-#define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL
-#define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL
-#define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL
-#define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL
-#define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL
-#define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL
-#define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL
-#define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL
-#define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL
-#define HW_READ_ALIGN_REG_ADDR 0x0D3CUL
-#define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL
-#define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL
-#define HW_AHB_SINGLE_REG_ADDR 0x0E00UL
-#define HW_SRAM_DATA_REG_ADDR 0x0F00UL
-#define HW_SRAM_ADDR_REG_ADDR 0x0F04UL
-#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL
-#define HW_HOST_IRR_REG_ADDR 0x0A00UL
-#define HW_HOST_IMR_REG_ADDR 0x0A04UL
-#define HW_HOST_ICR_REG_ADDR 0x0A08UL
-#define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL
-#define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL
-#define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL
-#define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL
-#define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL
-#define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL
-#define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL
-#define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL
-#define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL
-#define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL
-#define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL
-#define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL
-#define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL
-#define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL
-#define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL
-#define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL
-#define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL
-#define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL
-#define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL
-#define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL
-#define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL
-#define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL
-#define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL
-#define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL
-#define HW_CC_SRAM_BASE_ADDRESS 0x5800UL
-
-#endif /* ifndef HW_DEFS */
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c
index d0c5c97..44a7fbe 100644
--- a/drivers/staging/spectra/ffsport.c
+++ b/drivers/staging/spectra/ffsport.c
@@ -27,6 +27,7 @@
#include <linux/kthread.h>
#include <linux/log2.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
/**** Helper functions used for Div, Remainder operation on u64 ****/
@@ -113,7 +114,6 @@
#define GLOB_SBD_NAME "nd"
#define GLOB_SBD_IRQ_NUM (29)
-#define GLOB_VERSION "driver version 20091110"
#define GLOB_SBD_IOCTL_GC (0x7701)
#define GLOB_SBD_IOCTL_WL (0x7702)
@@ -272,13 +272,6 @@
return res_blks;
}
-static void SBD_prepare_flush(struct request_queue *q, struct request *rq)
-{
- rq->cmd_type = REQ_TYPE_LINUX_BLOCK;
- /* rq->timeout = 5 * HZ; */
- rq->cmd[0] = REQ_LB_OP_FLUSH;
-}
-
/* Transfer a full request. */
static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
{
@@ -296,8 +289,7 @@
IdentifyDeviceData.PagesPerBlock *
res_blks_os;
- if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
- req->cmd[0] == REQ_LB_OP_FLUSH) {
+ if (req->cmd_type & REQ_FLUSH) {
if (force_flush_cache()) /* Fail to flush cache */
return -EIO;
else
@@ -597,11 +589,23 @@
return -ENOTTY;
}
+int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret;
+
+ lock_kernel();
+ ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg);
+ unlock_kernel();
+
+ return ret;
+}
+
static struct block_device_operations GLOB_SBD_ops = {
.owner = THIS_MODULE,
.open = GLOB_SBD_open,
.release = GLOB_SBD_release,
- .locked_ioctl = GLOB_SBD_ioctl,
+ .ioctl = GLOB_SBD_unlocked_ioctl,
.getgeo = GLOB_SBD_getgeo,
};
@@ -650,8 +654,7 @@
/* Here we force report 512 byte hardware sector size to Kernel */
blk_queue_logical_block_size(dev->queue, 512);
- blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH,
- SBD_prepare_flush);
+ blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH);
dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
if (IS_ERR(dev->thread)) {
diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c
index 134aa51..9b5218b 100644
--- a/drivers/staging/spectra/flash.c
+++ b/drivers/staging/spectra/flash.c
@@ -61,7 +61,6 @@
static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr,
u8 cache_blk, u16 flag);
static int FTL_Cache_Write(void);
-static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr);
static void FTL_Calculate_LRU(void);
static u32 FTL_Get_Block_Index(u32 wBlockNum);
@@ -86,8 +85,6 @@
static int FTL_Replace_Block(u64 blk_addr);
static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX);
-static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, u64 blk_addr);
-
struct device_info_tag DeviceInfo;
struct flash_cache_tag Cache;
static struct spectra_l2_cache_info cache_l2;
@@ -775,7 +772,7 @@
{
struct list_head *p;
struct spectra_l2_cache_list *pnd;
- int n, i;
+ int n;
n = 0;
list_for_each(p, &cache_l2.table.list) {
@@ -1538,79 +1535,6 @@
}
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function: FTL_Cache_Update_Block
-* Inputs: pointer to buffer,page address,block address
-* Outputs: PASS=0 / FAIL=1
-* Description: It updates the cache
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Cache_Update_Block(u8 *pData,
- u64 old_page_addr, u64 blk_addr)
-{
- int i, j;
- u8 *buf = pData;
- int wResult = PASS;
- int wFoundInCache;
- u64 page_addr;
- u64 addr;
- u64 old_blk_addr;
- u16 page_offset;
-
- nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
- __FILE__, __LINE__, __func__);
-
- old_blk_addr = (u64)(old_page_addr >>
- DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize;
- page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >>
- DeviceInfo.nBitsInPageDataSize);
-
- for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) {
- page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize;
- if (i != page_offset) {
- wFoundInCache = FAIL;
- for (j = 0; j < CACHE_ITEM_NUM; j++) {
- addr = Cache.array[j].address;
- addr = FTL_Get_Physical_Block_Addr(addr) +
- GLOB_u64_Remainder(addr, 2);
- if ((addr >= page_addr) && addr <
- (page_addr + Cache.cache_item_size)) {
- wFoundInCache = PASS;
- buf = Cache.array[j].buf;
- Cache.array[j].changed = SET;
-#if CMD_DMA
-#if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE
- int_cache[ftl_cmd_cnt].item = j;
- int_cache[ftl_cmd_cnt].cache.address =
- Cache.array[j].address;
- int_cache[ftl_cmd_cnt].cache.changed =
- Cache.array[j].changed;
-#endif
-#endif
- break;
- }
- }
- if (FAIL == wFoundInCache) {
- if (ERR == FTL_Cache_Read_All(g_pTempBuf,
- page_addr)) {
- wResult = FAIL;
- break;
- }
- buf = g_pTempBuf;
- }
- } else {
- buf = pData;
- }
-
- if (FAIL == FTL_Cache_Write_All(buf,
- blk_addr + (page_addr - old_blk_addr))) {
- wResult = FAIL;
- break;
- }
- }
-
- return wResult;
-}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Copy_Block
* Inputs: source block address
* Destination block address
@@ -1698,7 +1622,7 @@
static int erase_l2_cache_blocks(void)
{
int i, ret = PASS;
- u32 pblk, lblk;
+ u32 pblk, lblk = BAD_BLOCK;
u64 addr;
u32 *pbt = (u32 *)g_pBlockTable;
@@ -2004,87 +1928,6 @@
return ret;
}
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function: FTL_Cache_Write_Back
-* Inputs: pointer to data cached in sys memory
-* address of free block in flash
-* Outputs: PASS=0 / FAIL=1
-* Description: writes all the pages of Cache Block to flash
-*
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr)
-{
- int i, j, iErase;
- u64 old_page_addr, addr, phy_addr;
- u32 *pbt = (u32 *)g_pBlockTable;
- u32 lba;
-
- nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
- __FILE__, __LINE__, __func__);
-
- old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) +
- GLOB_u64_Remainder(blk_addr, 2);
-
- iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL;
-
- pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK);
-
-#if CMD_DMA
- p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free;
- g_pBTDelta_Free += sizeof(struct BTableChangesDelta);
-
- p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt;
- p_BTableChangesDelta->BT_Index = (u32)(blk_addr >>
- DeviceInfo.nBitsInBlockDataSize);
- p_BTableChangesDelta->BT_Entry_Value =
- pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)];
- p_BTableChangesDelta->ValidFields = 0x0C;
-#endif
-
- if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
- g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
- FTL_Write_IN_Progress_Block_Table_Page();
- }
-
- for (i = 0; i < RETRY_TIMES; i++) {
- if (PASS == iErase) {
- phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
- if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
- lba = BLK_FROM_ADDR(blk_addr);
- MARK_BLOCK_AS_BAD(pbt[lba]);
- i = RETRY_TIMES;
- break;
- }
- }
-
- for (j = 0; j < CACHE_ITEM_NUM; j++) {
- addr = Cache.array[j].address;
- if ((addr <= blk_addr) &&
- ((addr + Cache.cache_item_size) > blk_addr))
- cache_block_to_write = j;
- }
-
- phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
- if (PASS == FTL_Cache_Update_Block(pData,
- old_page_addr, phy_addr)) {
- cache_block_to_write = UNHIT_CACHE_ITEM;
- break;
- } else {
- iErase = PASS;
- }
- }
-
- if (i >= RETRY_TIMES) {
- if (ERR == FTL_Flash_Error_Handle(pData,
- old_page_addr, blk_addr))
- return ERR;
- else
- return FAIL;
- }
-
- return PASS;
-}
-
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Cache_Write_Page
* Inputs: Pointer to buffer, page address, cache block number
@@ -2370,159 +2213,6 @@
return 1;
}
-/******************************************************************
-* Function: GLOB_FTL_Flash_Format
-* Inputs: none
-* Outputs: PASS
-* Description: The block table stores bad block info, including MDF+
-* blocks gone bad over the ages. Therefore, if we have a
-* block table in place, then use it to scan for bad blocks
-* If not, then scan for MDF.
-* Now, a block table will only be found if spectra was already
-* being used. For a fresh flash, we'll go thru scanning for
-* MDF. If spectra was being used, then there is a chance that
-* the MDF has been corrupted. Spectra avoids writing to the
-* first 2 bytes of the spare area to all pages in a block. This
-* covers all known flash devices. However, since flash
-* manufacturers have no standard of where the MDF is stored,
-* this cannot guarantee that the MDF is protected for future
-* devices too. The initial scanning for the block table assures
-* this. It is ok even if the block table is outdated, as all
-* we're looking for are bad block markers.
-* Use this when mounting a file system or starting a
-* new flash.
-*
-*********************************************************************/
-static int FTL_Format_Flash(u8 valid_block_table)
-{
- u32 i, j;
- u32 *pbt = (u32 *)g_pBlockTable;
- u32 tempNode;
- int ret;
-
-#if CMD_DMA
- u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy;
- if (ftl_cmd_cnt)
- return FAIL;
-#endif
-
- if (FAIL == FTL_Check_Block_Table(FAIL))
- valid_block_table = 0;
-
- if (valid_block_table) {
- u8 switched = 1;
- u32 block, k;
-
- k = DeviceInfo.wSpectraStartBlock;
- while (switched && (k < DeviceInfo.wSpectraEndBlock)) {
- switched = 0;
- k++;
- for (j = DeviceInfo.wSpectraStartBlock, i = 0;
- j <= DeviceInfo.wSpectraEndBlock;
- j++, i++) {
- block = (pbt[i] & ~BAD_BLOCK) -
- DeviceInfo.wSpectraStartBlock;
- if (block != i) {
- switched = 1;
- tempNode = pbt[i];
- pbt[i] = pbt[block];
- pbt[block] = tempNode;
- }
- }
- }
- if ((k == DeviceInfo.wSpectraEndBlock) && switched)
- valid_block_table = 0;
- }
-
- if (!valid_block_table) {
- memset(g_pBlockTable, 0,
- DeviceInfo.wDataBlockNum * sizeof(u32));
- memset(g_pWearCounter, 0,
- DeviceInfo.wDataBlockNum * sizeof(u8));
- if (DeviceInfo.MLCDevice)
- memset(g_pReadCounter, 0,
- DeviceInfo.wDataBlockNum * sizeof(u16));
-#if CMD_DMA
- memset(g_pBTStartingCopy, 0,
- DeviceInfo.wDataBlockNum * sizeof(u32));
- memset(g_pWearCounterCopy, 0,
- DeviceInfo.wDataBlockNum * sizeof(u8));
- if (DeviceInfo.MLCDevice)
- memset(g_pReadCounterCopy, 0,
- DeviceInfo.wDataBlockNum * sizeof(u16));
-#endif
- for (j = DeviceInfo.wSpectraStartBlock, i = 0;
- j <= DeviceInfo.wSpectraEndBlock;
- j++, i++) {
- if (GLOB_LLD_Get_Bad_Block((u32)j))
- pbt[i] = (u32)(BAD_BLOCK | j);
- }
- }
-
- nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n");
-
- for (j = DeviceInfo.wSpectraStartBlock, i = 0;
- j <= DeviceInfo.wSpectraEndBlock;
- j++, i++) {
- if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) {
- ret = GLOB_LLD_Erase_Block(j);
- if (FAIL == ret) {
- pbt[i] = (u32)(j);
- MARK_BLOCK_AS_BAD(pbt[i]);
- nand_dbg_print(NAND_DBG_WARN,
- "NAND Program fail in %s, Line %d, "
- "Function: %s, new Bad Block %d generated!\n",
- __FILE__, __LINE__, __func__, (int)j);
- } else {
- pbt[i] = (u32)(SPARE_BLOCK | j);
- }
- }
-#if CMD_DMA
- pbtStartingCopy[i] = pbt[i];
-#endif
- }
-
- g_wBlockTableOffset = 0;
- for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock -
- DeviceInfo.wSpectraStartBlock))
- && ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++)
- ;
- if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) {
- printk(KERN_ERR "All blocks bad!\n");
- return FAIL;
- } else {
- g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK;
- if (i != BLOCK_TABLE_INDEX) {
- tempNode = pbt[i];
- pbt[i] = pbt[BLOCK_TABLE_INDEX];
- pbt[BLOCK_TABLE_INDEX] = tempNode;
- }
- }
- pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
-
-#if CMD_DMA
- pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK);
-#endif
-
- g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
- memset(g_pBTBlocks, 0xFF,
- (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32));
- g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex;
- FTL_Write_Block_Table(FAIL);
-
- for (i = 0; i < CACHE_ITEM_NUM; i++) {
- Cache.array[i].address = NAND_CACHE_INIT_ADDR;
- Cache.array[i].use_cnt = 0;
- Cache.array[i].changed = CLEAR;
- }
-
-#if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA)
- memcpy((void *)&cache_start_copy, (void *)&Cache,
- sizeof(struct flash_cache_tag));
-#endif
- return PASS;
-}
-
static int force_format_nand(void)
{
u32 i;
@@ -3031,112 +2721,6 @@
return wResult;
}
-
-/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
-* Function: FTL_Flash_Error_Handle
-* Inputs: Pointer to data
-* Page address
-* Block address
-* Outputs: PASS=0 / FAIL=1
-* Description: It handles any error occured during Spectra operation
-*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
-static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr,
- u64 blk_addr)
-{
- u32 i;
- int j;
- u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr);
- u64 phy_addr;
- int wErase = FAIL;
- int wResult = FAIL;
- u32 *pbt = (u32 *)g_pBlockTable;
-
- nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
- __FILE__, __LINE__, __func__);
-
- if (ERR == GLOB_FTL_Garbage_Collection())
- return ERR;
-
- do {
- for (i = DeviceInfo.wSpectraEndBlock -
- DeviceInfo.wSpectraStartBlock;
- i > 0; i--) {
- if (IS_SPARE_BLOCK(i)) {
- tmp_node = (u32)(BAD_BLOCK |
- pbt[blk_node]);
- pbt[blk_node] = (u32)(pbt[i] &
- (~SPARE_BLOCK));
- pbt[i] = tmp_node;
-#if CMD_DMA
- p_BTableChangesDelta =
- (struct BTableChangesDelta *)
- g_pBTDelta_Free;
- g_pBTDelta_Free +=
- sizeof(struct BTableChangesDelta);
-
- p_BTableChangesDelta->ftl_cmd_cnt =
- ftl_cmd_cnt;
- p_BTableChangesDelta->BT_Index =
- blk_node;
- p_BTableChangesDelta->BT_Entry_Value =
- pbt[blk_node];
- p_BTableChangesDelta->ValidFields = 0x0C;
-
- p_BTableChangesDelta =
- (struct BTableChangesDelta *)
- g_pBTDelta_Free;
- g_pBTDelta_Free +=
- sizeof(struct BTableChangesDelta);
-
- p_BTableChangesDelta->ftl_cmd_cnt =
- ftl_cmd_cnt;
- p_BTableChangesDelta->BT_Index = i;
- p_BTableChangesDelta->BT_Entry_Value = pbt[i];
- p_BTableChangesDelta->ValidFields = 0x0C;
-#endif
- wResult = PASS;
- break;
- }
- }
-
- if (FAIL == wResult) {
- if (FAIL == GLOB_FTL_Garbage_Collection())
- break;
- else
- continue;
- }
-
- if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) {
- g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE;
- FTL_Write_IN_Progress_Block_Table_Page();
- }
-
- phy_addr = FTL_Get_Physical_Block_Addr(blk_addr);
-
- for (j = 0; j < RETRY_TIMES; j++) {
- if (PASS == wErase) {
- if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) {
- MARK_BLOCK_AS_BAD(pbt[blk_node]);
- break;
- }
- }
- if (PASS == FTL_Cache_Update_Block(pData,
- old_page_addr,
- phy_addr)) {
- wResult = PASS;
- break;
- } else {
- wResult = FAIL;
- wErase = PASS;
- }
- }
- } while (FAIL == wResult);
-
- FTL_Write_Block_Table(FAIL);
-
- return wResult;
-}
-
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function: FTL_Get_Page_Num
* Inputs: Size in bytes
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index e483f80..1160c55 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -723,12 +723,12 @@
/**
* usb_string_ids_n() - allocate unused string IDs in batch
- * @cdev: the device whose string descriptor IDs are being allocated
+ * @c: the device whose string descriptor IDs are being allocated
* @n: number of string IDs to allocate
* Context: single threaded during gadget setup
*
* Returns the first requested ID. This ID and next @n-1 IDs are now
- * valid IDs. At least providind that @n is non zore because if it
+ * valid IDs. At least provided that @n is non-zero because if it
* is, returns last requested ID which is now very useful information.
*
* @usb_string_ids_n() is called from bind() callbacks to allocate
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 166bf71..e03058f 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -1609,6 +1609,7 @@
/* initialize ucd */
m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
if (m66592 == NULL) {
+ ret = -ENOMEM;
pr_err("kzalloc error\n");
goto clean_up;
}
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 70a8178..2456ccd 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -1557,6 +1557,7 @@
/* initialize ucd */
r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL);
if (r8a66597 == NULL) {
+ ret = -ENOMEM;
printk(KERN_ERR "kzalloc error\n");
goto clean_up;
}
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c
index 2dcffda..5e807f0 100644
--- a/drivers/usb/gadget/uvc_v4l2.c
+++ b/drivers/usb/gadget/uvc_v4l2.c
@@ -94,7 +94,7 @@
break;
}
- if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
+ if (i == ARRAY_SIZE(uvc_formats)) {
printk(KERN_INFO "Unsupported format 0x%08x.\n",
fmt->fmt.pix.pixelformat);
return -EINVAL;
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index d1a3dfc..bdba8c5 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -829,6 +829,7 @@
* almost immediately. With ISP1761, this register requires a delay of
* 195ns between a write and subsequent read (see section 15.1.1.3).
*/
+ mmiowb();
ndelay(195);
skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG);
@@ -870,6 +871,7 @@
* almost immediately. With ISP1761, this register requires a delay of
* 195ns between a write and subsequent read (see section 15.1.1.3).
*/
+ mmiowb();
ndelay(195);
skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index bc3f4f4..48e60d1 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -131,7 +131,7 @@
*seg = (*seg)->next;
*trb = ((*seg)->trbs);
} else {
- *trb = (*trb)++;
+ (*trb)++;
}
}
@@ -1551,6 +1551,10 @@
/* calc actual length */
if (ep->skip) {
td->urb->iso_frame_desc[idx].actual_length = 0;
+ /* Update ring dequeue pointer */
+ while (ep_ring->dequeue != td->last_trb)
+ inc_deq(xhci, ep_ring, false);
+ inc_deq(xhci, ep_ring, false);
return finish_td(xhci, td, event_trb, event, ep, status, true);
}
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index d240de0..801324a 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -439,7 +439,7 @@
/* drain secondary buffer */
int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary;
i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount);
- if (i < 0) {
+ if (i) {
retval = -EFAULT;
goto exit;
}
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 2de49c8..bc88c79 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -542,7 +542,7 @@
retval = io_res;
else {
io_res = copy_to_user(user_buffer, buffer, dev->report_size);
- if (io_res < 0)
+ if (io_res)
retval = -EFAULT;
}
break;
@@ -574,7 +574,7 @@
}
io_res = copy_to_user((struct iowarrior_info __user *)arg, &info,
sizeof(struct iowarrior_info));
- if (io_res < 0)
+ if (io_res)
retval = -EFAULT;
break;
}
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 0e88885..05aaac1 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -550,6 +550,7 @@
struct twl4030_usb_data *pdata = pdev->dev.platform_data;
struct twl4030_usb *twl;
int status, err;
+ u8 pwr;
if (!pdata) {
dev_dbg(&pdev->dev, "platform_data not available\n");
@@ -568,7 +569,10 @@
twl->otg.set_peripheral = twl4030_set_peripheral;
twl->otg.set_suspend = twl4030_set_suspend;
twl->usb_mode = pdata->usb_mode;
- twl->asleep = 1;
+
+ pwr = twl4030_usb_read(twl, PHY_PWR_CTRL);
+
+ twl->asleep = (pwr & PHY_PWR_PHYPWD);
/* init spinlock for workqueue */
spin_lock_init(&twl->lock);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 2bef441..80bf833 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -222,8 +222,8 @@
#define BITS_STOP_2 0x0002
/* CP210X_SET_BREAK */
-#define BREAK_ON 0x0000
-#define BREAK_OFF 0x0001
+#define BREAK_ON 0x0001
+#define BREAK_OFF 0x0000
/* CP210X_(SET_MHS|GET_MDMSTS) */
#define CONTROL_DTR 0x0001
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index eb12d9b..63ddb2f 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -180,6 +180,7 @@
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SPROG_II) },
+ { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) },
@@ -750,6 +751,8 @@
{ USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID),
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) },
+ { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -1376,7 +1379,7 @@
}
/* set max packet size based on descriptor */
- priv->max_packet_size = ep_desc->wMaxPacketSize;
+ priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize);
dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
}
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 6e612c5..2e95857 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -110,6 +110,9 @@
/* Propox devices */
#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
+/* Lenz LI-USB Computer Interface. */
+#define FTDI_LENZ_LIUSB_PID 0xD780
+
/*
* Xsens Technologies BV products (http://www.xsens.com).
*/
@@ -989,6 +992,12 @@
#define ALTI2_N3_PID 0x6001 /* Neptune 3 */
/*
+ * Ionics PlugComputer
+ */
+#define IONICS_VID 0x1c0c
+#define IONICS_PLUGCOMPUTER_PID 0x0102
+
+/*
* Dresden Elektronik Sensor Terminal Board
*/
#define DE_VID 0x1cf1 /* Vendor ID */
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index ca92f67..0b1a133 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -518,6 +518,7 @@
for (i = 0; i < serial->num_ports; ++i)
generic_cleanup(serial->port[i]);
}
+EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect);
void usb_serial_generic_release(struct usb_serial *serial)
{
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index dc47f98..a7cfc59 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1151,7 +1151,7 @@
/* Check if we have an old version in the I2C and
update if necessary */
- if (download_cur_ver != download_new_ver) {
+ if (download_cur_ver < download_new_ver) {
dbg("%s - Update I2C dld from %d.%d to %d.%d",
__func__,
firmware_version->Ver_Major,
@@ -1284,7 +1284,7 @@
kfree(header);
kfree(rom_desc);
kfree(ti_manuf_desc);
- return status;
+ return -EINVAL;
}
/* Update I2C with type 0xf2 record with correct
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index a6b207c..1f00f24 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -25,6 +25,7 @@
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */
+ { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 9fc6ea2..adcbdb9 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -365,6 +365,10 @@
#define OLIVETTI_VENDOR_ID 0x0b3c
#define OLIVETTI_PRODUCT_OLICARD100 0xc000
+/* Celot products */
+#define CELOT_VENDOR_ID 0x211f
+#define CELOT_PRODUCT_CT680M 0x6801
+
/* some devices interfaces need special handling due to a number of reasons */
enum option_blacklist_reason {
OPTION_BLACKLIST_NONE = 0,
@@ -887,10 +891,9 @@
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
{ USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
-
{ USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
-
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
+ { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 6b60018..c98f0fb 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -86,6 +86,7 @@
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
+ { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index a871645..43eb9bd 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -128,6 +128,10 @@
#define CRESSI_VENDOR_ID 0x04b8
#define CRESSI_EDY_PRODUCT_ID 0x0521
+/* Zeagle dive computer interface */
+#define ZEAGLE_VENDOR_ID 0x04b8
+#define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522
+
/* Sony, USB data cable for CMD-Jxx mobile phones */
#define SONY_VENDOR_ID 0x054c
#define SONY_QN3USB_PRODUCT_ID 0x0437
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
index 6e82d4f..660c31f 100644
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -15,6 +15,7 @@
#include <linux/serial.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
+#include <linux/serial_reg.h>
#include <linux/uaccess.h>
#define QT_OPEN_CLOSE_CHANNEL 0xca
@@ -27,36 +28,11 @@
#define QT_HW_FLOW_CONTROL_MASK 0xc5
#define QT_SW_FLOW_CONTROL_MASK 0xc6
-#define MODEM_CTL_REGISTER 0x04
-#define MODEM_STATUS_REGISTER 0x06
-
-
-#define SERIAL_LSR_OE 0x02
-#define SERIAL_LSR_PE 0x04
-#define SERIAL_LSR_FE 0x08
-#define SERIAL_LSR_BI 0x10
-
-#define SERIAL_LSR_TEMT 0x40
-
-#define SERIAL_MCR_DTR 0x01
-#define SERIAL_MCR_RTS 0x02
-#define SERIAL_MCR_LOOP 0x10
-
-#define SERIAL_MSR_CTS 0x10
-#define SERIAL_MSR_CD 0x80
-#define SERIAL_MSR_RI 0x40
-#define SERIAL_MSR_DSR 0x20
#define SERIAL_MSR_MASK 0xf0
-#define SERIAL_CRTSCTS ((SERIAL_MCR_RTS << 8) | SERIAL_MSR_CTS)
+#define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS)
-#define SERIAL_8_DATA 0x03
-#define SERIAL_7_DATA 0x02
-#define SERIAL_6_DATA 0x01
-#define SERIAL_5_DATA 0x00
-
-#define SERIAL_ODD_PARITY 0X08
-#define SERIAL_EVEN_PARITY 0X18
+#define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR)
#define MAX_BAUD_RATE 460800
@@ -99,10 +75,12 @@
};
struct ssu100_port_private {
+ spinlock_t status_lock;
u8 shadowLSR;
u8 shadowMSR;
wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
unsigned short max_packet_size;
+ struct async_icount icount;
};
static void ssu100_release(struct usb_serial *serial)
@@ -150,9 +128,10 @@
static inline int ssu100_setregister(struct usb_device *dev,
unsigned short uart,
+ unsigned short reg,
u16 data)
{
- u16 value = (data << 8) | MODEM_CTL_REGISTER;
+ u16 value = (data << 8) | reg;
return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
QT_SET_GET_REGISTER, 0x40, value, uart,
@@ -178,11 +157,11 @@
clear &= ~set; /* 'set' takes precedence over 'clear' */
urb_value = 0;
if (set & TIOCM_DTR)
- urb_value |= SERIAL_MCR_DTR;
+ urb_value |= UART_MCR_DTR;
if (set & TIOCM_RTS)
- urb_value |= SERIAL_MCR_RTS;
+ urb_value |= UART_MCR_RTS;
- result = ssu100_setregister(dev, 0, urb_value);
+ result = ssu100_setregister(dev, 0, UART_MCR, urb_value);
if (result < 0)
dbg("%s Error from MODEM_CTRL urb", __func__);
@@ -264,24 +243,24 @@
if (cflag & PARENB) {
if (cflag & PARODD)
- urb_value |= SERIAL_ODD_PARITY;
+ urb_value |= UART_LCR_PARITY;
else
urb_value |= SERIAL_EVEN_PARITY;
}
switch (cflag & CSIZE) {
case CS5:
- urb_value |= SERIAL_5_DATA;
+ urb_value |= UART_LCR_WLEN5;
break;
case CS6:
- urb_value |= SERIAL_6_DATA;
+ urb_value |= UART_LCR_WLEN6;
break;
case CS7:
- urb_value |= SERIAL_7_DATA;
+ urb_value |= UART_LCR_WLEN7;
break;
default:
case CS8:
- urb_value |= SERIAL_8_DATA;
+ urb_value |= UART_LCR_WLEN8;
break;
}
@@ -333,6 +312,7 @@
struct ssu100_port_private *priv = usb_get_serial_port_data(port);
u8 *data;
int result;
+ unsigned long flags;
dbg("%s - port %d", __func__, port->number);
@@ -350,11 +330,10 @@
return result;
}
- priv->shadowLSR = data[0] & (SERIAL_LSR_OE | SERIAL_LSR_PE |
- SERIAL_LSR_FE | SERIAL_LSR_BI);
-
- priv->shadowMSR = data[1] & (SERIAL_MSR_CTS | SERIAL_MSR_DSR |
- SERIAL_MSR_RI | SERIAL_MSR_CD);
+ spin_lock_irqsave(&priv->status_lock, flags);
+ priv->shadowLSR = data[0];
+ priv->shadowMSR = data[1];
+ spin_unlock_irqrestore(&priv->status_lock, flags);
kfree(data);
@@ -398,11 +377,51 @@
return 0;
}
+static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+{
+ struct ssu100_port_private *priv = usb_get_serial_port_data(port);
+ struct async_icount prev, cur;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->status_lock, flags);
+ prev = priv->icount;
+ spin_unlock_irqrestore(&priv->status_lock, flags);
+
+ while (1) {
+ wait_event_interruptible(priv->delta_msr_wait,
+ ((priv->icount.rng != prev.rng) ||
+ (priv->icount.dsr != prev.dsr) ||
+ (priv->icount.dcd != prev.dcd) ||
+ (priv->icount.cts != prev.cts)));
+
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
+ spin_lock_irqsave(&priv->status_lock, flags);
+ cur = priv->icount;
+ spin_unlock_irqrestore(&priv->status_lock, flags);
+
+ if ((prev.rng == cur.rng) &&
+ (prev.dsr == cur.dsr) &&
+ (prev.dcd == cur.dcd) &&
+ (prev.cts == cur.cts))
+ return -EIO;
+
+ if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) ||
+ (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) ||
+ (arg & TIOCM_CD && (prev.dcd != cur.dcd)) ||
+ (arg & TIOCM_CTS && (prev.cts != cur.cts)))
+ return 0;
+ }
+ return 0;
+}
+
static int ssu100_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct usb_serial_port *port = tty->driver_data;
struct ssu100_port_private *priv = usb_get_serial_port_data(port);
+ void __user *user_arg = (void __user *)arg;
dbg("%s cmd 0x%04x", __func__, cmd);
@@ -412,28 +431,28 @@
(struct serial_struct __user *) arg);
case TIOCMIWAIT:
- while (priv != NULL) {
- u8 prevMSR = priv->shadowMSR & SERIAL_MSR_MASK;
- interruptible_sleep_on(&priv->delta_msr_wait);
- /* see if a signal did it */
- if (signal_pending(current))
- return -ERESTARTSYS;
- else {
- u8 diff = (priv->shadowMSR & SERIAL_MSR_MASK) ^ prevMSR;
- if (!diff)
- return -EIO; /* no change => error */
+ return wait_modem_info(port, arg);
- /* Return 0 if caller wanted to know about
- these bits */
-
- if (((arg & TIOCM_RNG) && (diff & SERIAL_MSR_RI)) ||
- ((arg & TIOCM_DSR) && (diff & SERIAL_MSR_DSR)) ||
- ((arg & TIOCM_CD) && (diff & SERIAL_MSR_CD)) ||
- ((arg & TIOCM_CTS) && (diff & SERIAL_MSR_CTS)))
- return 0;
- }
- }
+ case TIOCGICOUNT:
+ {
+ struct serial_icounter_struct icount;
+ struct async_icount cnow = priv->icount;
+ memset(&icount, 0, sizeof(icount));
+ icount.cts = cnow.cts;
+ icount.dsr = cnow.dsr;
+ icount.rng = cnow.rng;
+ icount.dcd = cnow.dcd;
+ icount.rx = cnow.rx;
+ icount.tx = cnow.tx;
+ icount.frame = cnow.frame;
+ icount.overrun = cnow.overrun;
+ icount.parity = cnow.parity;
+ icount.brk = cnow.brk;
+ icount.buf_overrun = cnow.buf_overrun;
+ if (copy_to_user(user_arg, &icount, sizeof(icount)))
+ return -EFAULT;
return 0;
+ }
default:
break;
@@ -455,6 +474,7 @@
unsigned num_endpoints;
int i;
+ unsigned long flags;
num_endpoints = interface->cur_altsetting->desc.bNumEndpoints;
dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints);
@@ -466,7 +486,9 @@
}
/* set max packet size based on descriptor */
+ spin_lock_irqsave(&priv->status_lock, flags);
priv->max_packet_size = ep_desc->wMaxPacketSize;
+ spin_unlock_irqrestore(&priv->status_lock, flags);
dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size);
}
@@ -485,9 +507,9 @@
return -ENOMEM;
}
+ spin_lock_init(&priv->status_lock);
init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv);
-
ssu100_set_max_packet_size(port);
return ssu100_initdevice(serial->dev);
@@ -506,20 +528,20 @@
if (!d)
return -ENOMEM;
- r = ssu100_getregister(dev, 0, MODEM_CTL_REGISTER, d);
+ r = ssu100_getregister(dev, 0, UART_MCR, d);
if (r < 0)
goto mget_out;
- r = ssu100_getregister(dev, 0, MODEM_STATUS_REGISTER, d+1);
+ r = ssu100_getregister(dev, 0, UART_MSR, d+1);
if (r < 0)
goto mget_out;
- r = (d[0] & SERIAL_MCR_DTR ? TIOCM_DTR : 0) |
- (d[0] & SERIAL_MCR_RTS ? TIOCM_RTS : 0) |
- (d[1] & SERIAL_MSR_CTS ? TIOCM_CTS : 0) |
- (d[1] & SERIAL_MSR_CD ? TIOCM_CAR : 0) |
- (d[1] & SERIAL_MSR_RI ? TIOCM_RI : 0) |
- (d[1] & SERIAL_MSR_DSR ? TIOCM_DSR : 0);
+ r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) |
+ (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) |
+ (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) |
+ (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) |
+ (d[1] & UART_MSR_RI ? TIOCM_RI : 0) |
+ (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0);
mget_out:
kfree(d);
@@ -546,7 +568,7 @@
if (!port->serial->disconnected) {
/* Disable flow control */
if (!on &&
- ssu100_setregister(dev, 0, 0) < 0)
+ ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
dev_err(&port->dev, "error from flowcontrol urb\n");
/* drop RTS and DTR */
if (on)
@@ -557,34 +579,88 @@
mutex_unlock(&port->serial->disc_mutex);
}
+static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
+{
+ struct ssu100_port_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->status_lock, flags);
+ priv->shadowMSR = msr;
+ spin_unlock_irqrestore(&priv->status_lock, flags);
+
+ if (msr & UART_MSR_ANY_DELTA) {
+ /* update input line counters */
+ if (msr & UART_MSR_DCTS)
+ priv->icount.cts++;
+ if (msr & UART_MSR_DDSR)
+ priv->icount.dsr++;
+ if (msr & UART_MSR_DDCD)
+ priv->icount.dcd++;
+ if (msr & UART_MSR_TERI)
+ priv->icount.rng++;
+ wake_up_interruptible(&priv->delta_msr_wait);
+ }
+}
+
+static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
+ char *tty_flag)
+{
+ struct ssu100_port_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->status_lock, flags);
+ priv->shadowLSR = lsr;
+ spin_unlock_irqrestore(&priv->status_lock, flags);
+
+ *tty_flag = TTY_NORMAL;
+ if (lsr & UART_LSR_BRK_ERROR_BITS) {
+ /* we always want to update icount, but we only want to
+ * update tty_flag for one case */
+ if (lsr & UART_LSR_BI) {
+ priv->icount.brk++;
+ *tty_flag = TTY_BREAK;
+ usb_serial_handle_break(port);
+ }
+ if (lsr & UART_LSR_PE) {
+ priv->icount.parity++;
+ if (*tty_flag == TTY_NORMAL)
+ *tty_flag = TTY_PARITY;
+ }
+ if (lsr & UART_LSR_FE) {
+ priv->icount.frame++;
+ if (*tty_flag == TTY_NORMAL)
+ *tty_flag = TTY_FRAME;
+ }
+ if (lsr & UART_LSR_OE){
+ priv->icount.overrun++;
+ if (*tty_flag == TTY_NORMAL)
+ *tty_flag = TTY_OVERRUN;
+ }
+ }
+
+}
+
static int ssu100_process_packet(struct tty_struct *tty,
struct usb_serial_port *port,
struct ssu100_port_private *priv,
char *packet, int len)
{
int i;
- char flag;
+ char flag = TTY_NORMAL;
char *ch;
dbg("%s - port %d", __func__, port->number);
- if (len < 4) {
- dbg("%s - malformed packet", __func__);
- return 0;
- }
-
- if ((packet[0] == 0x1b) && (packet[1] == 0x1b) &&
+ if ((len >= 4) &&
+ (packet[0] == 0x1b) && (packet[1] == 0x1b) &&
((packet[2] == 0x00) || (packet[2] == 0x01))) {
- if (packet[2] == 0x00)
- priv->shadowLSR = packet[3] & (SERIAL_LSR_OE |
- SERIAL_LSR_PE |
- SERIAL_LSR_FE |
- SERIAL_LSR_BI);
-
- if (packet[2] == 0x01) {
- priv->shadowMSR = packet[3];
- wake_up_interruptible(&priv->delta_msr_wait);
+ if (packet[2] == 0x00) {
+ ssu100_update_lsr(port, packet[3], &flag);
+ if (flag == TTY_OVERRUN)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
}
+ if (packet[2] == 0x01)
+ ssu100_update_msr(port, packet[3]);
len -= 4;
ch = packet + 4;
@@ -631,7 +707,6 @@
tty_kref_put(tty);
}
-
static struct usb_serial_driver ssu100_device = {
.driver = {
.owner = THIS_MODULE,
@@ -653,6 +728,7 @@
.tiocmset = ssu100_tiocmset,
.ioctl = ssu100_ioctl,
.set_termios = ssu100_set_termios,
+ .disconnect = usb_serial_generic_disconnect,
};
static int __init ssu100_init(void)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 2a982e6..7a2177c 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -736,6 +736,7 @@
serial = create_serial(dev, interface, type);
if (!serial) {
+ module_put(type->driver.owner);
dev_err(&interface->dev, "%s - out of memory\n", __func__);
return -ENOMEM;
}
@@ -746,11 +747,11 @@
id = get_iface_id(type, interface);
retval = type->probe(serial, id);
- module_put(type->driver.owner);
if (retval) {
dbg("sub driver rejected device");
kfree(serial);
+ module_put(type->driver.owner);
return retval;
}
}
@@ -822,6 +823,7 @@
if (num_bulk_in == 0 || num_bulk_out == 0) {
dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
kfree(serial);
+ module_put(type->driver.owner);
return -ENODEV;
}
}
@@ -835,22 +837,15 @@
dev_err(&interface->dev,
"Generic device with no bulk out, not allowed.\n");
kfree(serial);
+ module_put(type->driver.owner);
return -EIO;
}
}
#endif
if (!num_ports) {
/* if this device type has a calc_num_ports function, call it */
- if (type->calc_num_ports) {
- if (!try_module_get(type->driver.owner)) {
- dev_err(&interface->dev,
- "module get failed, exiting\n");
- kfree(serial);
- return -EIO;
- }
+ if (type->calc_num_ports)
num_ports = type->calc_num_ports(serial);
- module_put(type->driver.owner);
- }
if (!num_ports)
num_ports = type->num_ports;
}
@@ -1039,13 +1034,7 @@
/* if this device type has an attach function, call it */
if (type->attach) {
- if (!try_module_get(type->driver.owner)) {
- dev_err(&interface->dev,
- "module get failed, exiting\n");
- goto probe_error;
- }
retval = type->attach(serial);
- module_put(type->driver.owner);
if (retval < 0)
goto probe_error;
serial->attached = 1;
@@ -1088,10 +1077,12 @@
exit:
/* success */
usb_set_intfdata(interface, serial);
+ module_put(type->driver.owner);
return 0;
probe_error:
usb_serial_put(serial);
+ module_put(type->driver.owner);
return -EIO;
}
EXPORT_SYMBOL_GPL(usb_serial_probe);
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index cf343a8..7950a37 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -22,6 +22,7 @@
#include <linux/compiler.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
+#include <linux/kobject_ns.h>
#include <linux/kernel.h>
#include <linux/wait.h>
#include <asm/atomic.h>
@@ -136,42 +137,8 @@
extern const struct sysfs_ops kobj_sysfs_ops;
-/*
- * Namespace types which are used to tag kobjects and sysfs entries.
- * Network namespace will likely be the first.
- */
-enum kobj_ns_type {
- KOBJ_NS_TYPE_NONE = 0,
- KOBJ_NS_TYPE_NET,
- KOBJ_NS_TYPES
-};
-
struct sock;
-/*
- * Callbacks so sysfs can determine namespaces
- * @current_ns: return calling task's namespace
- * @netlink_ns: return namespace to which a sock belongs (right?)
- * @initial_ns: return the initial namespace (i.e. init_net_ns)
- */
-struct kobj_ns_type_operations {
- enum kobj_ns_type type;
- const void *(*current_ns)(void);
- const void *(*netlink_ns)(struct sock *sk);
- const void *(*initial_ns)(void);
-};
-
-int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
-int kobj_ns_type_registered(enum kobj_ns_type type);
-const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
-const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
-
-const void *kobj_ns_current(enum kobj_ns_type type);
-const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
-const void *kobj_ns_initial(enum kobj_ns_type type);
-void kobj_ns_exit(enum kobj_ns_type type, const void *ns);
-
-
/**
* struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
*
diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h
new file mode 100644
index 0000000..82cb5bf
--- /dev/null
+++ b/include/linux/kobject_ns.h
@@ -0,0 +1,56 @@
+/* Kernel object name space definitions
+ *
+ * Copyright (c) 2002-2003 Patrick Mochel
+ * Copyright (c) 2002-2003 Open Source Development Labs
+ * Copyright (c) 2006-2008 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (c) 2006-2008 Novell Inc.
+ *
+ * Split from kobject.h by David Howells (dhowells@redhat.com)
+ *
+ * This file is released under the GPLv2.
+ *
+ * Please read Documentation/kobject.txt before using the kobject
+ * interface, ESPECIALLY the parts about reference counts and object
+ * destructors.
+ */
+
+#ifndef _LINUX_KOBJECT_NS_H
+#define _LINUX_KOBJECT_NS_H
+
+struct sock;
+struct kobject;
+
+/*
+ * Namespace types which are used to tag kobjects and sysfs entries.
+ * Network namespace will likely be the first.
+ */
+enum kobj_ns_type {
+ KOBJ_NS_TYPE_NONE = 0,
+ KOBJ_NS_TYPE_NET,
+ KOBJ_NS_TYPES
+};
+
+/*
+ * Callbacks so sysfs can determine namespaces
+ * @current_ns: return calling task's namespace
+ * @netlink_ns: return namespace to which a sock belongs (right?)
+ * @initial_ns: return the initial namespace (i.e. init_net_ns)
+ */
+struct kobj_ns_type_operations {
+ enum kobj_ns_type type;
+ const void *(*current_ns)(void);
+ const void *(*netlink_ns)(struct sock *sk);
+ const void *(*initial_ns)(void);
+};
+
+int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
+int kobj_ns_type_registered(enum kobj_ns_type type);
+const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
+const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
+
+const void *kobj_ns_current(enum kobj_ns_type type);
+const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
+const void *kobj_ns_initial(enum kobj_ns_type type);
+void kobj_ns_exit(enum kobj_ns_type type, const void *ns);
+
+#endif /* _LINUX_KOBJECT_NS_H */
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 3c92121..96eb576 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -16,6 +16,7 @@
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/lockdep.h>
+#include <linux/kobject_ns.h>
#include <asm/atomic.h>
struct kobject;
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 890bc14..6170681 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -247,6 +247,7 @@
* value; it should return zero on successful initialization.
* @unbind: Reverses @bind(); called as a side effect of unregistering
* this driver.
+ * @disconnect: optional driver disconnect method
* @suspend: Notifies when the host stops sending USB traffic,
* after function notifications
* @resume: Notifies configuration when the host restarts USB traffic,
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index b935795..70af0a7 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -123,7 +123,7 @@
* @kobj: struct kobject that the action is happening to
* @envp_ext: pointer to environmental data
*
- * Returns 0 if kobject_uevent() is completed with success or the
+ * Returns 0 if kobject_uevent_env() is completed with success or the
* corresponding error when it fails.
*/
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
@@ -317,7 +317,7 @@
EXPORT_SYMBOL_GPL(kobject_uevent_env);
/**
- * kobject_uevent - notify userspace by ending an uevent
+ * kobject_uevent - notify userspace by sending an uevent
*
* @action: action that is happening
* @kobj: struct kobject that the action is happening to