diff options
Diffstat (limited to 'drivers/s390/net/lcs.c')
-rw-r--r-- | drivers/s390/net/lcs.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 0f19d540b655..c3b8064a102d 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #define KMSG_COMPONENT "lcs" | 26 | #define KMSG_COMPONENT "lcs" |
27 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 27 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
28 | 28 | ||
29 | #include <linux/kernel_stat.h> | ||
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <linux/if.h> | 31 | #include <linux/if.h> |
31 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
@@ -840,7 +841,7 @@ lcs_notify_lancmd_waiters(struct lcs_card *card, struct lcs_cmd *cmd) | |||
840 | } | 841 | } |
841 | 842 | ||
842 | /** | 843 | /** |
843 | * Emit buffer of a lan comand. | 844 | * Emit buffer of a lan command. |
844 | */ | 845 | */ |
845 | static void | 846 | static void |
846 | lcs_lancmd_timeout(unsigned long data) | 847 | lcs_lancmd_timeout(unsigned long data) |
@@ -1122,7 +1123,7 @@ list_modified: | |||
1122 | list_for_each_entry_safe(ipm, tmp, &card->ipm_list, list){ | 1123 | list_for_each_entry_safe(ipm, tmp, &card->ipm_list, list){ |
1123 | switch (ipm->ipm_state) { | 1124 | switch (ipm->ipm_state) { |
1124 | case LCS_IPM_STATE_SET_REQUIRED: | 1125 | case LCS_IPM_STATE_SET_REQUIRED: |
1125 | /* del from ipm_list so noone else can tamper with | 1126 | /* del from ipm_list so no one else can tamper with |
1126 | * this entry */ | 1127 | * this entry */ |
1127 | list_del_init(&ipm->list); | 1128 | list_del_init(&ipm->list); |
1128 | spin_unlock_irqrestore(&card->ipm_lock, flags); | 1129 | spin_unlock_irqrestore(&card->ipm_lock, flags); |
@@ -1188,7 +1189,8 @@ lcs_remove_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) | |||
1188 | spin_lock_irqsave(&card->ipm_lock, flags); | 1189 | spin_lock_irqsave(&card->ipm_lock, flags); |
1189 | list_for_each(l, &card->ipm_list) { | 1190 | list_for_each(l, &card->ipm_list) { |
1190 | ipm = list_entry(l, struct lcs_ipm_list, list); | 1191 | ipm = list_entry(l, struct lcs_ipm_list, list); |
1191 | for (im4 = in4_dev->mc_list; im4 != NULL; im4 = im4->next) { | 1192 | for (im4 = rcu_dereference(in4_dev->mc_list); |
1193 | im4 != NULL; im4 = rcu_dereference(im4->next_rcu)) { | ||
1192 | lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); | 1194 | lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); |
1193 | if ( (ipm->ipm.ip_addr == im4->multiaddr) && | 1195 | if ( (ipm->ipm.ip_addr == im4->multiaddr) && |
1194 | (memcmp(buf, &ipm->ipm.mac_addr, | 1196 | (memcmp(buf, &ipm->ipm.mac_addr, |
@@ -1233,7 +1235,8 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) | |||
1233 | unsigned long flags; | 1235 | unsigned long flags; |
1234 | 1236 | ||
1235 | LCS_DBF_TEXT(4, trace, "setmclst"); | 1237 | LCS_DBF_TEXT(4, trace, "setmclst"); |
1236 | for (im4 = in4_dev->mc_list; im4; im4 = im4->next) { | 1238 | for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL; |
1239 | im4 = rcu_dereference(im4->next_rcu)) { | ||
1237 | lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); | 1240 | lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); |
1238 | ipm = lcs_check_addr_entry(card, im4, buf); | 1241 | ipm = lcs_check_addr_entry(card, im4, buf); |
1239 | if (ipm != NULL) | 1242 | if (ipm != NULL) |
@@ -1269,10 +1272,10 @@ lcs_register_mc_addresses(void *data) | |||
1269 | in4_dev = in_dev_get(card->dev); | 1272 | in4_dev = in_dev_get(card->dev); |
1270 | if (in4_dev == NULL) | 1273 | if (in4_dev == NULL) |
1271 | goto out; | 1274 | goto out; |
1272 | read_lock(&in4_dev->mc_list_lock); | 1275 | rcu_read_lock(); |
1273 | lcs_remove_mc_addresses(card,in4_dev); | 1276 | lcs_remove_mc_addresses(card,in4_dev); |
1274 | lcs_set_mc_addresses(card, in4_dev); | 1277 | lcs_set_mc_addresses(card, in4_dev); |
1275 | read_unlock(&in4_dev->mc_list_lock); | 1278 | rcu_read_unlock(); |
1276 | in_dev_put(in4_dev); | 1279 | in_dev_put(in4_dev); |
1277 | 1280 | ||
1278 | netif_carrier_off(card->dev); | 1281 | netif_carrier_off(card->dev); |
@@ -1396,6 +1399,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
1396 | int rc, index; | 1399 | int rc, index; |
1397 | int cstat, dstat; | 1400 | int cstat, dstat; |
1398 | 1401 | ||
1402 | kstat_cpu(smp_processor_id()).irqs[IOINT_LCS]++; | ||
1399 | if (lcs_check_irb_error(cdev, irb)) | 1403 | if (lcs_check_irb_error(cdev, irb)) |
1400 | return; | 1404 | return; |
1401 | 1405 | ||
@@ -1479,7 +1483,6 @@ lcs_tasklet(unsigned long data) | |||
1479 | struct lcs_channel *channel; | 1483 | struct lcs_channel *channel; |
1480 | struct lcs_buffer *iob; | 1484 | struct lcs_buffer *iob; |
1481 | int buf_idx; | 1485 | int buf_idx; |
1482 | int rc; | ||
1483 | 1486 | ||
1484 | channel = (struct lcs_channel *) data; | 1487 | channel = (struct lcs_channel *) data; |
1485 | LCS_DBF_TEXT_(5, trace, "tlet%s", dev_name(&channel->ccwdev->dev)); | 1488 | LCS_DBF_TEXT_(5, trace, "tlet%s", dev_name(&channel->ccwdev->dev)); |
@@ -1496,14 +1499,11 @@ lcs_tasklet(unsigned long data) | |||
1496 | channel->buf_idx = buf_idx; | 1499 | channel->buf_idx = buf_idx; |
1497 | 1500 | ||
1498 | if (channel->state == LCS_CH_STATE_STOPPED) | 1501 | if (channel->state == LCS_CH_STATE_STOPPED) |
1499 | // FIXME: what if rc != 0 ?? | 1502 | lcs_start_channel(channel); |
1500 | rc = lcs_start_channel(channel); | ||
1501 | spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); | 1503 | spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); |
1502 | if (channel->state == LCS_CH_STATE_SUSPENDED && | 1504 | if (channel->state == LCS_CH_STATE_SUSPENDED && |
1503 | channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) { | 1505 | channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) |
1504 | // FIXME: what if rc != 0 ?? | 1506 | __lcs_resume_channel(channel); |
1505 | rc = __lcs_resume_channel(channel); | ||
1506 | } | ||
1507 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); | 1507 | spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); |
1508 | 1508 | ||
1509 | /* Something happened on the channel. Wake up waiters. */ | 1509 | /* Something happened on the channel. Wake up waiters. */ |
@@ -2392,8 +2392,10 @@ static struct ccw_device_id lcs_ids[] = { | |||
2392 | MODULE_DEVICE_TABLE(ccw, lcs_ids); | 2392 | MODULE_DEVICE_TABLE(ccw, lcs_ids); |
2393 | 2393 | ||
2394 | static struct ccw_driver lcs_ccw_driver = { | 2394 | static struct ccw_driver lcs_ccw_driver = { |
2395 | .owner = THIS_MODULE, | 2395 | .driver = { |
2396 | .name = "lcs", | 2396 | .owner = THIS_MODULE, |
2397 | .name = "lcs", | ||
2398 | }, | ||
2397 | .ids = lcs_ids, | 2399 | .ids = lcs_ids, |
2398 | .probe = ccwgroup_probe_ccwdev, | 2400 | .probe = ccwgroup_probe_ccwdev, |
2399 | .remove = ccwgroup_remove_ccwdev, | 2401 | .remove = ccwgroup_remove_ccwdev, |
@@ -2403,8 +2405,10 @@ static struct ccw_driver lcs_ccw_driver = { | |||
2403 | * LCS ccwgroup driver registration | 2405 | * LCS ccwgroup driver registration |
2404 | */ | 2406 | */ |
2405 | static struct ccwgroup_driver lcs_group_driver = { | 2407 | static struct ccwgroup_driver lcs_group_driver = { |
2406 | .owner = THIS_MODULE, | 2408 | .driver = { |
2407 | .name = "lcs", | 2409 | .owner = THIS_MODULE, |
2410 | .name = "lcs", | ||
2411 | }, | ||
2408 | .max_slaves = 2, | 2412 | .max_slaves = 2, |
2409 | .driver_id = 0xD3C3E2, | 2413 | .driver_id = 0xD3C3E2, |
2410 | .probe = lcs_probe_device, | 2414 | .probe = lcs_probe_device, |