projects
/
powerpc.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville...
[powerpc.git]
/
drivers
/
s390
/
net
/
ctcmain.c
diff --git
a/drivers/s390/net/ctcmain.c
b/drivers/s390/net/ctcmain.c
index
fe986af
..
b20fd06
100644
(file)
--- a/
drivers/s390/net/ctcmain.c
+++ b/
drivers/s390/net/ctcmain.c
@@
-6,7
+6,7
@@
* Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Peter Tiedemann (ptiedem@de.ibm.com)
* Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Peter Tiedemann (ptiedem@de.ibm.com)
- * Driver Model stuff by : Cornelia Huck <
huckc
@de.ibm.com>
+ * Driver Model stuff by : Cornelia Huck <
cornelia.huck
@de.ibm.com>
*
* Documentation used:
* - Principles of Operation (IBM doc#: SA22-7201-06)
*
* Documentation used:
* - Principles of Operation (IBM doc#: SA22-7201-06)
@@
-45,7
+45,6
@@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
-#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/signal.h>
#include <linux/bitops.h>
#include <linux/signal.h>
@@
-65,7
+64,6
@@
#include <asm/idals.h>
#include <asm/idals.h>
-#include "ctctty.h"
#include "fsm.h"
#include "cu3088.h"
#include "fsm.h"
#include "cu3088.h"
@@
-370,7
+368,7
@@
ctc_dump_skb(struct sk_buff *skb, int offset)
* @param ch The channel where this skb has been received.
* @param pskb The received skb.
*/
* @param ch The channel where this skb has been received.
* @param pskb The received skb.
*/
-static
__inline__
void
+static void
ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
{
struct net_device *dev = ch->netdev;
ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
{
struct net_device *dev = ch->netdev;
@@
-457,7
+455,7
@@
ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
return;
}
skb_put(pskb, header->length);
return;
}
skb_put(pskb, header->length);
-
pskb->mac.raw = pskb->data
;
+
skb_reset_mac_header(pskb)
;
len -= header->length;
skb = dev_alloc_skb(pskb->len);
if (!skb) {
len -= header->length;
skb = dev_alloc_skb(pskb->len);
if (!skb) {
@@
-474,15
+472,13
@@
ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
privptr->stats.rx_dropped++;
return;
}
privptr->stats.rx_dropped++;
return;
}
- memcpy(skb_put(skb, pskb->len), pskb->data, pskb->len);
- skb->mac.raw = skb->data;
+ skb_copy_from_linear_data(pskb, skb_put(skb, pskb->len),
+ pskb->len);
+ skb_reset_mac_header(skb);
skb->dev = pskb->dev;
skb->protocol = pskb->protocol;
pskb->ip_summed = CHECKSUM_UNNECESSARY;
skb->dev = pskb->dev;
skb->protocol = pskb->protocol;
pskb->ip_summed = CHECKSUM_UNNECESSARY;
- if (ch->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_netif_rx(skb);
- else
- netif_rx_ni(skb);
+ netif_rx_ni(skb);
/**
* Successful rx; reset logflags
*/
/**
* Successful rx; reset logflags
*/
@@
-516,7
+512,7
@@
ctc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
* @param ch The channel, the error belongs to.
* @param return_code The error code to inspect.
*/
* @param ch The channel, the error belongs to.
* @param return_code The error code to inspect.
*/
-static void
inline
+static void
ccw_check_return_code(struct channel *ch, int return_code, char *msg)
{
DBF_TEXT(trace, 5, __FUNCTION__);
ccw_check_return_code(struct channel *ch, int return_code, char *msg)
{
DBF_TEXT(trace, 5, __FUNCTION__);
@@
-551,14
+547,13
@@
ccw_check_return_code(struct channel *ch, int return_code, char *msg)
* @param ch The channel, the sense code belongs to.
* @param sense The sense code to inspect.
*/
* @param ch The channel, the sense code belongs to.
* @param sense The sense code to inspect.
*/
-static void
inline
+static void
ccw_unit_check(struct channel *ch, unsigned char sense)
{
DBF_TEXT(trace, 5, __FUNCTION__);
if (sense & SNS0_INTERVENTION_REQ) {
if (sense & 0x01) {
ccw_unit_check(struct channel *ch, unsigned char sense)
{
DBF_TEXT(trace, 5, __FUNCTION__);
if (sense & SNS0_INTERVENTION_REQ) {
if (sense & 0x01) {
- if (ch->protocol != CTC_PROTO_LINUX_TTY)
- ctc_pr_debug("%s: Interface disc. or Sel. reset "
+ ctc_pr_debug("%s: Interface disc. or Sel. reset "
"(remote)\n", ch->id);
fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch);
} else {
"(remote)\n", ch->id);
fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch);
} else {
@@
-608,7
+603,7
@@
ctc_purge_skb_queue(struct sk_buff_head *q)
}
}
}
}
-static
__inline__
int
+static int
ctc_checkalloc_buffer(struct channel *ch, int warn)
{
DBF_TEXT(trace, 5, __FUNCTION__);
ctc_checkalloc_buffer(struct channel *ch, int warn)
{
DBF_TEXT(trace, 5, __FUNCTION__);
@@
-712,7
+707,8
@@
ch_action_txdone(fsm_instance * fi, int event, void *arg)
spin_unlock(&ch->collect_lock);
return;
}
spin_unlock(&ch->collect_lock);
return;
}
- ch->trans_skb->tail = ch->trans_skb->data = ch->trans_skb_data;
+ ch->trans_skb->data = ch->trans_skb_data;
+ skb_reset_tail_pointer(ch->trans_skb);
ch->trans_skb->len = 0;
if (ch->prof.maxmulti < (ch->collect_len + 2))
ch->prof.maxmulti = ch->collect_len + 2;
ch->trans_skb->len = 0;
if (ch->prof.maxmulti < (ch->collect_len + 2))
ch->prof.maxmulti = ch->collect_len + 2;
@@
-721,8
+717,9
@@
ch_action_txdone(fsm_instance * fi, int event, void *arg)
*((__u16 *) skb_put(ch->trans_skb, 2)) = ch->collect_len + 2;
i = 0;
while ((skb = skb_dequeue(&ch->collect_queue))) {
*((__u16 *) skb_put(ch->trans_skb, 2)) = ch->collect_len + 2;
i = 0;
while ((skb = skb_dequeue(&ch->collect_queue))) {
- memcpy(skb_put(ch->trans_skb, skb->len), skb->data,
- skb->len);
+ skb_copy_from_linear_data(skb, skb_put(ch->trans_skb,
+ skb->len),
+ skb->len);
privptr->stats.tx_packets++;
privptr->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
atomic_dec(&skb->users);
privptr->stats.tx_packets++;
privptr->stats.tx_bytes += skb->len - LL_HEADER_LENGTH;
atomic_dec(&skb->users);
@@
-837,7
+834,8
@@
ch_action_rx(fsm_instance * fi, int event, void *arg)
ctc_unpack_skb(ch, skb);
}
again:
ctc_unpack_skb(ch, skb);
}
again:
- skb->data = skb->tail = ch->trans_skb_data;
+ skb->data = ch->trans_skb_data;
+ skb_reset_tail_pointer(skb);
skb->len = 0;
if (ctc_checkalloc_buffer(ch, 1))
return;
skb->len = 0;
if (ctc_checkalloc_buffer(ch, 1))
return;
@@
-1644,21
+1642,19
@@
add_channel(struct ccw_device *cdev, enum channel_types type)
struct channel *ch;
DBF_TEXT(trace, 2, __FUNCTION__);
struct channel *ch;
DBF_TEXT(trace, 2, __FUNCTION__);
- if ((ch =
- (struct channel *) kmalloc(sizeof (struct channel),
- GFP_KERNEL)) == NULL) {
+ ch = kzalloc(sizeof(struct channel), GFP_KERNEL);
+ if (!ch) {
ctc_pr_warn("ctc: Out of memory in add_channel\n");
return -1;
}
ctc_pr_warn("ctc: Out of memory in add_channel\n");
return -1;
}
- memset(ch, 0, sizeof (struct channel));
- if ((ch->ccw = (struct ccw1 *) kmalloc(8*sizeof(struct ccw1),
-
GFP_KERNEL | GFP_DMA)) == NULL
) {
+ /* assure all flags and counters are reset */
+ ch->ccw = kzalloc(8 * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
+
if (!ch->ccw
) {
kfree(ch);
ctc_pr_warn("ctc: Out of memory in add_channel\n");
return -1;
}
kfree(ch);
ctc_pr_warn("ctc: Out of memory in add_channel\n");
return -1;
}
- memset(ch->ccw, 0, 8*sizeof(struct ccw1)); // assure all flags and counters are reset
/**
* "static" ccws are used in the following way:
/**
* "static" ccws are used in the following way:
@@
-1698,15
+1694,14
@@
add_channel(struct ccw_device *cdev, enum channel_types type)
return -1;
}
fsm_newstate(ch->fsm, CH_STATE_IDLE);
return -1;
}
fsm_newstate(ch->fsm, CH_STATE_IDLE);
- if ((ch->irb = (struct irb *) kmalloc(sizeof (struct irb),
-
GFP_KERNEL)) == NULL
) {
+ ch->irb = kzalloc(sizeof(struct irb), GFP_KERNEL);
+
if (!ch->irb
) {
ctc_pr_warn("ctc: Out of memory in add_channel\n");
kfree_fsm(ch->fsm);
kfree(ch->ccw);
kfree(ch);
return -1;
}
ctc_pr_warn("ctc: Out of memory in add_channel\n");
kfree_fsm(ch->fsm);
kfree(ch->ccw);
kfree(ch);
return -1;
}
- memset(ch->irb, 0, sizeof (struct irb));
while (*c && less_than((*c)->id, ch->id))
c = &(*c)->next;
if (*c && (!strncmp((*c)->id, ch->id, CTC_ID_SIZE))) {
while (*c && less_than((*c)->id, ch->id))
c = &(*c)->next;
if (*c && (!strncmp((*c)->id, ch->id, CTC_ID_SIZE))) {
@@
-1719,6
+1714,9
@@
add_channel(struct ccw_device *cdev, enum channel_types type)
kfree(ch);
return 0;
}
kfree(ch);
return 0;
}
+
+ spin_lock_init(&ch->collect_lock);
+
fsm_settimer(ch->fsm, &ch->timer);
skb_queue_head_init(&ch->io_queue);
skb_queue_head_init(&ch->collect_queue);
fsm_settimer(ch->fsm, &ch->timer);
skb_queue_head_init(&ch->io_queue);
skb_queue_head_init(&ch->collect_queue);
@@
-2034,7
+2032,6
@@
static void
dev_action_chup(fsm_instance * fi, int event, void *arg)
{
struct net_device *dev = (struct net_device *) arg;
dev_action_chup(fsm_instance * fi, int event, void *arg)
{
struct net_device *dev = (struct net_device *) arg;
- struct ctc_priv *privptr = dev->priv;
DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
@@
-2049,8
+2046,6
@@
dev_action_chup(fsm_instance * fi, int event, void *arg)
fsm_newstate(fi, DEV_STATE_RUNNING);
ctc_pr_info("%s: connected with remote side\n",
dev->name);
fsm_newstate(fi, DEV_STATE_RUNNING);
ctc_pr_info("%s: connected with remote side\n",
dev->name);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 1);
ctc_clear_busy(dev);
}
break;
ctc_clear_busy(dev);
}
break;
@@
-2059,8
+2054,6
@@
dev_action_chup(fsm_instance * fi, int event, void *arg)
fsm_newstate(fi, DEV_STATE_RUNNING);
ctc_pr_info("%s: connected with remote side\n",
dev->name);
fsm_newstate(fi, DEV_STATE_RUNNING);
ctc_pr_info("%s: connected with remote side\n",
dev->name);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 1);
ctc_clear_busy(dev);
}
break;
ctc_clear_busy(dev);
}
break;
@@
-2086,14
+2079,10
@@
dev_action_chup(fsm_instance * fi, int event, void *arg)
static void
dev_action_chdown(fsm_instance * fi, int event, void *arg)
{
static void
dev_action_chdown(fsm_instance * fi, int event, void *arg)
{
- struct net_device *dev = (struct net_device *) arg;
- struct ctc_priv *privptr = dev->priv;
DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
case DEV_STATE_RUNNING:
DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
case DEV_STATE_RUNNING:
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 0);
if (event == DEV_EVENT_TXDOWN)
fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
else
if (event == DEV_EVENT_TXDOWN)
fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
else
@@
-2238,7
+2227,8
@@
transmit_skb(struct channel *ch, struct sk_buff *skb)
* IDAL support in CTC is broken, so we have to
* care about skb's above 2G ourselves.
*/
* IDAL support in CTC is broken, so we have to
* care about skb's above 2G ourselves.
*/
- hi = ((unsigned long) skb->tail + LL_HEADER_LENGTH) >> 31;
+ hi = ((unsigned long)skb_tail_pointer(skb) +
+ LL_HEADER_LENGTH) >> 31;
if (hi) {
nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
if (!nskb) {
if (hi) {
nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
if (!nskb) {
@@
-2274,11
+2264,12
@@
transmit_skb(struct channel *ch, struct sk_buff *skb)
return -EBUSY;
}
return -EBUSY;
}
-
ch->trans_skb->tail = ch->trans_skb->data
;
+
skb_reset_tail_pointer(ch->trans_skb)
;
ch->trans_skb->len = 0;
ch->ccw[1].count = skb->len;
ch->trans_skb->len = 0;
ch->ccw[1].count = skb->len;
- memcpy(skb_put(ch->trans_skb, skb->len), skb->data,
- skb->len);
+ skb_copy_from_linear_data(skb, skb_put(ch->trans_skb,
+ skb->len),
+ skb->len);
atomic_dec(&skb->users);
dev_kfree_skb_irq(skb);
ccw_idx = 0;
atomic_dec(&skb->users);
dev_kfree_skb_irq(skb);
ccw_idx = 0;
@@
-2397,8
+2388,6
@@
ctc_tx(struct sk_buff *skb, struct net_device * dev)
*/
if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
fsm_event(privptr->fsm, DEV_EVENT_START, dev);
*/
if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
fsm_event(privptr->fsm, DEV_EVENT_START, dev);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- return -EBUSY;
dev_kfree_skb(skb);
privptr->stats.tx_dropped++;
privptr->stats.tx_errors++;
dev_kfree_skb(skb);
privptr->stats.tx_dropped++;
privptr->stats.tx_errors++;
@@
-2548,7
+2537,7
@@
ctc_print_statistics(struct ctc_priv *priv)
DBF_TEXT(trace, 4, __FUNCTION__);
if (!priv)
return;
DBF_TEXT(trace, 4, __FUNCTION__);
if (!priv)
return;
- sbuf =
(char *)
kmalloc(2048, GFP_KERNEL);
+ sbuf = kmalloc(2048, GFP_KERNEL);
if (sbuf == NULL)
return;
p = sbuf;
if (sbuf == NULL)
return;
p = sbuf;
@@
-2608,20
+2597,13
@@
ctc_netdev_unregister(struct net_device * dev)
if (!dev)
return;
privptr = (struct ctc_priv *) dev->priv;
if (!dev)
return;
privptr = (struct ctc_priv *) dev->priv;
- if (privptr->protocol != CTC_PROTO_LINUX_TTY)
- unregister_netdev(dev);
- else
- ctc_tty_unregister_netdev(dev);
+ unregister_netdev(dev);
}
static int
ctc_netdev_register(struct net_device * dev)
{
}
static int
ctc_netdev_register(struct net_device * dev)
{
- struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
- if (privptr->protocol != CTC_PROTO_LINUX_TTY)
- return register_netdev(dev);
- else
- return ctc_tty_register_netdev(dev);
+ return register_netdev(dev);
}
static void
}
static void
@@
-2667,7
+2649,9
@@
ctc_proto_store(struct device *dev, struct device_attribute *attr, const char *b
if (!priv)
return -ENODEV;
sscanf(buf, "%u", &value);
if (!priv)
return -ENODEV;
sscanf(buf, "%u", &value);
- if ((value < 0) || (value > CTC_PROTO_MAX))
+ if (!((value == CTC_PROTO_S390) ||
+ (value == CTC_PROTO_LINUX) ||
+ (value == CTC_PROTO_OS390)))
return -EINVAL;
priv->protocol = value;
return -EINVAL;
priv->protocol = value;
@@
-2707,9
+2691,17
@@
static struct attribute_group ctc_attr_group = {
static int
ctc_add_attributes(struct device *dev)
{
static int
ctc_add_attributes(struct device *dev)
{
- device_create_file(dev, &dev_attr_loglevel);
- device_create_file(dev, &dev_attr_stats);
- return 0;
+ int rc;
+
+ rc = device_create_file(dev, &dev_attr_loglevel);
+ if (rc)
+ goto out;
+ rc = device_create_file(dev, &dev_attr_stats);
+ if (!rc)
+ goto out;
+ device_remove_file(dev, &dev_attr_loglevel);
+out:
+ return rc;
}
static void
}
static void
@@
-2756,14
+2748,13
@@
ctc_probe_device(struct ccwgroup_device *cgdev)
if (!get_device(&cgdev->dev))
return -ENODEV;
if (!get_device(&cgdev->dev))
return -ENODEV;
- priv = k
malloc(sizeof
(struct ctc_priv), GFP_KERNEL);
+ priv = k
zalloc(sizeof
(struct ctc_priv), GFP_KERNEL);
if (!priv) {
ctc_pr_err("%s: Out of memory\n", __func__);
put_device(&cgdev->dev);
return -ENOMEM;
}
if (!priv) {
ctc_pr_err("%s: Out of memory\n", __func__);
put_device(&cgdev->dev);
return -ENOMEM;
}
- memset(priv, 0, sizeof (struct ctc_priv));
rc = ctc_add_files(&cgdev->dev);
if (rc) {
kfree(priv);
rc = ctc_add_files(&cgdev->dev);
if (rc) {
kfree(priv);
@@
-2804,10
+2795,9
@@
ctc_init_netdevice(struct net_device * dev, int alloc_device,
DBF_TEXT(setup, 3, __FUNCTION__);
if (alloc_device) {
DBF_TEXT(setup, 3, __FUNCTION__);
if (alloc_device) {
- dev = k
malloc(sizeof
(struct net_device), GFP_KERNEL);
+ dev = k
zalloc(sizeof
(struct net_device), GFP_KERNEL);
if (!dev)
return NULL;
if (!dev)
return NULL;
- memset(dev, 0, sizeof (struct net_device));
}
dev->priv = privptr;
}
dev->priv = privptr;
@@
-2897,10
+2887,7
@@
ctc_new_device(struct ccwgroup_device *cgdev)
goto out;
}
goto out;
}
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- strlcpy(dev->name, "ctctty%d", IFNAMSIZ);
- else
- strlcpy(dev->name, "ctc%d", IFNAMSIZ);
+ strlcpy(dev->name, "ctc%d", IFNAMSIZ);
for (direction = READ; direction <= WRITE; direction++) {
privptr->channel[direction] =
for (direction = READ; direction <= WRITE; direction++) {
privptr->channel[direction] =
@@
-2925,7
+2912,12
@@
ctc_new_device(struct ccwgroup_device *cgdev)
goto out;
}
goto out;
}
- ctc_add_attributes(&cgdev->dev);
+ if (ctc_add_attributes(&cgdev->dev)) {
+ ctc_netdev_unregister(dev);
+ dev->priv = NULL;
+ ctc_free_netdevice(dev, 1);
+ goto out;
+ }
strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name));
strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name));
@@
-3046,7
+3038,6
@@
ctc_exit(void)
{
DBF_TEXT(setup, 3, __FUNCTION__);
unregister_cu3088_discipline(&ctc_group_driver);
{
DBF_TEXT(setup, 3, __FUNCTION__);
unregister_cu3088_discipline(&ctc_group_driver);
- ctc_tty_cleanup();
ctc_unregister_dbf_views();
ctc_pr_info("CTC driver unloaded\n");
}
ctc_unregister_dbf_views();
ctc_pr_info("CTC driver unloaded\n");
}
@@
-3073,10
+3064,8
@@
ctc_init(void)
ctc_pr_crit("ctc_init failed with ctc_register_dbf_views rc = %d\n", ret);
return ret;
}
ctc_pr_crit("ctc_init failed with ctc_register_dbf_views rc = %d\n", ret);
return ret;
}
- ctc_tty_init();
ret = register_cu3088_discipline(&ctc_group_driver);
if (ret) {
ret = register_cu3088_discipline(&ctc_group_driver);
if (ret) {
- ctc_tty_cleanup();
ctc_unregister_dbf_views();
}
return ret;
ctc_unregister_dbf_views();
}
return ret;