···11/*22 *33- * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.4 $)33+ * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $)44 *55 * CTC / ESCON network driver - s390 dbf exploit.66 *···99 * Author(s): Original Code written by1010 * Peter Tiedemann (ptiedem@de.ibm.com)1111 *1212- * $Revision: 1.4 $ $Date: 2004/10/15 09:26:58 $1212+ * $Revision: 1.5 $ $Date: 2005/02/27 19:46:44 $1313 *1414 * This program is free software; you can redistribute it and/or modify1515 * it under the terms of the GNU General Public License as published by···2525 * along with this program; if not, write to the Free Software2626 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2727 */2828-2828+#ifndef _CTCDBUG_H_2929+#define _CTCDBUG_H_29303031#include <asm/debug.h>3232+#include "ctcmain.h"3133/**3234 * Debug Facility stuff3335 */···4341#define CTC_DBF_DATA_LEN 1284442#define CTC_DBF_DATA_INDEX 34543#define CTC_DBF_DATA_NR_AREAS 14646-#define CTC_DBF_DATA_LEVEL 24444+#define CTC_DBF_DATA_LEVEL 347454846#define CTC_DBF_TRACE_NAME "ctc_trace"4947#define CTC_DBF_TRACE_LEN 16···123121 printk("\n");124122}125123124124+125125+#endif
+207-411
drivers/s390/net/ctcmain.c
···11/*22- * $Id: ctcmain.c,v 1.72 2005/03/17 10:51:52 ptiedem Exp $22+ * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $33 *44 * CTC / ESCON network driver55 *···3737 * along with this program; if not, write to the Free Software3838 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.3939 *4040- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.72 $4040+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $4141 *4242 */43434444#undef DEBUG4545-4645#include <linux/module.h>4746#include <linux/init.h>4847#include <linux/kernel.h>···7374#include "ctctty.h"7475#include "fsm.h"7576#include "cu3088.h"7777+7678#include "ctcdbug.h"7979+#include "ctcmain.h"77807881MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");7982MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver");8083MODULE_LICENSE("GPL");8181-8282-/**8383- * CCW commands, used in this driver.8484- */8585-#define CCW_CMD_WRITE 0x018686-#define CCW_CMD_READ 0x028787-#define CCW_CMD_SET_EXTENDED 0xc38888-#define CCW_CMD_PREPARE 0xe38989-9090-#define CTC_PROTO_S390 09191-#define CTC_PROTO_LINUX 19292-#define CTC_PROTO_LINUX_TTY 29393-#define CTC_PROTO_OS390 39494-#define CTC_PROTO_MAX 39595-9696-#define CTC_BUFSIZE_LIMIT 655359797-#define CTC_BUFSIZE_DEFAULT 327689898-9999-#define CTC_TIMEOUT_5SEC 5000100100-101101-#define CTC_INITIAL_BLOCKLEN 2102102-103103-#define READ 0104104-#define WRITE 1105105-106106-#define CTC_ID_SIZE BUS_ID_SIZE+3107107-108108-109109-struct ctc_profile {110110- unsigned long maxmulti;111111- unsigned long maxcqueue;112112- unsigned long doios_single;113113- unsigned long doios_multi;114114- unsigned long txlen;115115- unsigned long tx_time;116116- struct timespec send_stamp;117117-};118118-119119-/**120120- * Definition of one channel121121- */122122-struct channel {123123-124124- /**125125- * Pointer to next channel in list.126126- */127127- struct channel *next;128128- char id[CTC_ID_SIZE];129129- struct ccw_device *cdev;130130-131131- /**132132- * Type of this channel.133133- * CTC/A or Escon for valid channels.134134- */135135- enum channel_types type;136136-137137- /**138138- * Misc. flags. See CHANNEL_FLAGS_... below139139- */140140- __u32 flags;141141-142142- /**143143- * The protocol of this channel144144- */145145- __u16 protocol;146146-147147- /**148148- * I/O and irq related stuff149149- */150150- struct ccw1 *ccw;151151- struct irb *irb;152152-153153- /**154154- * RX/TX buffer size155155- */156156- int max_bufsize;157157-158158- /**159159- * Transmit/Receive buffer.160160- */161161- struct sk_buff *trans_skb;162162-163163- /**164164- * Universal I/O queue.165165- */166166- struct sk_buff_head io_queue;167167-168168- /**169169- * TX queue for collecting skb's during busy.170170- */171171- struct sk_buff_head collect_queue;172172-173173- /**174174- * Amount of data in collect_queue.175175- */176176- int collect_len;177177-178178- /**179179- * spinlock for collect_queue and collect_len180180- */181181- spinlock_t collect_lock;182182-183183- /**184184- * Timer for detecting unresposive185185- * I/O operations.186186- */187187- fsm_timer timer;188188-189189- /**190190- * Retry counter for misc. operations.191191- */192192- int retry;193193-194194- /**195195- * The finite state machine of this channel196196- */197197- fsm_instance *fsm;198198-199199- /**200200- * The corresponding net_device this channel201201- * belongs to.202202- */203203- struct net_device *netdev;204204-205205- struct ctc_profile prof;206206-207207- unsigned char *trans_skb_data;208208-209209- __u16 logflags;210210-};211211-212212-#define CHANNEL_FLAGS_READ 0213213-#define CHANNEL_FLAGS_WRITE 1214214-#define CHANNEL_FLAGS_INUSE 2215215-#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4216216-#define CHANNEL_FLAGS_FAILED 8217217-#define CHANNEL_FLAGS_WAITIRQ 16218218-#define CHANNEL_FLAGS_RWMASK 1219219-#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)220220-221221-#define LOG_FLAG_ILLEGALPKT 1222222-#define LOG_FLAG_ILLEGALSIZE 2223223-#define LOG_FLAG_OVERRUN 4224224-#define LOG_FLAG_NOMEM 8225225-226226-#define CTC_LOGLEVEL_INFO 1227227-#define CTC_LOGLEVEL_NOTICE 2228228-#define CTC_LOGLEVEL_WARN 4229229-#define CTC_LOGLEVEL_EMERG 8230230-#define CTC_LOGLEVEL_ERR 16231231-#define CTC_LOGLEVEL_DEBUG 32232232-#define CTC_LOGLEVEL_CRIT 64233233-234234-#define CTC_LOGLEVEL_DEFAULT \235235-(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)236236-237237-#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1)238238-239239-static int loglevel = CTC_LOGLEVEL_DEFAULT;240240-241241-#define ctc_pr_debug(fmt, arg...) \242242-do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0)243243-244244-#define ctc_pr_info(fmt, arg...) \245245-do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0)246246-247247-#define ctc_pr_notice(fmt, arg...) \248248-do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0)249249-250250-#define ctc_pr_warn(fmt, arg...) \251251-do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0)252252-253253-#define ctc_pr_emerg(fmt, arg...) \254254-do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0)255255-256256-#define ctc_pr_err(fmt, arg...) \257257-do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0)258258-259259-#define ctc_pr_crit(fmt, arg...) \260260-do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0)261261-262262-/**263263- * Linked list of all detected channels.264264- */265265-static struct channel *channels = NULL;266266-267267-struct ctc_priv {268268- struct net_device_stats stats;269269- unsigned long tbusy;270270- /**271271- * The finite state machine of this interface.272272- */273273- fsm_instance *fsm;274274- /**275275- * The protocol of this device276276- */277277- __u16 protocol;278278- /**279279- * Timer for restarting after I/O Errors280280- */281281- fsm_timer restart_timer;282282-283283- int buffer_size;284284-285285- struct channel *channel[2];286286-};287287-288288-/**289289- * Definition of our link level header.290290- */291291-struct ll_header {292292- __u16 length;293293- __u16 type;294294- __u16 unused;295295-};296296-#define LL_HEADER_LENGTH (sizeof(struct ll_header))297297-298298-/**299299- * Compatibility macros for busy handling300300- * of network devices.301301- */302302-static __inline__ void303303-ctc_clear_busy(struct net_device * dev)304304-{305305- clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));306306- if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)307307- netif_wake_queue(dev);308308-}309309-310310-static __inline__ int311311-ctc_test_and_set_busy(struct net_device * dev)312312-{313313- if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)314314- netif_stop_queue(dev);315315- return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);316316-}317317-318318-/**319319- * Print Banner.320320- */321321-static void322322-print_banner(void)323323-{324324- static int printed = 0;325325- char vbuf[] = "$Revision: 1.72 $";326326- char *version = vbuf;327327-328328- if (printed)329329- return;330330- if ((version = strchr(version, ':'))) {331331- char *p = strchr(version + 1, '$');332332- if (p)333333- *p = '\0';334334- } else335335- version = " ??? ";336336- printk(KERN_INFO "CTC driver Version%s"337337-#ifdef DEBUG338338- " (DEBUG-VERSION, " __DATE__ __TIME__ ")"339339-#endif340340- " initialized\n", version);341341- printed = 1;342342-}343343-344344-/**345345- * Return type of a detected device.346346- */347347-static enum channel_types348348-get_channel_type(struct ccw_device_id *id)349349-{350350- enum channel_types type = (enum channel_types) id->driver_info;351351-352352- if (type == channel_type_ficon)353353- type = channel_type_escon;354354-355355- return type;356356-}357357-35884/**35985 * States of the interface statemachine.36086 */···95371 /**96372 * MUST be always the last element!!97373 */9898- NR_DEV_STATES374374+ CTC_NR_DEV_STATES99375};100376101377static const char *dev_state_names[] = {···123399 /**124400 * MUST be always the last element!!125401 */126126- NR_DEV_EVENTS402402+ CTC_NR_DEV_EVENTS127403};128404129405static const char *dev_event_names[] = {···200476 NR_CH_EVENTS,201477};202478203203-static const char *ch_event_names[] = {204204- "ccw_device success",205205- "ccw_device busy",206206- "ccw_device enodev",207207- "ccw_device ioerr",208208- "ccw_device unknown",209209-210210- "Status ATTN & BUSY",211211- "Status ATTN",212212- "Status BUSY",213213-214214- "Unit check remote reset",215215- "Unit check remote system reset",216216- "Unit check TX timeout",217217- "Unit check TX parity",218218- "Unit check Hardware failure",219219- "Unit check RX parity",220220- "Unit check ZERO",221221- "Unit check Unknown",222222-223223- "SubChannel check Unknown",224224-225225- "Machine check failure",226226- "Machine check operational",227227-228228- "IRQ normal",229229- "IRQ final",230230-231231- "Timer",232232-233233- "Start",234234- "Stop",235235-};236236-237479/**238480 * States of the channel statemachine.239481 */···233543 * MUST be always the last element!!234544 */235545 NR_CH_STATES,546546+};547547+548548+static int loglevel = CTC_LOGLEVEL_DEFAULT;549549+550550+/**551551+ * Linked list of all detected channels.552552+ */553553+static struct channel *channels = NULL;554554+555555+/**556556+ * Print Banner.557557+ */558558+static void559559+print_banner(void)560560+{561561+ static int printed = 0;562562+ char vbuf[] = "$Revision: 1.74 $";563563+ char *version = vbuf;564564+565565+ if (printed)566566+ return;567567+ if ((version = strchr(version, ':'))) {568568+ char *p = strchr(version + 1, '$');569569+ if (p)570570+ *p = '\0';571571+ } else572572+ version = " ??? ";573573+ printk(KERN_INFO "CTC driver Version%s"574574+#ifdef DEBUG575575+ " (DEBUG-VERSION, " __DATE__ __TIME__ ")"576576+#endif577577+ " initialized\n", version);578578+ printed = 1;579579+}580580+581581+/**582582+ * Return type of a detected device.583583+ */584584+static enum channel_types585585+get_channel_type(struct ccw_device_id *id)586586+{587587+ enum channel_types type = (enum channel_types) id->driver_info;588588+589589+ if (type == channel_type_ficon)590590+ type = channel_type_escon;591591+592592+ return type;593593+}594594+595595+static const char *ch_event_names[] = {596596+ "ccw_device success",597597+ "ccw_device busy",598598+ "ccw_device enodev",599599+ "ccw_device ioerr",600600+ "ccw_device unknown",601601+602602+ "Status ATTN & BUSY",603603+ "Status ATTN",604604+ "Status BUSY",605605+606606+ "Unit check remote reset",607607+ "Unit check remote system reset",608608+ "Unit check TX timeout",609609+ "Unit check TX parity",610610+ "Unit check Hardware failure",611611+ "Unit check RX parity",612612+ "Unit check ZERO",613613+ "Unit check Unknown",614614+615615+ "SubChannel check Unknown",616616+617617+ "Machine check failure",618618+ "Machine check operational",619619+620620+ "IRQ normal",621621+ "IRQ final",622622+623623+ "Timer",624624+625625+ "Start",626626+ "Stop",236627};237628238629static const char *ch_state_names[] = {···17051934 ch->cdev = cdev;17061935 snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id);17071936 ch->type = type;17081708- loglevel = CTC_LOGLEVEL_DEFAULT;17091937 ch->fsm = init_fsm(ch->id, ch_state_names,17101938 ch_event_names, NR_CH_STATES, NR_CH_EVENTS,17111939 ch_fsm, CH_FSM_LEN, GFP_KERNEL);···24672697/*24682698 * sysfs attributes24692699 */27002700+24702701static ssize_t24712702buffer_show(struct device *dev, char *buf)24722703{···24862715 struct ctc_priv *priv;24872716 struct net_device *ndev;24882717 int bs1;27182718+ char buffer[16];2489271924902720 DBF_TEXT(trace, 3, __FUNCTION__);27212721+ DBF_TEXT(trace, 3, buf);24912722 priv = dev->driver_data;24922492- if (!priv)27232723+ if (!priv) {27242724+ DBF_TEXT(trace, 3, "bfnopriv");24932725 return -ENODEV;24942494- ndev = priv->channel[READ]->netdev;24952495- if (!ndev)24962496- return -ENODEV;24972497- sscanf(buf, "%u", &bs1);27262726+ }2498272727282728+ sscanf(buf, "%u", &bs1);24992729 if (bs1 > CTC_BUFSIZE_LIMIT)25002500- return -EINVAL;27302730+ goto einval;27312731+ if (bs1 < (576 + LL_HEADER_LENGTH + 2))27322732+ goto einval;27332733+ priv->buffer_size = bs1; // just to overwrite the default27342734+27352735+ ndev = priv->channel[READ]->netdev;27362736+ if (!ndev) {27372737+ DBF_TEXT(trace, 3, "bfnondev");27382738+ return -ENODEV;27392739+ }27402740+25012741 if ((ndev->flags & IFF_RUNNING) &&25022742 (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2)))25032503- return -EINVAL;25042504- if (bs1 < (576 + LL_HEADER_LENGTH + 2))25052505- return -EINVAL;27432743+ goto einval;2506274425072507- priv->buffer_size = bs1;25082508- priv->channel[READ]->max_bufsize =25092509- priv->channel[WRITE]->max_bufsize = bs1;27452745+ priv->channel[READ]->max_bufsize = bs1;27462746+ priv->channel[WRITE]->max_bufsize = bs1;25102747 if (!(ndev->flags & IFF_RUNNING))25112748 ndev->mtu = bs1 - LL_HEADER_LENGTH - 2;25122749 priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;25132750 priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;2514275127522752+ sprintf(buffer, "%d",priv->buffer_size);27532753+ DBF_TEXT(trace, 3, buffer);25152754 return count;2516275527562756+einval:27572757+ DBF_TEXT(trace, 3, "buff_err");27582758+ return -EINVAL;25172759}2518276025192761static ssize_t25202762loglevel_show(struct device *dev, char *buf)25212763{25222522- struct ctc_priv *priv;25232523-25242524- priv = dev->driver_data;25252525- if (!priv)25262526- return -ENODEV;25272764 return sprintf(buf, "%d\n", loglevel);25282765}2529276625302767static ssize_t25312768loglevel_write(struct device *dev, const char *buf, size_t count)25322769{25332533- struct ctc_priv *priv;25342770 int ll1;2535277125362772 DBF_TEXT(trace, 5, __FUNCTION__);25372537- priv = dev->driver_data;25382538- if (!priv)25392539- return -ENODEV;25402773 sscanf(buf, "%i", &ll1);2541277425422775 if ((ll1 > CTC_LOGLEVEL_MAX) || (ll1 < 0))···26102835 return count;26112836}2612283726132613-static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);26142614-static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write);26152615-static DEVICE_ATTR(stats, 0644, stats_show, stats_write);26162616-26172617-static int26182618-ctc_add_attributes(struct device *dev)26192619-{26202620-// device_create_file(dev, &dev_attr_buffer);26212621- device_create_file(dev, &dev_attr_loglevel);26222622- device_create_file(dev, &dev_attr_stats);26232623- return 0;26242624-}26252625-26262626-static void26272627-ctc_remove_attributes(struct device *dev)26282628-{26292629- device_remove_file(dev, &dev_attr_stats);26302630- device_remove_file(dev, &dev_attr_loglevel);26312631-// device_remove_file(dev, &dev_attr_buffer);26322632-}26332633-2634283826352839static void26362840ctc_netdev_unregister(struct net_device * dev)···26532899#endif26542900}2655290126562656-/**26572657- * Initialize everything of the net device except the name and the26582658- * channel structs.26592659- */26602660-static struct net_device *26612661-ctc_init_netdevice(struct net_device * dev, int alloc_device, 26622662- struct ctc_priv *privptr)26632663-{26642664- if (!privptr)26652665- return NULL;26662666-26672667- DBF_TEXT(setup, 3, __FUNCTION__);26682668- if (alloc_device) {26692669- dev = kmalloc(sizeof (struct net_device), GFP_KERNEL);26702670- if (!dev)26712671- return NULL;26722672- memset(dev, 0, sizeof (struct net_device));26732673- }26742674-26752675- dev->priv = privptr;26762676- privptr->fsm = init_fsm("ctcdev", dev_state_names,26772677- dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS,26782678- dev_fsm, DEV_FSM_LEN, GFP_KERNEL);26792679- if (privptr->fsm == NULL) {26802680- if (alloc_device)26812681- kfree(dev);26822682- return NULL;26832683- }26842684- fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);26852685- fsm_settimer(privptr->fsm, &privptr->restart_timer);26862686- if (dev->mtu == 0)26872687- dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;26882688- dev->hard_start_xmit = ctc_tx;26892689- dev->open = ctc_open;26902690- dev->stop = ctc_close;26912691- dev->get_stats = ctc_stats;26922692- dev->change_mtu = ctc_change_mtu;26932693- dev->hard_header_len = LL_HEADER_LENGTH + 2;26942694- dev->addr_len = 0;26952695- dev->type = ARPHRD_SLIP;26962696- dev->tx_queue_len = 100;26972697- dev->flags = IFF_POINTOPOINT | IFF_NOARP;26982698- SET_MODULE_OWNER(dev);26992699- return dev;27002700-}27012701-27022902static ssize_t27032903ctc_proto_show(struct device *dev, char *buf)27042904{···26852977 return count;26862978}2687297926882688-static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store);2689298026902981static ssize_t26912982ctc_type_show(struct device *dev, char *buf)···26982991 return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]);26992992}2700299329942994+static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);29952995+static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store);27012996static DEVICE_ATTR(type, 0444, ctc_type_show, NULL);29972997+29982998+static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write);29992999+static DEVICE_ATTR(stats, 0644, stats_show, stats_write);2702300027033001static struct attribute *ctc_attr[] = {27043002 &dev_attr_protocol.attr,···27153003static struct attribute_group ctc_attr_group = {27163004 .attrs = ctc_attr,27173005};30063006+30073007+static int30083008+ctc_add_attributes(struct device *dev)30093009+{30103010+ device_create_file(dev, &dev_attr_loglevel);30113011+ device_create_file(dev, &dev_attr_stats);30123012+ return 0;30133013+}30143014+30153015+static void30163016+ctc_remove_attributes(struct device *dev)30173017+{30183018+ device_remove_file(dev, &dev_attr_stats);30193019+ device_remove_file(dev, &dev_attr_loglevel);30203020+}2718302127193022static int27203023ctc_add_files(struct device *dev)···27553028 *27563029 * @returns 0 on success, !0 on failure.27573030 */27582758-27593031static int27603032ctc_probe_device(struct ccwgroup_device *cgdev)27613033{27623034 struct ctc_priv *priv;27633035 int rc;30363036+ char buffer[16];2764303727653038 pr_debug("%s() called\n", __FUNCTION__);27662766- DBF_TEXT(trace, 3, __FUNCTION__);30393039+ DBF_TEXT(setup, 3, __FUNCTION__);2767304027683041 if (!get_device(&cgdev->dev))27693042 return -ENODEV;···27873060 cgdev->cdev[1]->handler = ctc_irq_handler;27883061 cgdev->dev.driver_data = priv;2789306230633063+ sprintf(buffer, "%p", priv);30643064+ DBF_TEXT(data, 3, buffer);30653065+30663066+ sprintf(buffer, "%u", (unsigned int)sizeof(struct ctc_priv));30673067+ DBF_TEXT(data, 3, buffer);30683068+30693069+ sprintf(buffer, "%p", &channels);30703070+ DBF_TEXT(data, 3, buffer);30713071+30723072+ sprintf(buffer, "%u", (unsigned int)sizeof(struct channel));30733073+ DBF_TEXT(data, 3, buffer);30743074+27903075 return 0;27913076}30773077+30783078+/**30793079+ * Initialize everything of the net device except the name and the30803080+ * channel structs.30813081+ */30823082+static struct net_device *30833083+ctc_init_netdevice(struct net_device * dev, int alloc_device,30843084+ struct ctc_priv *privptr)30853085+{30863086+ if (!privptr)30873087+ return NULL;30883088+30893089+ DBF_TEXT(setup, 3, __FUNCTION__);30903090+30913091+ if (alloc_device) {30923092+ dev = kmalloc(sizeof (struct net_device), GFP_KERNEL);30933093+ if (!dev)30943094+ return NULL;30953095+ memset(dev, 0, sizeof (struct net_device));30963096+ }30973097+30983098+ dev->priv = privptr;30993099+ privptr->fsm = init_fsm("ctcdev", dev_state_names,31003100+ dev_event_names, CTC_NR_DEV_STATES, CTC_NR_DEV_EVENTS,31013101+ dev_fsm, DEV_FSM_LEN, GFP_KERNEL);31023102+ if (privptr->fsm == NULL) {31033103+ if (alloc_device)31043104+ kfree(dev);31053105+ return NULL;31063106+ }31073107+ fsm_newstate(privptr->fsm, DEV_STATE_STOPPED);31083108+ fsm_settimer(privptr->fsm, &privptr->restart_timer);31093109+ if (dev->mtu == 0)31103110+ dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;31113111+ dev->hard_start_xmit = ctc_tx;31123112+ dev->open = ctc_open;31133113+ dev->stop = ctc_close;31143114+ dev->get_stats = ctc_stats;31153115+ dev->change_mtu = ctc_change_mtu;31163116+ dev->hard_header_len = LL_HEADER_LENGTH + 2;31173117+ dev->addr_len = 0;31183118+ dev->type = ARPHRD_SLIP;31193119+ dev->tx_queue_len = 100;31203120+ dev->flags = IFF_POINTOPOINT | IFF_NOARP;31213121+ SET_MODULE_OWNER(dev);31223122+ return dev;31233123+}31243124+2792312527933126/**27943127 *···28683081 struct ctc_priv *privptr;28693082 struct net_device *dev;28703083 int ret;30843084+ char buffer[16];2871308528723086 pr_debug("%s() called\n", __FUNCTION__);28733087 DBF_TEXT(setup, 3, __FUNCTION__);···28763088 privptr = cgdev->dev.driver_data;28773089 if (!privptr)28783090 return -ENODEV;30913091+30923092+ sprintf(buffer, "%d", privptr->buffer_size);30933093+ DBF_TEXT(setup, 3, buffer);2879309428803095 type = get_channel_type(&cgdev->cdev[0]->id);28813096···29683177 struct ctc_priv *priv;29693178 struct net_device *ndev;2970317929712971- DBF_TEXT(trace, 3, __FUNCTION__);31803180+ DBF_TEXT(setup, 3, __FUNCTION__);29723181 pr_debug("%s() called\n", __FUNCTION__);31823182+2973318329743184 priv = cgdev->dev.driver_data;29753185 ndev = NULL;···30073215 channel_remove(priv->channel[READ]);30083216 if (priv->channel[WRITE])30093217 channel_remove(priv->channel[WRITE]);30103010-30113218 priv->channel[READ] = priv->channel[WRITE] = NULL;3012321930133220 return 0;···30193228 struct ctc_priv *priv;3020322930213230 pr_debug("%s() called\n", __FUNCTION__);30223022- DBF_TEXT(trace, 3, __FUNCTION__);32313231+ DBF_TEXT(setup, 3, __FUNCTION__);3023323230243233 priv = cgdev->dev.driver_data;30253234 if (!priv)···30563265static void __exit30573266ctc_exit(void)30583267{32683268+ DBF_TEXT(setup, 3, __FUNCTION__);30593269 unregister_cu3088_discipline(&ctc_group_driver);30603270 ctc_tty_cleanup();30613271 ctc_unregister_dbf_views();···30733281ctc_init(void)30743282{30753283 int ret = 0;32843284+32853285+ loglevel = CTC_LOGLEVEL_DEFAULT;32863286+32873287+ DBF_TEXT(setup, 3, __FUNCTION__);3076328830773289 print_banner();30783290
+276
drivers/s390/net/ctcmain.h
···11+/*22+ * $Id: ctcmain.h,v 1.4 2005/03/24 09:04:17 mschwide Exp $33+ *44+ * CTC / ESCON network driver55+ *66+ * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation77+ * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)88+ Peter Tiedemann (ptiedem@de.ibm.com)99+ *1010+ *1111+ * Documentation used:1212+ * - Principles of Operation (IBM doc#: SA22-7201-06)1313+ * - Common IO/-Device Commands and Self Description (IBM doc#: SA22-7204-02)1414+ * - Common IO/-Device Commands and Self Description (IBM doc#: SN22-5535)1515+ * - ESCON Channel-to-Channel Adapter (IBM doc#: SA22-7203-00)1616+ * - ESCON I/O Interface (IBM doc#: SA22-7202-0291717+ *1818+ * This program is free software; you can redistribute it and/or modify1919+ * it under the terms of the GNU General Public License as published by2020+ * the Free Software Foundation; either version 2, or (at your option)2121+ * any later version.2222+ *2323+ * This program is distributed in the hope that it will be useful,2424+ * but WITHOUT ANY WARRANTY; without even the implied warranty of2525+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the2626+ * GNU General Public License for more details.2727+ *2828+ * You should have received a copy of the GNU General Public License2929+ * along with this program; if not, write to the Free Software3030+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.3131+ *3232+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.4 $3333+ *3434+ */3535+3636+#ifndef _CTCMAIN_H_3737+#define _CTCMAIN_H_3838+3939+#include <asm/ccwdev.h>4040+#include <asm/ccwgroup.h>4141+4242+#include "ctctty.h"4343+#include "fsm.h"4444+#include "cu3088.h"4545+4646+4747+/**4848+ * CCW commands, used in this driver.4949+ */5050+#define CCW_CMD_WRITE 0x015151+#define CCW_CMD_READ 0x025252+#define CCW_CMD_SET_EXTENDED 0xc35353+#define CCW_CMD_PREPARE 0xe35454+5555+#define CTC_PROTO_S390 05656+#define CTC_PROTO_LINUX 15757+#define CTC_PROTO_LINUX_TTY 25858+#define CTC_PROTO_OS390 35959+#define CTC_PROTO_MAX 36060+6161+#define CTC_BUFSIZE_LIMIT 655356262+#define CTC_BUFSIZE_DEFAULT 327686363+6464+#define CTC_TIMEOUT_5SEC 50006565+6666+#define CTC_INITIAL_BLOCKLEN 26767+6868+#define READ 06969+#define WRITE 17070+7171+#define CTC_ID_SIZE BUS_ID_SIZE+37272+7373+7474+struct ctc_profile {7575+ unsigned long maxmulti;7676+ unsigned long maxcqueue;7777+ unsigned long doios_single;7878+ unsigned long doios_multi;7979+ unsigned long txlen;8080+ unsigned long tx_time;8181+ struct timespec send_stamp;8282+};8383+8484+/**8585+ * Definition of one channel8686+ */8787+struct channel {8888+8989+ /**9090+ * Pointer to next channel in list.9191+ */9292+ struct channel *next;9393+ char id[CTC_ID_SIZE];9494+ struct ccw_device *cdev;9595+9696+ /**9797+ * Type of this channel.9898+ * CTC/A or Escon for valid channels.9999+ */100100+ enum channel_types type;101101+102102+ /**103103+ * Misc. flags. See CHANNEL_FLAGS_... below104104+ */105105+ __u32 flags;106106+107107+ /**108108+ * The protocol of this channel109109+ */110110+ __u16 protocol;111111+112112+ /**113113+ * I/O and irq related stuff114114+ */115115+ struct ccw1 *ccw;116116+ struct irb *irb;117117+118118+ /**119119+ * RX/TX buffer size120120+ */121121+ int max_bufsize;122122+123123+ /**124124+ * Transmit/Receive buffer.125125+ */126126+ struct sk_buff *trans_skb;127127+128128+ /**129129+ * Universal I/O queue.130130+ */131131+ struct sk_buff_head io_queue;132132+133133+ /**134134+ * TX queue for collecting skb's during busy.135135+ */136136+ struct sk_buff_head collect_queue;137137+138138+ /**139139+ * Amount of data in collect_queue.140140+ */141141+ int collect_len;142142+143143+ /**144144+ * spinlock for collect_queue and collect_len145145+ */146146+ spinlock_t collect_lock;147147+148148+ /**149149+ * Timer for detecting unresposive150150+ * I/O operations.151151+ */152152+ fsm_timer timer;153153+154154+ /**155155+ * Retry counter for misc. operations.156156+ */157157+ int retry;158158+159159+ /**160160+ * The finite state machine of this channel161161+ */162162+ fsm_instance *fsm;163163+164164+ /**165165+ * The corresponding net_device this channel166166+ * belongs to.167167+ */168168+ struct net_device *netdev;169169+170170+ struct ctc_profile prof;171171+172172+ unsigned char *trans_skb_data;173173+174174+ __u16 logflags;175175+};176176+177177+#define CHANNEL_FLAGS_READ 0178178+#define CHANNEL_FLAGS_WRITE 1179179+#define CHANNEL_FLAGS_INUSE 2180180+#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4181181+#define CHANNEL_FLAGS_FAILED 8182182+#define CHANNEL_FLAGS_WAITIRQ 16183183+#define CHANNEL_FLAGS_RWMASK 1184184+#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)185185+186186+#define LOG_FLAG_ILLEGALPKT 1187187+#define LOG_FLAG_ILLEGALSIZE 2188188+#define LOG_FLAG_OVERRUN 4189189+#define LOG_FLAG_NOMEM 8190190+191191+#define CTC_LOGLEVEL_INFO 1192192+#define CTC_LOGLEVEL_NOTICE 2193193+#define CTC_LOGLEVEL_WARN 4194194+#define CTC_LOGLEVEL_EMERG 8195195+#define CTC_LOGLEVEL_ERR 16196196+#define CTC_LOGLEVEL_DEBUG 32197197+#define CTC_LOGLEVEL_CRIT 64198198+199199+#define CTC_LOGLEVEL_DEFAULT \200200+(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)201201+202202+#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1)203203+204204+#define ctc_pr_debug(fmt, arg...) \205205+do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0)206206+207207+#define ctc_pr_info(fmt, arg...) \208208+do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0)209209+210210+#define ctc_pr_notice(fmt, arg...) \211211+do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0)212212+213213+#define ctc_pr_warn(fmt, arg...) \214214+do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0)215215+216216+#define ctc_pr_emerg(fmt, arg...) \217217+do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0)218218+219219+#define ctc_pr_err(fmt, arg...) \220220+do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0)221221+222222+#define ctc_pr_crit(fmt, arg...) \223223+do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0)224224+225225+struct ctc_priv {226226+ struct net_device_stats stats;227227+ unsigned long tbusy;228228+ /**229229+ * The finite state machine of this interface.230230+ */231231+ fsm_instance *fsm;232232+ /**233233+ * The protocol of this device234234+ */235235+ __u16 protocol;236236+ /**237237+ * Timer for restarting after I/O Errors238238+ */239239+ fsm_timer restart_timer;240240+241241+ int buffer_size;242242+243243+ struct channel *channel[2];244244+};245245+246246+/**247247+ * Definition of our link level header.248248+ */249249+struct ll_header {250250+ __u16 length;251251+ __u16 type;252252+ __u16 unused;253253+};254254+#define LL_HEADER_LENGTH (sizeof(struct ll_header))255255+256256+/**257257+ * Compatibility macros for busy handling258258+ * of network devices.259259+ */260260+static __inline__ void261261+ctc_clear_busy(struct net_device * dev)262262+{263263+ clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));264264+ if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)265265+ netif_wake_queue(dev);266266+}267267+268268+static __inline__ int269269+ctc_test_and_set_busy(struct net_device * dev)270270+{271271+ if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)272272+ netif_stop_queue(dev);273273+ return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);274274+}275275+276276+#endif
···2323 /* Device is a OSA2 card */2424 channel_type_osa2,25252626+ /* Device is a CLAW channel device */2727+ channel_type_claw,2828+2629 /* Device is a channel, but we don't know2730 * anything about it */2831 channel_type_unknown,