Loading drivers/s390/net/cu3088.c +5 −5 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <linux/init.h> #include <linux/module.h> #include <linux/err.h> Loading Loading @@ -77,7 +77,7 @@ group_write(struct device_driver *drv, const char *buf, size_t count) int len; if (!(end = strchr(start, delim[i]))) return count; return -EINVAL; len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start + 1); strlcpy (bus_ids[i], start, len); argv[i] = bus_ids[i]; Loading drivers/s390/net/iucv.c +18 −18 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* #define DEBUG */ #include <linux/module.h> Loading Loading @@ -297,7 +297,7 @@ MODULE_LICENSE("GPL"); /* * Debugging stuff *******************************************************************************/ #ifdef DEBUG static int debuglevel = 0; Loading Loading @@ -344,7 +344,7 @@ do { \ /* * Internal functions *******************************************************************************/ /** * print start banner */ Loading drivers/s390/net/lcs.c +173 −172 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ static void lcs_tasklet(unsigned long); static void lcs_start_kernel_thread(struct lcs_card *card); static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *); static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *); static int lcs_recovery(void *ptr); /** * Debug Facility Stuff Loading Loading @@ -429,12 +430,6 @@ lcs_setup_card(struct lcs_card *card) card->tx_buffer = NULL; card->tx_emitted = 0; /* Initialize kernel thread task used for LGW commands. */ INIT_WORK(&card->kernel_thread_starter, (void *)lcs_start_kernel_thread,card); card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; init_waitqueue_head(&card->wait_q); spin_lock_init(&card->lock); spin_lock_init(&card->ipm_lock); Loading Loading @@ -675,8 +670,9 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) int index, rc; LCS_DBF_TEXT(5, trace, "rdybuff"); BUG_ON(buffer->state != BUF_STATE_LOCKED && buffer->state != BUF_STATE_PROCESSED); if (buffer->state != BUF_STATE_LOCKED && buffer->state != BUF_STATE_PROCESSED) BUG(); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); buffer->state = BUF_STATE_READY; index = buffer - channel->iob; Loading @@ -700,7 +696,8 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) int index, prev, next; LCS_DBF_TEXT(5, trace, "prcsbuff"); BUG_ON(buffer->state != BUF_STATE_READY); if (buffer->state != BUF_STATE_READY) BUG(); buffer->state = BUF_STATE_PROCESSED; index = buffer - channel->iob; prev = (index - 1) & (LCS_NUM_BUFFS - 1); Loading Loading @@ -732,8 +729,9 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) unsigned long flags; LCS_DBF_TEXT(5, trace, "relbuff"); BUG_ON(buffer->state != BUF_STATE_LOCKED && buffer->state != BUF_STATE_PROCESSED); if (buffer->state != BUF_STATE_LOCKED && buffer->state != BUF_STATE_PROCESSED) BUG(); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); buffer->state = BUF_STATE_EMPTY; spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); Loading Loading @@ -1147,8 +1145,6 @@ lcs_fix_multicast_list(struct lcs_card *card) list_add_tail(&ipm->list, &card->ipm_list); } spin_unlock_irqrestore(&card->ipm_lock, flags); if (card->state == DEV_STATE_UP) netif_wake_queue(card->dev); } /** Loading Loading @@ -1231,17 +1227,17 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) if (ipm != NULL) continue; /* Address already in list. */ ipm = (struct lcs_ipm_list *) kmalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC); kzalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC); if (ipm == NULL) { PRINT_INFO("Not enough memory to add " "new multicast entry!\n"); break; } memset(ipm, 0, sizeof(struct lcs_ipm_list)); memcpy(&ipm->ipm.mac_addr, buf, LCS_MAC_LENGTH); ipm->ipm.ip_addr = im4->multiaddr; ipm->ipm_state = LCS_IPM_STATE_SET_REQUIRED; spin_lock_irqsave(&card->ipm_lock, flags); LCS_DBF_HEX(2,trace,&ipm->ipm.ip_addr,4); list_add(&ipm->list, &card->ipm_list); spin_unlock_irqrestore(&card->ipm_lock, flags); } Loading Loading @@ -1269,7 +1265,15 @@ lcs_register_mc_addresses(void *data) read_unlock(&in4_dev->mc_list_lock); in_dev_put(in4_dev); netif_carrier_off(card->dev); netif_tx_disable(card->dev); wait_event(card->write.wait_q, (card->write.state != CH_STATE_RUNNING)); lcs_fix_multicast_list(card); if (card->state == DEV_STATE_UP) { netif_carrier_on(card->dev); netif_wake_queue(card->dev); } out: lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD); return 0; Loading Loading @@ -1318,6 +1322,53 @@ lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb) return PTR_ERR(irb); } static int lcs_get_problem(struct ccw_device *cdev, struct irb *irb) { int dstat, cstat; char *sense; sense = (char *) irb->ecw; cstat = irb->scsw.cstat; dstat = irb->scsw.dstat; if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK | SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK | SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) { LCS_DBF_TEXT(2, trace, "CGENCHK"); return 1; } if (dstat & DEV_STAT_UNIT_CHECK) { if (sense[LCS_SENSE_BYTE_1] & LCS_SENSE_RESETTING_EVENT) { LCS_DBF_TEXT(2, trace, "REVIND"); return 1; } if (sense[LCS_SENSE_BYTE_0] & LCS_SENSE_CMD_REJECT) { LCS_DBF_TEXT(2, trace, "CMDREJ"); return 0; } if ((!sense[LCS_SENSE_BYTE_0]) && (!sense[LCS_SENSE_BYTE_1]) && (!sense[LCS_SENSE_BYTE_2]) && (!sense[LCS_SENSE_BYTE_3])) { LCS_DBF_TEXT(2, trace, "ZEROSEN"); return 0; } LCS_DBF_TEXT(2, trace, "DGENCHK"); return 1; } return 0; } void lcs_schedule_recovery(struct lcs_card *card) { LCS_DBF_TEXT(2, trace, "startrec"); if (!lcs_set_thread_start_bit(card, LCS_RECOVERY_THREAD)) schedule_work(&card->kernel_thread_starter); } /** * IRQ Handler for LCS channels Loading @@ -1327,7 +1378,8 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) { struct lcs_card *card; struct lcs_channel *channel; int index; int rc, index; int cstat, dstat; if (lcs_check_irb_error(cdev, irb)) return; Loading @@ -1338,10 +1390,23 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) else channel = &card->write; cstat = irb->scsw.cstat; dstat = irb->scsw.dstat; LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id); LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.cstat, irb->scsw.dstat); LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.fctl, irb->scsw.actl); /* Check for channel and device errors presented */ rc = lcs_get_problem(cdev, irb); if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) { PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n", cdev->dev.bus_id, dstat, cstat); if (rc) { lcs_schedule_recovery(card); wake_up(&card->wait_q); return; } } /* How far in the ccw chain have we processed? */ if ((channel->state != CH_STATE_INIT) && (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) { Loading @@ -1367,7 +1432,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED) /* CCW execution stopped on a suspend bit. */ channel->state = CH_STATE_SUSPENDED; if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) { if (irb->scsw.cc != 0) { ccw_device_halt(channel->ccwdev, (addr_t) channel); Loading @@ -1376,7 +1440,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) /* The channel has been stopped by halt_IO. */ channel->state = CH_STATE_HALTED; } if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { channel->state = CH_STATE_CLEARED; } Loading Loading @@ -1452,7 +1515,7 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) lcs_release_buffer(channel, buffer); card = (struct lcs_card *) ((char *) channel - offsetof(struct lcs_card, write)); if (netif_queue_stopped(card->dev)) if (netif_queue_stopped(card->dev) && netif_carrier_ok(card->dev)) netif_wake_queue(card->dev); spin_lock(&card->lock); card->tx_emitted--; Loading Loading @@ -1488,6 +1551,10 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, card->stats.tx_carrier_errors++; return 0; } if (skb->protocol == htons(ETH_P_IPV6)) { dev_kfree_skb(skb); return 0; } netif_stop_queue(card->dev); spin_lock(&card->lock); if (card->tx_buffer != NULL && Loading Loading @@ -1632,30 +1699,6 @@ lcs_detect(struct lcs_card *card) return rc; } /** * reset card */ static int lcs_resetcard(struct lcs_card *card) { int retries; LCS_DBF_TEXT(2, trace, "rescard"); for (retries = 0; retries < 10; retries++) { if (lcs_detect(card) == 0) { netif_wake_queue(card->dev); card->state = DEV_STATE_UP; PRINT_INFO("LCS device %s successfully restarted!\n", card->dev->name); return 0; } msleep(3000); } PRINT_ERR("Error in Reseting LCS card!\n"); return -EIO; } /** * LCS Stop card */ Loading @@ -1679,111 +1722,6 @@ lcs_stopcard(struct lcs_card *card) return rc; } /** * LGW initiated commands */ static int lcs_lgw_startlan_thread(void *data) { struct lcs_card *card; card = (struct lcs_card *) data; daemonize("lgwstpln"); if (!lcs_do_run_thread(card, LCS_STARTLAN_THREAD)) return 0; LCS_DBF_TEXT(4, trace, "lgwstpln"); if (card->dev) netif_stop_queue(card->dev); if (lcs_startlan(card) == 0) { netif_wake_queue(card->dev); card->state = DEV_STATE_UP; PRINT_INFO("LCS Startlan for device %s succeeded!\n", card->dev->name); } else PRINT_ERR("LCS Startlan for device %s failed!\n", card->dev->name); lcs_clear_thread_running_bit(card, LCS_STARTLAN_THREAD); return 0; } /** * Send startup command initiated by Lan Gateway */ static int lcs_lgw_startup_thread(void *data) { int rc; struct lcs_card *card; card = (struct lcs_card *) data; daemonize("lgwstaln"); if (!lcs_do_run_thread(card, LCS_STARTUP_THREAD)) return 0; LCS_DBF_TEXT(4, trace, "lgwstaln"); if (card->dev) netif_stop_queue(card->dev); rc = lcs_send_startup(card, LCS_INITIATOR_LGW); if (rc != 0) { PRINT_ERR("Startup for LCS device %s initiated " \ "by LGW failed!\nReseting card ...\n", card->dev->name); /* do a card reset */ rc = lcs_resetcard(card); if (rc == 0) goto Done; } rc = lcs_startlan(card); if (rc == 0) { netif_wake_queue(card->dev); card->state = DEV_STATE_UP; } Done: if (rc == 0) PRINT_INFO("LCS Startup for device %s succeeded!\n", card->dev->name); else PRINT_ERR("LCS Startup for device %s failed!\n", card->dev->name); lcs_clear_thread_running_bit(card, LCS_STARTUP_THREAD); return 0; } /** * send stoplan command initiated by Lan Gateway */ static int lcs_lgw_stoplan_thread(void *data) { struct lcs_card *card; int rc; card = (struct lcs_card *) data; daemonize("lgwstop"); if (!lcs_do_run_thread(card, LCS_STOPLAN_THREAD)) return 0; LCS_DBF_TEXT(4, trace, "lgwstop"); if (card->dev) netif_stop_queue(card->dev); if (lcs_send_stoplan(card, LCS_INITIATOR_LGW) == 0) PRINT_INFO("Stoplan for %s initiated by LGW succeeded!\n", card->dev->name); else PRINT_ERR("Stoplan %s initiated by LGW failed!\n", card->dev->name); /*Try to reset the card, stop it on failure */ rc = lcs_resetcard(card); if (rc != 0) rc = lcs_stopcard(card); lcs_clear_thread_running_bit(card, LCS_STOPLAN_THREAD); return rc; } /** * Kernel Thread helper functions for LGW initiated commands */ Loading @@ -1791,15 +1729,12 @@ static void lcs_start_kernel_thread(struct lcs_card *card) { LCS_DBF_TEXT(5, trace, "krnthrd"); if (lcs_do_start_thread(card, LCS_STARTUP_THREAD)) kernel_thread(lcs_lgw_startup_thread, (void *) card, SIGCHLD); if (lcs_do_start_thread(card, LCS_STARTLAN_THREAD)) kernel_thread(lcs_lgw_startlan_thread, (void *) card, SIGCHLD); if (lcs_do_start_thread(card, LCS_STOPLAN_THREAD)) kernel_thread(lcs_lgw_stoplan_thread, (void *) card, SIGCHLD); if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD)) kernel_thread(lcs_recovery, (void *) card, SIGCHLD); #ifdef CONFIG_IP_MULTICAST if (lcs_do_start_thread(card, LCS_SET_MC_THREAD)) kernel_thread(lcs_register_mc_addresses, (void *) card, SIGCHLD); kernel_thread(lcs_register_mc_addresses, (void *) card, SIGCHLD); #endif } Loading @@ -1813,19 +1748,14 @@ lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd) if (cmd->initiator == LCS_INITIATOR_LGW) { switch(cmd->cmd_code) { case LCS_CMD_STARTUP: if (!lcs_set_thread_start_bit(card, LCS_STARTUP_THREAD)) schedule_work(&card->kernel_thread_starter); break; case LCS_CMD_STARTLAN: if (!lcs_set_thread_start_bit(card, LCS_STARTLAN_THREAD)) schedule_work(&card->kernel_thread_starter); lcs_schedule_recovery(card); break; case LCS_CMD_STOPLAN: if (!lcs_set_thread_start_bit(card, LCS_STOPLAN_THREAD)) schedule_work(&card->kernel_thread_starter); PRINT_WARN("Stoplan for %s initiated by LGW.\n", card->dev->name); if (card->dev) netif_carrier_off(card->dev); break; default: PRINT_INFO("UNRECOGNIZED LGW COMMAND\n"); Loading Loading @@ -1941,8 +1871,11 @@ lcs_stop_device(struct net_device *dev) LCS_DBF_TEXT(2, trace, "stopdev"); card = (struct lcs_card *) dev->priv; netif_stop_queue(dev); netif_carrier_off(dev); netif_tx_disable(dev); dev->flags &= ~IFF_UP; wait_event(card->write.wait_q, (card->write.state != CH_STATE_RUNNING)); rc = lcs_stopcard(card); if (rc) PRINT_ERR("Try it again!\n "); Loading @@ -1968,6 +1901,7 @@ lcs_open_device(struct net_device *dev) } else { dev->flags |= IFF_UP; netif_carrier_on(dev); netif_wake_queue(dev); card->state = DEV_STATE_UP; } Loading Loading @@ -2059,10 +1993,31 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store); static ssize_t lcs_dev_recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct lcs_card *card = dev->driver_data; char *tmp; int i; if (!card) return -EINVAL; if (card->state != DEV_STATE_UP) return -EPERM; i = simple_strtoul(buf, &tmp, 16); if (i == 1) lcs_schedule_recovery(card); return count; } static DEVICE_ATTR(recover, 0200, NULL, lcs_dev_recover_store); static struct attribute * lcs_attrs[] = { &dev_attr_portno.attr, &dev_attr_type.attr, &dev_attr_lancmd_timeout.attr, &dev_attr_recover.attr, NULL, }; Loading Loading @@ -2099,6 +2054,12 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) ccwgdev->dev.driver_data = card; ccwgdev->cdev[0]->handler = lcs_irq; ccwgdev->cdev[1]->handler = lcs_irq; card->gdev = ccwgdev; INIT_WORK(&card->kernel_thread_starter, (void *) lcs_start_kernel_thread, card); card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; return 0; } Loading Loading @@ -2200,6 +2161,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) if (recover_state == DEV_STATE_RECOVER) { lcs_set_multicast_list(card->dev); card->dev->flags |= IFF_UP; netif_carrier_on(card->dev); netif_wake_queue(card->dev); card->state = DEV_STATE_UP; } else { Loading Loading @@ -2229,7 +2191,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) * lcs_shutdown_device, called when setting the group device offline. */ static int lcs_shutdown_device(struct ccwgroup_device *ccwgdev) __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode) { struct lcs_card *card; enum lcs_dev_states recover_state; Loading @@ -2239,9 +2201,11 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev) card = (struct lcs_card *)ccwgdev->dev.driver_data; if (!card) return -ENODEV; if (recovery_mode == 0) { lcs_set_allowed_threads(card, 0); if (lcs_wait_for_threads(card, LCS_SET_MC_THREAD)) return -ERESTARTSYS; } LCS_DBF_HEX(3, setup, &card, sizeof(void*)); recover_state = card->state; Loading @@ -2256,6 +2220,43 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev) return 0; } static int lcs_shutdown_device(struct ccwgroup_device *ccwgdev) { return __lcs_shutdown_device(ccwgdev, 0); } /** * drive lcs recovery after startup and startlan initiated by Lan Gateway */ static int lcs_recovery(void *ptr) { struct lcs_card *card; struct ccwgroup_device *gdev; int rc; card = (struct lcs_card *) ptr; daemonize("lcs_recover"); LCS_DBF_TEXT(4, trace, "recover1"); if (!lcs_do_run_thread(card, LCS_RECOVERY_THREAD)) return 0; LCS_DBF_TEXT(4, trace, "recover2"); gdev = card->gdev; PRINT_WARN("Recovery of device %s started...\n", gdev->dev.bus_id); rc = __lcs_shutdown_device(gdev, 1); rc = lcs_new_device(gdev); if (!rc) PRINT_INFO("Device %s successfully recovered!\n", card->dev->name); else PRINT_INFO("Device %s could not be recovered!\n", card->dev->name); lcs_clear_thread_running_bit(card, LCS_RECOVERY_THREAD); return 0; } /** * lcs_remove_device, free buffers and card */ Loading drivers/s390/net/lcs.h +9 −5 Original line number Diff line number Diff line Loading @@ -73,13 +73,17 @@ do { \ /** * LCS sense byte definitions */ #define LCS_SENSE_BYTE_0 0 #define LCS_SENSE_BYTE_1 1 #define LCS_SENSE_BYTE_2 2 #define LCS_SENSE_BYTE_3 3 #define LCS_SENSE_INTERFACE_DISCONNECT 0x01 #define LCS_SENSE_EQUIPMENT_CHECK 0x10 #define LCS_SENSE_BUS_OUT_CHECK 0x20 #define LCS_SENSE_INTERVENTION_REQUIRED 0x40 #define LCS_SENSE_CMD_REJECT 0x80 #define LCS_SENSE_RESETTING_EVENT 0x0080 #define LCS_SENSE_DEVICE_ONLINE 0x0020 #define LCS_SENSE_RESETTING_EVENT 0x80 #define LCS_SENSE_DEVICE_ONLINE 0x20 /** * LCS packet type definitions Loading Loading @@ -152,10 +156,9 @@ enum lcs_dev_states { enum lcs_threads { LCS_SET_MC_THREAD = 1, LCS_STARTLAN_THREAD = 2, LCS_STOPLAN_THREAD = 4, LCS_STARTUP_THREAD = 8, LCS_RECOVERY_THREAD = 2, }; /** * LCS struct declarations */ Loading Loading @@ -286,6 +289,7 @@ struct lcs_card { struct net_device_stats stats; unsigned short (*lan_type_trans)(struct sk_buff *skb, struct net_device *dev); struct ccwgroup_device *gdev; struct lcs_channel read; struct lcs_channel write; struct lcs_buffer *tx_buffer; Loading drivers/s390/net/netiucv.c +18 −18 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #undef DEBUG #include <linux/module.h> Loading Loading @@ -65,7 +65,7 @@ MODULE_AUTHOR ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); #define PRINTK_HEADER " iucv: " /* for debugging */ static struct device_driver netiucv_driver = { Loading Loading @@ -202,7 +202,7 @@ netiucv_printname(char *name) *p = '\0'; return tmp; } /** * States of the interface statemachine. */ Loading Loading @@ -244,7 +244,7 @@ static const char *dev_event_names[] = { "Connection up", "Connection down", }; /** * Events of the connection statemachine */ Loading Loading @@ -364,7 +364,7 @@ static const char *conn_state_names[] = { "Connect error", }; /** * Debug Facility Stuff */ Loading Loading @@ -516,7 +516,7 @@ static void fsm_action_nop(fsm_instance *fi, int event, void *arg) { } /** * Actions of the connection statemachine *****************************************************************************/ Loading Loading @@ -993,7 +993,7 @@ static const fsm_node conn_fsm[] = { static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); /** * Actions for interface - statemachine. *****************************************************************************/ Loading Loading @@ -1220,7 +1220,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) { return rc; } /** * Interface API for upper network layers *****************************************************************************/ Loading Loading
drivers/s390/net/cu3088.c +5 −5 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <linux/init.h> #include <linux/module.h> #include <linux/err.h> Loading Loading @@ -77,7 +77,7 @@ group_write(struct device_driver *drv, const char *buf, size_t count) int len; if (!(end = strchr(start, delim[i]))) return count; return -EINVAL; len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start + 1); strlcpy (bus_ids[i], start, len); argv[i] = bus_ids[i]; Loading
drivers/s390/net/iucv.c +18 −18 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* #define DEBUG */ #include <linux/module.h> Loading Loading @@ -297,7 +297,7 @@ MODULE_LICENSE("GPL"); /* * Debugging stuff *******************************************************************************/ #ifdef DEBUG static int debuglevel = 0; Loading Loading @@ -344,7 +344,7 @@ do { \ /* * Internal functions *******************************************************************************/ /** * print start banner */ Loading
drivers/s390/net/lcs.c +173 −172 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ static void lcs_tasklet(unsigned long); static void lcs_start_kernel_thread(struct lcs_card *card); static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *); static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *); static int lcs_recovery(void *ptr); /** * Debug Facility Stuff Loading Loading @@ -429,12 +430,6 @@ lcs_setup_card(struct lcs_card *card) card->tx_buffer = NULL; card->tx_emitted = 0; /* Initialize kernel thread task used for LGW commands. */ INIT_WORK(&card->kernel_thread_starter, (void *)lcs_start_kernel_thread,card); card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; init_waitqueue_head(&card->wait_q); spin_lock_init(&card->lock); spin_lock_init(&card->ipm_lock); Loading Loading @@ -675,8 +670,9 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) int index, rc; LCS_DBF_TEXT(5, trace, "rdybuff"); BUG_ON(buffer->state != BUF_STATE_LOCKED && buffer->state != BUF_STATE_PROCESSED); if (buffer->state != BUF_STATE_LOCKED && buffer->state != BUF_STATE_PROCESSED) BUG(); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); buffer->state = BUF_STATE_READY; index = buffer - channel->iob; Loading @@ -700,7 +696,8 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) int index, prev, next; LCS_DBF_TEXT(5, trace, "prcsbuff"); BUG_ON(buffer->state != BUF_STATE_READY); if (buffer->state != BUF_STATE_READY) BUG(); buffer->state = BUF_STATE_PROCESSED; index = buffer - channel->iob; prev = (index - 1) & (LCS_NUM_BUFFS - 1); Loading Loading @@ -732,8 +729,9 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) unsigned long flags; LCS_DBF_TEXT(5, trace, "relbuff"); BUG_ON(buffer->state != BUF_STATE_LOCKED && buffer->state != BUF_STATE_PROCESSED); if (buffer->state != BUF_STATE_LOCKED && buffer->state != BUF_STATE_PROCESSED) BUG(); spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); buffer->state = BUF_STATE_EMPTY; spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); Loading Loading @@ -1147,8 +1145,6 @@ lcs_fix_multicast_list(struct lcs_card *card) list_add_tail(&ipm->list, &card->ipm_list); } spin_unlock_irqrestore(&card->ipm_lock, flags); if (card->state == DEV_STATE_UP) netif_wake_queue(card->dev); } /** Loading Loading @@ -1231,17 +1227,17 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) if (ipm != NULL) continue; /* Address already in list. */ ipm = (struct lcs_ipm_list *) kmalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC); kzalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC); if (ipm == NULL) { PRINT_INFO("Not enough memory to add " "new multicast entry!\n"); break; } memset(ipm, 0, sizeof(struct lcs_ipm_list)); memcpy(&ipm->ipm.mac_addr, buf, LCS_MAC_LENGTH); ipm->ipm.ip_addr = im4->multiaddr; ipm->ipm_state = LCS_IPM_STATE_SET_REQUIRED; spin_lock_irqsave(&card->ipm_lock, flags); LCS_DBF_HEX(2,trace,&ipm->ipm.ip_addr,4); list_add(&ipm->list, &card->ipm_list); spin_unlock_irqrestore(&card->ipm_lock, flags); } Loading Loading @@ -1269,7 +1265,15 @@ lcs_register_mc_addresses(void *data) read_unlock(&in4_dev->mc_list_lock); in_dev_put(in4_dev); netif_carrier_off(card->dev); netif_tx_disable(card->dev); wait_event(card->write.wait_q, (card->write.state != CH_STATE_RUNNING)); lcs_fix_multicast_list(card); if (card->state == DEV_STATE_UP) { netif_carrier_on(card->dev); netif_wake_queue(card->dev); } out: lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD); return 0; Loading Loading @@ -1318,6 +1322,53 @@ lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb) return PTR_ERR(irb); } static int lcs_get_problem(struct ccw_device *cdev, struct irb *irb) { int dstat, cstat; char *sense; sense = (char *) irb->ecw; cstat = irb->scsw.cstat; dstat = irb->scsw.dstat; if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK | SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK | SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) { LCS_DBF_TEXT(2, trace, "CGENCHK"); return 1; } if (dstat & DEV_STAT_UNIT_CHECK) { if (sense[LCS_SENSE_BYTE_1] & LCS_SENSE_RESETTING_EVENT) { LCS_DBF_TEXT(2, trace, "REVIND"); return 1; } if (sense[LCS_SENSE_BYTE_0] & LCS_SENSE_CMD_REJECT) { LCS_DBF_TEXT(2, trace, "CMDREJ"); return 0; } if ((!sense[LCS_SENSE_BYTE_0]) && (!sense[LCS_SENSE_BYTE_1]) && (!sense[LCS_SENSE_BYTE_2]) && (!sense[LCS_SENSE_BYTE_3])) { LCS_DBF_TEXT(2, trace, "ZEROSEN"); return 0; } LCS_DBF_TEXT(2, trace, "DGENCHK"); return 1; } return 0; } void lcs_schedule_recovery(struct lcs_card *card) { LCS_DBF_TEXT(2, trace, "startrec"); if (!lcs_set_thread_start_bit(card, LCS_RECOVERY_THREAD)) schedule_work(&card->kernel_thread_starter); } /** * IRQ Handler for LCS channels Loading @@ -1327,7 +1378,8 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) { struct lcs_card *card; struct lcs_channel *channel; int index; int rc, index; int cstat, dstat; if (lcs_check_irb_error(cdev, irb)) return; Loading @@ -1338,10 +1390,23 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) else channel = &card->write; cstat = irb->scsw.cstat; dstat = irb->scsw.dstat; LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id); LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.cstat, irb->scsw.dstat); LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.fctl, irb->scsw.actl); /* Check for channel and device errors presented */ rc = lcs_get_problem(cdev, irb); if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) { PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n", cdev->dev.bus_id, dstat, cstat); if (rc) { lcs_schedule_recovery(card); wake_up(&card->wait_q); return; } } /* How far in the ccw chain have we processed? */ if ((channel->state != CH_STATE_INIT) && (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) { Loading @@ -1367,7 +1432,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED) /* CCW execution stopped on a suspend bit. */ channel->state = CH_STATE_SUSPENDED; if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) { if (irb->scsw.cc != 0) { ccw_device_halt(channel->ccwdev, (addr_t) channel); Loading @@ -1376,7 +1440,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) /* The channel has been stopped by halt_IO. */ channel->state = CH_STATE_HALTED; } if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { channel->state = CH_STATE_CLEARED; } Loading Loading @@ -1452,7 +1515,7 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) lcs_release_buffer(channel, buffer); card = (struct lcs_card *) ((char *) channel - offsetof(struct lcs_card, write)); if (netif_queue_stopped(card->dev)) if (netif_queue_stopped(card->dev) && netif_carrier_ok(card->dev)) netif_wake_queue(card->dev); spin_lock(&card->lock); card->tx_emitted--; Loading Loading @@ -1488,6 +1551,10 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, card->stats.tx_carrier_errors++; return 0; } if (skb->protocol == htons(ETH_P_IPV6)) { dev_kfree_skb(skb); return 0; } netif_stop_queue(card->dev); spin_lock(&card->lock); if (card->tx_buffer != NULL && Loading Loading @@ -1632,30 +1699,6 @@ lcs_detect(struct lcs_card *card) return rc; } /** * reset card */ static int lcs_resetcard(struct lcs_card *card) { int retries; LCS_DBF_TEXT(2, trace, "rescard"); for (retries = 0; retries < 10; retries++) { if (lcs_detect(card) == 0) { netif_wake_queue(card->dev); card->state = DEV_STATE_UP; PRINT_INFO("LCS device %s successfully restarted!\n", card->dev->name); return 0; } msleep(3000); } PRINT_ERR("Error in Reseting LCS card!\n"); return -EIO; } /** * LCS Stop card */ Loading @@ -1679,111 +1722,6 @@ lcs_stopcard(struct lcs_card *card) return rc; } /** * LGW initiated commands */ static int lcs_lgw_startlan_thread(void *data) { struct lcs_card *card; card = (struct lcs_card *) data; daemonize("lgwstpln"); if (!lcs_do_run_thread(card, LCS_STARTLAN_THREAD)) return 0; LCS_DBF_TEXT(4, trace, "lgwstpln"); if (card->dev) netif_stop_queue(card->dev); if (lcs_startlan(card) == 0) { netif_wake_queue(card->dev); card->state = DEV_STATE_UP; PRINT_INFO("LCS Startlan for device %s succeeded!\n", card->dev->name); } else PRINT_ERR("LCS Startlan for device %s failed!\n", card->dev->name); lcs_clear_thread_running_bit(card, LCS_STARTLAN_THREAD); return 0; } /** * Send startup command initiated by Lan Gateway */ static int lcs_lgw_startup_thread(void *data) { int rc; struct lcs_card *card; card = (struct lcs_card *) data; daemonize("lgwstaln"); if (!lcs_do_run_thread(card, LCS_STARTUP_THREAD)) return 0; LCS_DBF_TEXT(4, trace, "lgwstaln"); if (card->dev) netif_stop_queue(card->dev); rc = lcs_send_startup(card, LCS_INITIATOR_LGW); if (rc != 0) { PRINT_ERR("Startup for LCS device %s initiated " \ "by LGW failed!\nReseting card ...\n", card->dev->name); /* do a card reset */ rc = lcs_resetcard(card); if (rc == 0) goto Done; } rc = lcs_startlan(card); if (rc == 0) { netif_wake_queue(card->dev); card->state = DEV_STATE_UP; } Done: if (rc == 0) PRINT_INFO("LCS Startup for device %s succeeded!\n", card->dev->name); else PRINT_ERR("LCS Startup for device %s failed!\n", card->dev->name); lcs_clear_thread_running_bit(card, LCS_STARTUP_THREAD); return 0; } /** * send stoplan command initiated by Lan Gateway */ static int lcs_lgw_stoplan_thread(void *data) { struct lcs_card *card; int rc; card = (struct lcs_card *) data; daemonize("lgwstop"); if (!lcs_do_run_thread(card, LCS_STOPLAN_THREAD)) return 0; LCS_DBF_TEXT(4, trace, "lgwstop"); if (card->dev) netif_stop_queue(card->dev); if (lcs_send_stoplan(card, LCS_INITIATOR_LGW) == 0) PRINT_INFO("Stoplan for %s initiated by LGW succeeded!\n", card->dev->name); else PRINT_ERR("Stoplan %s initiated by LGW failed!\n", card->dev->name); /*Try to reset the card, stop it on failure */ rc = lcs_resetcard(card); if (rc != 0) rc = lcs_stopcard(card); lcs_clear_thread_running_bit(card, LCS_STOPLAN_THREAD); return rc; } /** * Kernel Thread helper functions for LGW initiated commands */ Loading @@ -1791,15 +1729,12 @@ static void lcs_start_kernel_thread(struct lcs_card *card) { LCS_DBF_TEXT(5, trace, "krnthrd"); if (lcs_do_start_thread(card, LCS_STARTUP_THREAD)) kernel_thread(lcs_lgw_startup_thread, (void *) card, SIGCHLD); if (lcs_do_start_thread(card, LCS_STARTLAN_THREAD)) kernel_thread(lcs_lgw_startlan_thread, (void *) card, SIGCHLD); if (lcs_do_start_thread(card, LCS_STOPLAN_THREAD)) kernel_thread(lcs_lgw_stoplan_thread, (void *) card, SIGCHLD); if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD)) kernel_thread(lcs_recovery, (void *) card, SIGCHLD); #ifdef CONFIG_IP_MULTICAST if (lcs_do_start_thread(card, LCS_SET_MC_THREAD)) kernel_thread(lcs_register_mc_addresses, (void *) card, SIGCHLD); kernel_thread(lcs_register_mc_addresses, (void *) card, SIGCHLD); #endif } Loading @@ -1813,19 +1748,14 @@ lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd) if (cmd->initiator == LCS_INITIATOR_LGW) { switch(cmd->cmd_code) { case LCS_CMD_STARTUP: if (!lcs_set_thread_start_bit(card, LCS_STARTUP_THREAD)) schedule_work(&card->kernel_thread_starter); break; case LCS_CMD_STARTLAN: if (!lcs_set_thread_start_bit(card, LCS_STARTLAN_THREAD)) schedule_work(&card->kernel_thread_starter); lcs_schedule_recovery(card); break; case LCS_CMD_STOPLAN: if (!lcs_set_thread_start_bit(card, LCS_STOPLAN_THREAD)) schedule_work(&card->kernel_thread_starter); PRINT_WARN("Stoplan for %s initiated by LGW.\n", card->dev->name); if (card->dev) netif_carrier_off(card->dev); break; default: PRINT_INFO("UNRECOGNIZED LGW COMMAND\n"); Loading Loading @@ -1941,8 +1871,11 @@ lcs_stop_device(struct net_device *dev) LCS_DBF_TEXT(2, trace, "stopdev"); card = (struct lcs_card *) dev->priv; netif_stop_queue(dev); netif_carrier_off(dev); netif_tx_disable(dev); dev->flags &= ~IFF_UP; wait_event(card->write.wait_q, (card->write.state != CH_STATE_RUNNING)); rc = lcs_stopcard(card); if (rc) PRINT_ERR("Try it again!\n "); Loading @@ -1968,6 +1901,7 @@ lcs_open_device(struct net_device *dev) } else { dev->flags |= IFF_UP; netif_carrier_on(dev); netif_wake_queue(dev); card->state = DEV_STATE_UP; } Loading Loading @@ -2059,10 +1993,31 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store); static ssize_t lcs_dev_recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct lcs_card *card = dev->driver_data; char *tmp; int i; if (!card) return -EINVAL; if (card->state != DEV_STATE_UP) return -EPERM; i = simple_strtoul(buf, &tmp, 16); if (i == 1) lcs_schedule_recovery(card); return count; } static DEVICE_ATTR(recover, 0200, NULL, lcs_dev_recover_store); static struct attribute * lcs_attrs[] = { &dev_attr_portno.attr, &dev_attr_type.attr, &dev_attr_lancmd_timeout.attr, &dev_attr_recover.attr, NULL, }; Loading Loading @@ -2099,6 +2054,12 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) ccwgdev->dev.driver_data = card; ccwgdev->cdev[0]->handler = lcs_irq; ccwgdev->cdev[1]->handler = lcs_irq; card->gdev = ccwgdev; INIT_WORK(&card->kernel_thread_starter, (void *) lcs_start_kernel_thread, card); card->thread_start_mask = 0; card->thread_allowed_mask = 0; card->thread_running_mask = 0; return 0; } Loading Loading @@ -2200,6 +2161,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) if (recover_state == DEV_STATE_RECOVER) { lcs_set_multicast_list(card->dev); card->dev->flags |= IFF_UP; netif_carrier_on(card->dev); netif_wake_queue(card->dev); card->state = DEV_STATE_UP; } else { Loading Loading @@ -2229,7 +2191,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) * lcs_shutdown_device, called when setting the group device offline. */ static int lcs_shutdown_device(struct ccwgroup_device *ccwgdev) __lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode) { struct lcs_card *card; enum lcs_dev_states recover_state; Loading @@ -2239,9 +2201,11 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev) card = (struct lcs_card *)ccwgdev->dev.driver_data; if (!card) return -ENODEV; if (recovery_mode == 0) { lcs_set_allowed_threads(card, 0); if (lcs_wait_for_threads(card, LCS_SET_MC_THREAD)) return -ERESTARTSYS; } LCS_DBF_HEX(3, setup, &card, sizeof(void*)); recover_state = card->state; Loading @@ -2256,6 +2220,43 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev) return 0; } static int lcs_shutdown_device(struct ccwgroup_device *ccwgdev) { return __lcs_shutdown_device(ccwgdev, 0); } /** * drive lcs recovery after startup and startlan initiated by Lan Gateway */ static int lcs_recovery(void *ptr) { struct lcs_card *card; struct ccwgroup_device *gdev; int rc; card = (struct lcs_card *) ptr; daemonize("lcs_recover"); LCS_DBF_TEXT(4, trace, "recover1"); if (!lcs_do_run_thread(card, LCS_RECOVERY_THREAD)) return 0; LCS_DBF_TEXT(4, trace, "recover2"); gdev = card->gdev; PRINT_WARN("Recovery of device %s started...\n", gdev->dev.bus_id); rc = __lcs_shutdown_device(gdev, 1); rc = lcs_new_device(gdev); if (!rc) PRINT_INFO("Device %s successfully recovered!\n", card->dev->name); else PRINT_INFO("Device %s could not be recovered!\n", card->dev->name); lcs_clear_thread_running_bit(card, LCS_RECOVERY_THREAD); return 0; } /** * lcs_remove_device, free buffers and card */ Loading
drivers/s390/net/lcs.h +9 −5 Original line number Diff line number Diff line Loading @@ -73,13 +73,17 @@ do { \ /** * LCS sense byte definitions */ #define LCS_SENSE_BYTE_0 0 #define LCS_SENSE_BYTE_1 1 #define LCS_SENSE_BYTE_2 2 #define LCS_SENSE_BYTE_3 3 #define LCS_SENSE_INTERFACE_DISCONNECT 0x01 #define LCS_SENSE_EQUIPMENT_CHECK 0x10 #define LCS_SENSE_BUS_OUT_CHECK 0x20 #define LCS_SENSE_INTERVENTION_REQUIRED 0x40 #define LCS_SENSE_CMD_REJECT 0x80 #define LCS_SENSE_RESETTING_EVENT 0x0080 #define LCS_SENSE_DEVICE_ONLINE 0x0020 #define LCS_SENSE_RESETTING_EVENT 0x80 #define LCS_SENSE_DEVICE_ONLINE 0x20 /** * LCS packet type definitions Loading Loading @@ -152,10 +156,9 @@ enum lcs_dev_states { enum lcs_threads { LCS_SET_MC_THREAD = 1, LCS_STARTLAN_THREAD = 2, LCS_STOPLAN_THREAD = 4, LCS_STARTUP_THREAD = 8, LCS_RECOVERY_THREAD = 2, }; /** * LCS struct declarations */ Loading Loading @@ -286,6 +289,7 @@ struct lcs_card { struct net_device_stats stats; unsigned short (*lan_type_trans)(struct sk_buff *skb, struct net_device *dev); struct ccwgroup_device *gdev; struct lcs_channel read; struct lcs_channel write; struct lcs_buffer *tx_buffer; Loading
drivers/s390/net/netiucv.c +18 −18 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #undef DEBUG #include <linux/module.h> Loading Loading @@ -65,7 +65,7 @@ MODULE_AUTHOR ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); #define PRINTK_HEADER " iucv: " /* for debugging */ static struct device_driver netiucv_driver = { Loading Loading @@ -202,7 +202,7 @@ netiucv_printname(char *name) *p = '\0'; return tmp; } /** * States of the interface statemachine. */ Loading Loading @@ -244,7 +244,7 @@ static const char *dev_event_names[] = { "Connection up", "Connection down", }; /** * Events of the connection statemachine */ Loading Loading @@ -364,7 +364,7 @@ static const char *conn_state_names[] = { "Connect error", }; /** * Debug Facility Stuff */ Loading Loading @@ -516,7 +516,7 @@ static void fsm_action_nop(fsm_instance *fi, int event, void *arg) { } /** * Actions of the connection statemachine *****************************************************************************/ Loading Loading @@ -993,7 +993,7 @@ static const fsm_node conn_fsm[] = { static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); /** * Actions for interface - statemachine. *****************************************************************************/ Loading Loading @@ -1220,7 +1220,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) { return rc; } /** * Interface API for upper network layers *****************************************************************************/ Loading