Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.12 4447 lines 157 kB view raw
1/* 2 * drivers/s390/net/claw.c 3 * ESCON CLAW network driver 4 * 5 * $Revision: 1.35 $ $Date: 2005/03/24 12:25:38 $ 6 * 7 * Linux fo zSeries version 8 * Copyright (C) 2002,2005 IBM Corporation 9 * Author(s) Original code written by: 10 * Kazuo Iimura (iimura@jp.ibm.com) 11 * Rewritten by 12 * Andy Richter (richtera@us.ibm.com) 13 * Marc Price (mwprice@us.ibm.com) 14 * 15 * sysfs parms: 16 * group x.x.rrrr,x.x.wwww 17 * read_buffer nnnnnnn 18 * write_buffer nnnnnn 19 * host_name aaaaaaaa 20 * adapter_name aaaaaaaa 21 * api_type aaaaaaaa 22 * 23 * eg. 24 * group 0.0.0200 0.0.0201 25 * read_buffer 25 26 * write_buffer 20 27 * host_name LINUX390 28 * adapter_name RS6K 29 * api_type TCPIP 30 * 31 * where 32 * 33 * The device id is decided by the order entries 34 * are added to the group the first is claw0 the second claw1 35 * up to CLAW_MAX_DEV 36 * 37 * rrrr - the first of 2 consecutive device addresses used for the 38 * CLAW protocol. 39 * The specified address is always used as the input (Read) 40 * channel and the next address is used as the output channel. 41 * 42 * wwww - the second of 2 consecutive device addresses used for 43 * the CLAW protocol. 44 * The specified address is always used as the output 45 * channel and the previous address is used as the input channel. 46 * 47 * read_buffer - specifies number of input buffers to allocate. 48 * write_buffer - specifies number of output buffers to allocate. 49 * host_name - host name 50 * adaptor_name - adaptor name 51 * api_type - API type TCPIP or API will be sent and expected 52 * as ws_name 53 * 54 * Note the following requirements: 55 * 1) host_name must match the configured adapter_name on the remote side 56 * 2) adaptor_name must match the configured host name on the remote side 57 * 58 * Change History 59 * 1.00 Initial release shipped 60 * 1.10 Changes for Buffer allocation 61 * 1.15 Changed for 2.6 Kernel No longer compiles on 2.4 or lower 62 * 1.25 Added Packing support 63 */ 64#include <asm/bitops.h> 65#include <asm/ccwdev.h> 66#include <asm/ccwgroup.h> 67#include <asm/debug.h> 68#include <asm/idals.h> 69#include <asm/io.h> 70 71#include <linux/ctype.h> 72#include <linux/delay.h> 73#include <linux/errno.h> 74#include <linux/if_arp.h> 75#include <linux/init.h> 76#include <linux/interrupt.h> 77#include <linux/ip.h> 78#include <linux/kernel.h> 79#include <linux/module.h> 80#include <linux/netdevice.h> 81#include <linux/etherdevice.h> 82#include <linux/proc_fs.h> 83#include <linux/sched.h> 84#include <linux/signal.h> 85#include <linux/skbuff.h> 86#include <linux/slab.h> 87#include <linux/string.h> 88#include <linux/tcp.h> 89#include <linux/timer.h> 90#include <linux/types.h> 91#include <linux/version.h> 92 93#include "cu3088.h" 94#include "claw.h" 95 96MODULE_AUTHOR("Andy Richter <richtera@us.ibm.com>"); 97MODULE_DESCRIPTION("Linux for zSeries CLAW Driver\n" \ 98 "Copyright 2000,2005 IBM Corporation\n"); 99MODULE_LICENSE("GPL"); 100 101/* Debugging is based on DEBUGMSG, IOTRACE, or FUNCTRACE options: 102 DEBUGMSG - Enables output of various debug messages in the code 103 IOTRACE - Enables output of CCW and other IO related traces 104 FUNCTRACE - Enables output of function entry/exit trace 105 Define any combination of above options to enable tracing 106 107 CLAW also uses the s390dbf file system see claw_trace and claw_setup 108*/ 109 110/* following enables tracing */ 111//#define DEBUGMSG 112//#define IOTRACE 113//#define FUNCTRACE 114 115#ifdef DEBUGMSG 116#define DEBUG 117#endif 118 119#ifdef IOTRACE 120#define DEBUG 121#endif 122 123#ifdef FUNCTRACE 124#define DEBUG 125#endif 126 127 char debug_buffer[255]; 128/** 129 * Debug Facility Stuff 130 */ 131static debug_info_t *claw_dbf_setup; 132static debug_info_t *claw_dbf_trace; 133 134/** 135 * CLAW Debug Facility functions 136 */ 137static void 138claw_unregister_debug_facility(void) 139{ 140 if (claw_dbf_setup) 141 debug_unregister(claw_dbf_setup); 142 if (claw_dbf_trace) 143 debug_unregister(claw_dbf_trace); 144} 145 146static int 147claw_register_debug_facility(void) 148{ 149 claw_dbf_setup = debug_register("claw_setup", 1, 1, 8); 150 claw_dbf_trace = debug_register("claw_trace", 1, 2, 8); 151 if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) { 152 printk(KERN_WARNING "Not enough memory for debug facility.\n"); 153 claw_unregister_debug_facility(); 154 return -ENOMEM; 155 } 156 debug_register_view(claw_dbf_setup, &debug_hex_ascii_view); 157 debug_set_level(claw_dbf_setup, 2); 158 debug_register_view(claw_dbf_trace, &debug_hex_ascii_view); 159 debug_set_level(claw_dbf_trace, 2); 160 return 0; 161} 162 163static inline void 164claw_set_busy(struct net_device *dev) 165{ 166 ((struct claw_privbk *) dev->priv)->tbusy=1; 167 eieio(); 168} 169 170static inline void 171claw_clear_busy(struct net_device *dev) 172{ 173 clear_bit(0, &(((struct claw_privbk *) dev->priv)->tbusy)); 174 netif_wake_queue(dev); 175 eieio(); 176} 177 178static inline int 179claw_check_busy(struct net_device *dev) 180{ 181 eieio(); 182 return ((struct claw_privbk *) dev->priv)->tbusy; 183} 184 185static inline void 186claw_setbit_busy(int nr,struct net_device *dev) 187{ 188 netif_stop_queue(dev); 189 set_bit(nr, (void *)&(((struct claw_privbk *)dev->priv)->tbusy)); 190} 191 192static inline void 193claw_clearbit_busy(int nr,struct net_device *dev) 194{ 195 clear_bit(nr,(void *)&(((struct claw_privbk *)dev->priv)->tbusy)); 196 netif_wake_queue(dev); 197} 198 199static inline int 200claw_test_and_setbit_busy(int nr,struct net_device *dev) 201{ 202 netif_stop_queue(dev); 203 return test_and_set_bit(nr, 204 (void *)&(((struct claw_privbk *) dev->priv)->tbusy)); 205} 206 207 208/* Functions for the DEV methods */ 209 210static int claw_probe(struct ccwgroup_device *cgdev); 211static void claw_remove_device(struct ccwgroup_device *cgdev); 212static void claw_purge_skb_queue(struct sk_buff_head *q); 213static int claw_new_device(struct ccwgroup_device *cgdev); 214static int claw_shutdown_device(struct ccwgroup_device *cgdev); 215static int claw_tx(struct sk_buff *skb, struct net_device *dev); 216static int claw_change_mtu( struct net_device *dev, int new_mtu); 217static int claw_open(struct net_device *dev); 218static void claw_irq_handler(struct ccw_device *cdev, 219 unsigned long intparm, struct irb *irb); 220static void claw_irq_tasklet ( unsigned long data ); 221static int claw_release(struct net_device *dev); 222static void claw_write_retry ( struct chbk * p_ch ); 223static void claw_write_next ( struct chbk * p_ch ); 224static void claw_timer ( struct chbk * p_ch ); 225 226/* Functions */ 227static int add_claw_reads(struct net_device *dev, 228 struct ccwbk* p_first, struct ccwbk* p_last); 229static void inline ccw_check_return_code (struct ccw_device *cdev, 230 int return_code); 231static void inline ccw_check_unit_check (struct chbk * p_ch, 232 unsigned char sense ); 233static int find_link(struct net_device *dev, char *host_name, char *ws_name ); 234static int claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid); 235static int init_ccw_bk(struct net_device *dev); 236static void probe_error( struct ccwgroup_device *cgdev); 237static struct net_device_stats *claw_stats(struct net_device *dev); 238static int inline pages_to_order_of_mag(int num_of_pages); 239static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr); 240#ifdef DEBUG 241static void dumpit (char *buf, int len); 242#endif 243/* sysfs Functions */ 244static ssize_t claw_hname_show(struct device *dev, char *buf); 245static ssize_t claw_hname_write(struct device *dev, 246 const char *buf, size_t count); 247static ssize_t claw_adname_show(struct device *dev, char *buf); 248static ssize_t claw_adname_write(struct device *dev, 249 const char *buf, size_t count); 250static ssize_t claw_apname_show(struct device *dev, char *buf); 251static ssize_t claw_apname_write(struct device *dev, 252 const char *buf, size_t count); 253static ssize_t claw_wbuff_show(struct device *dev, char *buf); 254static ssize_t claw_wbuff_write(struct device *dev, 255 const char *buf, size_t count); 256static ssize_t claw_rbuff_show(struct device *dev, char *buf); 257static ssize_t claw_rbuff_write(struct device *dev, 258 const char *buf, size_t count); 259static int claw_add_files(struct device *dev); 260static void claw_remove_files(struct device *dev); 261 262/* Functions for System Validate */ 263static int claw_process_control( struct net_device *dev, struct ccwbk * p_ccw); 264static int claw_send_control(struct net_device *dev, __u8 type, __u8 link, 265 __u8 correlator, __u8 rc , char *local_name, char *remote_name); 266static int claw_snd_conn_req(struct net_device *dev, __u8 link); 267static int claw_snd_disc(struct net_device *dev, struct clawctl * p_ctl); 268static int claw_snd_sys_validate_rsp(struct net_device *dev, 269 struct clawctl * p_ctl, __u32 return_code); 270static int claw_strt_conn_req(struct net_device *dev ); 271static void claw_strt_read ( struct net_device *dev, int lock ); 272static void claw_strt_out_IO( struct net_device *dev ); 273static void claw_free_wrt_buf( struct net_device *dev ); 274 275/* Functions for unpack reads */ 276static void unpack_read (struct net_device *dev ); 277 278/* ccwgroup table */ 279 280static struct ccwgroup_driver claw_group_driver = { 281 .owner = THIS_MODULE, 282 .name = "claw", 283 .max_slaves = 2, 284 .driver_id = 0xC3D3C1E6, 285 .probe = claw_probe, 286 .remove = claw_remove_device, 287 .set_online = claw_new_device, 288 .set_offline = claw_shutdown_device, 289}; 290 291/* 292* 293* Key functions 294*/ 295 296/*----------------------------------------------------------------* 297 * claw_probe * 298 * this function is called for each CLAW device. * 299 *----------------------------------------------------------------*/ 300static int 301claw_probe(struct ccwgroup_device *cgdev) 302{ 303 int rc; 304 struct claw_privbk *privptr=NULL; 305 306#ifdef FUNCTRACE 307 printk(KERN_INFO "%s Enter\n",__FUNCTION__); 308#endif 309 CLAW_DBF_TEXT(2,setup,"probe"); 310 if (!get_device(&cgdev->dev)) 311 return -ENODEV; 312#ifdef DEBUGMSG 313 printk(KERN_INFO "claw: variable cgdev =\n"); 314 dumpit((char *)cgdev, sizeof(struct ccwgroup_device)); 315#endif 316 privptr = kmalloc(sizeof(struct claw_privbk), GFP_KERNEL); 317 if (privptr == NULL) { 318 probe_error(cgdev); 319 put_device(&cgdev->dev); 320 printk(KERN_WARNING "Out of memory %s %s Exit Line %d \n", 321 cgdev->cdev[0]->dev.bus_id,__FUNCTION__,__LINE__); 322 CLAW_DBF_TEXT_(2,setup,"probex%d",-ENOMEM); 323 return -ENOMEM; 324 } 325 memset(privptr,0x00,sizeof(struct claw_privbk)); 326 privptr->p_mtc_envelope= kmalloc( MAX_ENVELOPE_SIZE, GFP_KERNEL); 327 privptr->p_env = kmalloc(sizeof(struct claw_env), GFP_KERNEL); 328 if ((privptr->p_mtc_envelope==NULL) || (privptr->p_env==NULL)) { 329 probe_error(cgdev); 330 put_device(&cgdev->dev); 331 printk(KERN_WARNING "Out of memory %s %s Exit Line %d \n", 332 cgdev->cdev[0]->dev.bus_id,__FUNCTION__,__LINE__); 333 CLAW_DBF_TEXT_(2,setup,"probex%d",-ENOMEM); 334 return -ENOMEM; 335 } 336 memset(privptr->p_mtc_envelope, 0x00, MAX_ENVELOPE_SIZE); 337 memset(privptr->p_env, 0x00, sizeof(struct claw_env)); 338 memcpy(privptr->p_env->adapter_name,WS_NAME_NOT_DEF,8); 339 memcpy(privptr->p_env->host_name,WS_NAME_NOT_DEF,8); 340 memcpy(privptr->p_env->api_type,WS_NAME_NOT_DEF,8); 341 privptr->p_env->packing = 0; 342 privptr->p_env->write_buffers = 5; 343 privptr->p_env->read_buffers = 5; 344 privptr->p_env->read_size = CLAW_FRAME_SIZE; 345 privptr->p_env->write_size = CLAW_FRAME_SIZE; 346 rc = claw_add_files(&cgdev->dev); 347 if (rc) { 348 probe_error(cgdev); 349 put_device(&cgdev->dev); 350 printk(KERN_WARNING "add_files failed %s %s Exit Line %d \n", 351 cgdev->cdev[0]->dev.bus_id,__FUNCTION__,__LINE__); 352 CLAW_DBF_TEXT_(2,setup,"probex%d",rc); 353 return rc; 354 } 355 printk(KERN_INFO "claw: sysfs files added for %s\n",cgdev->cdev[0]->dev.bus_id); 356 privptr->p_env->p_priv = privptr; 357 cgdev->cdev[0]->handler = claw_irq_handler; 358 cgdev->cdev[1]->handler = claw_irq_handler; 359 cgdev->dev.driver_data = privptr; 360#ifdef FUNCTRACE 361 printk(KERN_INFO "claw:%s exit on line %d, " 362 "rc = 0\n",__FUNCTION__,__LINE__); 363#endif 364 CLAW_DBF_TEXT(2,setup,"prbext 0"); 365 366 return 0; 367} /* end of claw_probe */ 368 369/*-------------------------------------------------------------------* 370 * claw_tx * 371 *-------------------------------------------------------------------*/ 372 373static int 374claw_tx(struct sk_buff *skb, struct net_device *dev) 375{ 376 int rc; 377 struct claw_privbk *privptr=dev->priv; 378 unsigned long saveflags; 379 struct chbk *p_ch; 380 381#ifdef FUNCTRACE 382 printk(KERN_INFO "%s:%s enter\n",dev->name,__FUNCTION__); 383#endif 384 CLAW_DBF_TEXT(4,trace,"claw_tx"); 385 p_ch=&privptr->channel[WRITE]; 386 if (skb == NULL) { 387 printk(KERN_WARNING "%s: null pointer passed as sk_buffer\n", 388 dev->name); 389 privptr->stats.tx_dropped++; 390#ifdef FUNCTRACE 391 printk(KERN_INFO "%s: %s() exit on line %d, rc = EIO\n", 392 dev->name,__FUNCTION__, __LINE__); 393#endif 394 CLAW_DBF_TEXT_(2,trace,"clawtx%d",-EIO); 395 return -EIO; 396 } 397 398#ifdef IOTRACE 399 printk(KERN_INFO "%s: variable sk_buff=\n",dev->name); 400 dumpit((char *) skb, sizeof(struct sk_buff)); 401 printk(KERN_INFO "%s: variable dev=\n",dev->name); 402 dumpit((char *) dev, sizeof(struct net_device)); 403#endif 404 spin_lock_irqsave(get_ccwdev_lock(p_ch->cdev), saveflags); 405 rc=claw_hw_tx( skb, dev, 1 ); 406 spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags); 407#ifdef FUNCTRACE 408 printk(KERN_INFO "%s:%s exit on line %d, rc = %d\n", 409 dev->name, __FUNCTION__, __LINE__, rc); 410#endif 411 CLAW_DBF_TEXT_(4,trace,"clawtx%d",rc); 412 return rc; 413} /* end of claw_tx */ 414 415/*------------------------------------------------------------------* 416 * pack the collect queue into an skb and return it * 417 * If not packing just return the top skb from the queue * 418 *------------------------------------------------------------------*/ 419 420static struct sk_buff * 421claw_pack_skb(struct claw_privbk *privptr) 422{ 423 struct sk_buff *new_skb,*held_skb; 424 struct chbk *p_ch = &privptr->channel[WRITE]; 425 struct claw_env *p_env = privptr->p_env; 426 int pkt_cnt,pk_ind,so_far; 427 428 new_skb = NULL; /* assume no dice */ 429 pkt_cnt = 0; 430 CLAW_DBF_TEXT(4,trace,"PackSKBe"); 431 if (skb_queue_len(&p_ch->collect_queue) > 0) { 432 /* some data */ 433 held_skb = skb_dequeue(&p_ch->collect_queue); 434 if (p_env->packing != DO_PACKED) 435 return held_skb; 436 if (held_skb) 437 atomic_dec(&held_skb->users); 438 else 439 return NULL; 440 /* get a new SKB we will pack at least one */ 441 new_skb = dev_alloc_skb(p_env->write_size); 442 if (new_skb == NULL) { 443 atomic_inc(&held_skb->users); 444 skb_queue_head(&p_ch->collect_queue,held_skb); 445 return NULL; 446 } 447 /* we have packed packet and a place to put it */ 448 pk_ind = 1; 449 so_far = 0; 450 new_skb->cb[1] = 'P'; /* every skb on queue has pack header */ 451 while ((pk_ind) && (held_skb != NULL)) { 452 if (held_skb->len+so_far <= p_env->write_size-8) { 453 memcpy(skb_put(new_skb,held_skb->len), 454 held_skb->data,held_skb->len); 455 privptr->stats.tx_packets++; 456 so_far += held_skb->len; 457 pkt_cnt++; 458 dev_kfree_skb_irq(held_skb); 459 held_skb = skb_dequeue(&p_ch->collect_queue); 460 if (held_skb) 461 atomic_dec(&held_skb->users); 462 } else { 463 pk_ind = 0; 464 atomic_inc(&held_skb->users); 465 skb_queue_head(&p_ch->collect_queue,held_skb); 466 } 467 } 468#ifdef IOTRACE 469 printk(KERN_INFO "%s: %s() Packed %d len %d\n", 470 p_env->ndev->name, 471 __FUNCTION__,pkt_cnt,new_skb->len); 472#endif 473 } 474 CLAW_DBF_TEXT(4,trace,"PackSKBx"); 475 return new_skb; 476} 477 478/*-------------------------------------------------------------------* 479 * claw_change_mtu * 480 * * 481 *-------------------------------------------------------------------*/ 482 483static int 484claw_change_mtu(struct net_device *dev, int new_mtu) 485{ 486 struct claw_privbk *privptr=dev->priv; 487 int buff_size; 488#ifdef FUNCTRACE 489 printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__); 490#endif 491#ifdef DEBUGMSG 492 printk(KERN_INFO "variable dev =\n"); 493 dumpit((char *) dev, sizeof(struct net_device)); 494 printk(KERN_INFO "variable new_mtu = %d\n", new_mtu); 495#endif 496 CLAW_DBF_TEXT(4,trace,"setmtu"); 497 buff_size = privptr->p_env->write_size; 498 if ((new_mtu < 60) || (new_mtu > buff_size)) { 499#ifdef FUNCTRACE 500 printk(KERN_INFO "%s:%s Exit on line %d, rc=EINVAL\n", 501 dev->name, 502 __FUNCTION__, __LINE__); 503#endif 504 return -EINVAL; 505 } 506 dev->mtu = new_mtu; 507#ifdef FUNCTRACE 508 printk(KERN_INFO "%s:%s Exit on line %d\n",dev->name, 509 __FUNCTION__, __LINE__); 510#endif 511 return 0; 512} /* end of claw_change_mtu */ 513 514 515/*-------------------------------------------------------------------* 516 * claw_open * 517 * * 518 *-------------------------------------------------------------------*/ 519static int 520claw_open(struct net_device *dev) 521{ 522 523 int rc; 524 int i; 525 unsigned long saveflags=0; 526 unsigned long parm; 527 struct claw_privbk *privptr; 528 DECLARE_WAITQUEUE(wait, current); 529 struct timer_list timer; 530 struct ccwbk *p_buf; 531 532#ifdef FUNCTRACE 533 printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__); 534#endif 535 CLAW_DBF_TEXT(4,trace,"open"); 536 if (!dev | (dev->name[0] == 0x00)) { 537 CLAW_DBF_TEXT(2,trace,"BadDev"); 538 printk(KERN_WARNING "claw: Bad device at open failing \n"); 539 return -ENODEV; 540 } 541 privptr = (struct claw_privbk *)dev->priv; 542 /* allocate and initialize CCW blocks */ 543 if (privptr->buffs_alloc == 0) { 544 rc=init_ccw_bk(dev); 545 if (rc) { 546 printk(KERN_INFO "%s:%s Exit on line %d, rc=ENOMEM\n", 547 dev->name, 548 __FUNCTION__, __LINE__); 549 CLAW_DBF_TEXT(2,trace,"openmem"); 550 return -ENOMEM; 551 } 552 } 553 privptr->system_validate_comp=0; 554 privptr->release_pend=0; 555 if(strncmp(privptr->p_env->api_type,WS_APPL_NAME_PACKED,6) == 0) { 556 privptr->p_env->read_size=DEF_PACK_BUFSIZE; 557 privptr->p_env->write_size=DEF_PACK_BUFSIZE; 558 privptr->p_env->packing=PACKING_ASK; 559 } else { 560 privptr->p_env->packing=0; 561 privptr->p_env->read_size=CLAW_FRAME_SIZE; 562 privptr->p_env->write_size=CLAW_FRAME_SIZE; 563 } 564 claw_set_busy(dev); 565 tasklet_init(&privptr->channel[READ].tasklet, claw_irq_tasklet, 566 (unsigned long) &privptr->channel[READ]); 567 for ( i = 0; i < 2; i++) { 568 CLAW_DBF_TEXT_(2,trace,"opn_ch%d",i); 569 init_waitqueue_head(&privptr->channel[i].wait); 570 /* skb_queue_head_init(&p_ch->io_queue); */ 571 if (i == WRITE) 572 skb_queue_head_init( 573 &privptr->channel[WRITE].collect_queue); 574 privptr->channel[i].flag_a = 0; 575 privptr->channel[i].IO_active = 0; 576 privptr->channel[i].flag &= ~CLAW_TIMER; 577 init_timer(&timer); 578 timer.function = (void *)claw_timer; 579 timer.data = (unsigned long)(&privptr->channel[i]); 580 timer.expires = jiffies + 15*HZ; 581 add_timer(&timer); 582 spin_lock_irqsave(get_ccwdev_lock( 583 privptr->channel[i].cdev), saveflags); 584 parm = (unsigned long) &privptr->channel[i]; 585 privptr->channel[i].claw_state = CLAW_START_HALT_IO; 586 rc = 0; 587 add_wait_queue(&privptr->channel[i].wait, &wait); 588 rc = ccw_device_halt( 589 (struct ccw_device *)privptr->channel[i].cdev,parm); 590 set_current_state(TASK_INTERRUPTIBLE); 591 spin_unlock_irqrestore( 592 get_ccwdev_lock(privptr->channel[i].cdev), saveflags); 593 schedule(); 594 set_current_state(TASK_RUNNING); 595 remove_wait_queue(&privptr->channel[i].wait, &wait); 596 if(rc != 0) 597 ccw_check_return_code(privptr->channel[i].cdev, rc); 598 if((privptr->channel[i].flag & CLAW_TIMER) == 0x00) 599 del_timer(&timer); 600 } 601 if ((((privptr->channel[READ].last_dstat | 602 privptr->channel[WRITE].last_dstat) & 603 ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) || 604 (((privptr->channel[READ].flag | 605 privptr->channel[WRITE].flag) & CLAW_TIMER) != 0x00)) { 606#ifdef DEBUGMSG 607 printk(KERN_INFO "%s: channel problems during open - read:" 608 " %02x - write: %02x\n", 609 dev->name, 610 privptr->channel[READ].last_dstat, 611 privptr->channel[WRITE].last_dstat); 612#endif 613 printk(KERN_INFO "%s: remote side is not ready\n", dev->name); 614 CLAW_DBF_TEXT(2,trace,"notrdy"); 615 616 for ( i = 0; i < 2; i++) { 617 spin_lock_irqsave( 618 get_ccwdev_lock(privptr->channel[i].cdev), 619 saveflags); 620 parm = (unsigned long) &privptr->channel[i]; 621 privptr->channel[i].claw_state = CLAW_STOP; 622 rc = ccw_device_halt( 623 (struct ccw_device *)&privptr->channel[i].cdev, 624 parm); 625 spin_unlock_irqrestore( 626 get_ccwdev_lock(privptr->channel[i].cdev), 627 saveflags); 628 if (rc != 0) { 629 ccw_check_return_code( 630 privptr->channel[i].cdev, rc); 631 } 632 } 633 free_pages((unsigned long)privptr->p_buff_ccw, 634 (int)pages_to_order_of_mag(privptr->p_buff_ccw_num)); 635 if (privptr->p_env->read_size < PAGE_SIZE) { 636 free_pages((unsigned long)privptr->p_buff_read, 637 (int)pages_to_order_of_mag( 638 privptr->p_buff_read_num)); 639 } 640 else { 641 p_buf=privptr->p_read_active_first; 642 while (p_buf!=NULL) { 643 free_pages((unsigned long)p_buf->p_buffer, 644 (int)pages_to_order_of_mag( 645 privptr->p_buff_pages_perread )); 646 p_buf=p_buf->next; 647 } 648 } 649 if (privptr->p_env->write_size < PAGE_SIZE ) { 650 free_pages((unsigned long)privptr->p_buff_write, 651 (int)pages_to_order_of_mag( 652 privptr->p_buff_write_num)); 653 } 654 else { 655 p_buf=privptr->p_write_active_first; 656 while (p_buf!=NULL) { 657 free_pages((unsigned long)p_buf->p_buffer, 658 (int)pages_to_order_of_mag( 659 privptr->p_buff_pages_perwrite )); 660 p_buf=p_buf->next; 661 } 662 } 663 privptr->buffs_alloc = 0; 664 privptr->channel[READ].flag= 0x00; 665 privptr->channel[WRITE].flag = 0x00; 666 privptr->p_buff_ccw=NULL; 667 privptr->p_buff_read=NULL; 668 privptr->p_buff_write=NULL; 669 claw_clear_busy(dev); 670#ifdef FUNCTRACE 671 printk(KERN_INFO "%s:%s Exit on line %d, rc=EIO\n", 672 dev->name,__FUNCTION__,__LINE__); 673#endif 674 CLAW_DBF_TEXT(2,trace,"open EIO"); 675 return -EIO; 676 } 677 678 /* Send SystemValidate command */ 679 680 claw_clear_busy(dev); 681 682#ifdef FUNCTRACE 683 printk(KERN_INFO "%s:%s Exit on line %d, rc=0\n", 684 dev->name,__FUNCTION__,__LINE__); 685#endif 686 CLAW_DBF_TEXT(4,trace,"openok"); 687 return 0; 688} /* end of claw_open */ 689 690/*-------------------------------------------------------------------* 691* * 692* claw_irq_handler * 693* * 694*--------------------------------------------------------------------*/ 695static void 696claw_irq_handler(struct ccw_device *cdev, 697 unsigned long intparm, struct irb *irb) 698{ 699 struct chbk *p_ch = NULL; 700 struct claw_privbk *privptr = NULL; 701 struct net_device *dev = NULL; 702 struct claw_env *p_env; 703 struct chbk *p_ch_r=NULL; 704 705 706#ifdef FUNCTRACE 707 printk(KERN_INFO "%s enter \n",__FUNCTION__); 708#endif 709 CLAW_DBF_TEXT(4,trace,"clawirq"); 710 /* Bypass all 'unsolicited interrupts' */ 711 if (!cdev->dev.driver_data) { 712 printk(KERN_WARNING "claw: unsolicited interrupt for device:" 713 "%s received c-%02x d-%02x\n", 714 cdev->dev.bus_id,irb->scsw.cstat, irb->scsw.dstat); 715#ifdef FUNCTRACE 716 printk(KERN_INFO "claw: %s() " 717 "exit on line %d\n",__FUNCTION__,__LINE__); 718#endif 719 CLAW_DBF_TEXT(2,trace,"badirq"); 720 return; 721 } 722 privptr = (struct claw_privbk *)cdev->dev.driver_data; 723 724 /* Try to extract channel from driver data. */ 725 if (privptr->channel[READ].cdev == cdev) 726 p_ch = &privptr->channel[READ]; 727 else if (privptr->channel[WRITE].cdev == cdev) 728 p_ch = &privptr->channel[WRITE]; 729 else { 730 printk(KERN_WARNING "claw: Can't determine channel for " 731 "interrupt, device %s\n", cdev->dev.bus_id); 732 CLAW_DBF_TEXT(2,trace,"badchan"); 733 return; 734 } 735 CLAW_DBF_TEXT_(4,trace,"IRQCH=%d",p_ch->flag); 736 737 dev = (struct net_device *) (p_ch->ndev); 738 p_env=privptr->p_env; 739 740#ifdef IOTRACE 741 printk(KERN_INFO "%s: interrupt for device: %04x " 742 "received c-%02x d-%02x state-%02x\n", 743 dev->name, p_ch->devno, irb->scsw.cstat, 744 irb->scsw.dstat, p_ch->claw_state); 745#endif 746 747 /* Copy interruption response block. */ 748 memcpy(p_ch->irb, irb, sizeof(struct irb)); 749 750 /* Check for good subchannel return code, otherwise error message */ 751 if (irb->scsw.cstat && !(irb->scsw.cstat & SCHN_STAT_PCI)) { 752 printk(KERN_INFO "%s: subchannel check for device: %04x -" 753 " Sch Stat %02x Dev Stat %02x CPA - %04x\n", 754 dev->name, p_ch->devno, 755 irb->scsw.cstat, irb->scsw.dstat,irb->scsw.cpa); 756#ifdef IOTRACE 757 dumpit((char *)irb,sizeof(struct irb)); 758 dumpit((char *)(unsigned long)irb->scsw.cpa, 759 sizeof(struct ccw1)); 760#endif 761#ifdef FUNCTRACE 762 printk(KERN_INFO "%s:%s Exit on line %d\n", 763 dev->name,__FUNCTION__,__LINE__); 764#endif 765 CLAW_DBF_TEXT(2,trace,"chanchk"); 766 /* return; */ 767 } 768 769 /* Check the reason-code of a unit check */ 770 if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { 771 ccw_check_unit_check(p_ch, irb->ecw[0]); 772 } 773 774 /* State machine to bring the connection up, down and to restart */ 775 p_ch->last_dstat = irb->scsw.dstat; 776 777 switch (p_ch->claw_state) { 778 case CLAW_STOP:/* HALT_IO by claw_release (halt sequence) */ 779#ifdef DEBUGMSG 780 printk(KERN_INFO "%s: CLAW_STOP enter\n", dev->name); 781#endif 782 if (!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || 783 (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || 784 (p_ch->irb->scsw.stctl == 785 (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) { 786#ifdef FUNCTRACE 787 printk(KERN_INFO "%s:%s Exit on line %d\n", 788 dev->name,__FUNCTION__,__LINE__); 789#endif 790 return; 791 } 792 wake_up(&p_ch->wait); /* wake up claw_release */ 793 794#ifdef DEBUGMSG 795 printk(KERN_INFO "%s: CLAW_STOP exit\n", dev->name); 796#endif 797#ifdef FUNCTRACE 798 printk(KERN_INFO "%s:%s Exit on line %d\n", 799 dev->name,__FUNCTION__,__LINE__); 800#endif 801 CLAW_DBF_TEXT(4,trace,"stop"); 802 return; 803 804 case CLAW_START_HALT_IO: /* HALT_IO issued by claw_open */ 805#ifdef DEBUGMSG 806 printk(KERN_INFO "%s: process CLAW_STAT_HALT_IO\n", 807 dev->name); 808#endif 809 if (!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || 810 (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || 811 (p_ch->irb->scsw.stctl == 812 (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) { 813#ifdef FUNCTRACE 814 printk(KERN_INFO "%s:%s Exit on line %d\n", 815 dev->name,__FUNCTION__,__LINE__); 816#endif 817 CLAW_DBF_TEXT(4,trace,"haltio"); 818 return; 819 } 820 if (p_ch->flag == CLAW_READ) { 821 p_ch->claw_state = CLAW_START_READ; 822 wake_up(&p_ch->wait); /* wake claw_open (READ)*/ 823 } 824 else 825 if (p_ch->flag == CLAW_WRITE) { 826 p_ch->claw_state = CLAW_START_WRITE; 827 /* send SYSTEM_VALIDATE */ 828 claw_strt_read(dev, LOCK_NO); 829 claw_send_control(dev, 830 SYSTEM_VALIDATE_REQUEST, 831 0, 0, 0, 832 p_env->host_name, 833 p_env->adapter_name ); 834 } else { 835 printk(KERN_WARNING "claw: unsolicited " 836 "interrupt for device:" 837 "%s received c-%02x d-%02x\n", 838 cdev->dev.bus_id, 839 irb->scsw.cstat, 840 irb->scsw.dstat); 841 return; 842 } 843#ifdef DEBUGMSG 844 printk(KERN_INFO "%s: process CLAW_STAT_HALT_IO exit\n", 845 dev->name); 846#endif 847#ifdef FUNCTRACE 848 printk(KERN_INFO "%s:%s Exit on line %d\n", 849 dev->name,__FUNCTION__,__LINE__); 850#endif 851 CLAW_DBF_TEXT(4,trace,"haltio"); 852 return; 853 case CLAW_START_READ: 854 CLAW_DBF_TEXT(4,trace,"ReadIRQ"); 855 if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { 856 clear_bit(0, (void *)&p_ch->IO_active); 857 if ((p_ch->irb->ecw[0] & 0x41) == 0x41 || 858 (p_ch->irb->ecw[0] & 0x40) == 0x40 || 859 (p_ch->irb->ecw[0]) == 0) 860 { 861 privptr->stats.rx_errors++; 862 printk(KERN_INFO "%s: Restart is " 863 "required after remote " 864 "side recovers \n", 865 dev->name); 866 } 867#ifdef FUNCTRACE 868 printk(KERN_INFO "%s:%s Exit on line %d\n", 869 dev->name,__FUNCTION__,__LINE__); 870#endif 871 CLAW_DBF_TEXT(4,trace,"notrdy"); 872 return; 873 } 874 if ((p_ch->irb->scsw.cstat & SCHN_STAT_PCI) && 875 (p_ch->irb->scsw.dstat==0)) { 876 if (test_and_set_bit(CLAW_BH_ACTIVE, 877 (void *)&p_ch->flag_a) == 0) { 878 tasklet_schedule(&p_ch->tasklet); 879 } 880 else { 881 CLAW_DBF_TEXT(4,trace,"PCINoBH"); 882 } 883#ifdef FUNCTRACE 884 printk(KERN_INFO "%s:%s Exit on line %d\n", 885 dev->name,__FUNCTION__,__LINE__); 886#endif 887 CLAW_DBF_TEXT(4,trace,"PCI_read"); 888 return; 889 } 890 if(!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || 891 (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || 892 (p_ch->irb->scsw.stctl == 893 (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) { 894#ifdef FUNCTRACE 895 printk(KERN_INFO "%s:%s Exit on line %d\n", 896 dev->name,__FUNCTION__,__LINE__); 897#endif 898 CLAW_DBF_TEXT(4,trace,"SPend_rd"); 899 return; 900 } 901 clear_bit(0, (void *)&p_ch->IO_active); 902 claw_clearbit_busy(TB_RETRY,dev); 903 if (test_and_set_bit(CLAW_BH_ACTIVE, 904 (void *)&p_ch->flag_a) == 0) { 905 tasklet_schedule(&p_ch->tasklet); 906 } 907 else { 908 CLAW_DBF_TEXT(4,trace,"RdBHAct"); 909 } 910 911#ifdef DEBUGMSG 912 printk(KERN_INFO "%s: process CLAW_START_READ exit\n", 913 dev->name); 914#endif 915#ifdef FUNCTRACE 916 printk(KERN_INFO "%s:%s Exit on line %d\n", 917 dev->name,__FUNCTION__,__LINE__); 918#endif 919 CLAW_DBF_TEXT(4,trace,"RdIRQXit"); 920 return; 921 case CLAW_START_WRITE: 922 if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { 923 printk(KERN_INFO "%s: Unit Check Occured in " 924 "write channel\n",dev->name); 925 clear_bit(0, (void *)&p_ch->IO_active); 926 if (p_ch->irb->ecw[0] & 0x80 ) { 927 printk(KERN_INFO "%s: Resetting Event " 928 "occurred:\n",dev->name); 929 init_timer(&p_ch->timer); 930 p_ch->timer.function = 931 (void *)claw_write_retry; 932 p_ch->timer.data = (unsigned long)p_ch; 933 p_ch->timer.expires = jiffies + 10*HZ; 934 add_timer(&p_ch->timer); 935 printk(KERN_INFO "%s: write connection " 936 "restarting\n",dev->name); 937 } 938#ifdef FUNCTRACE 939 printk(KERN_INFO "%s:%s Exit on line %d\n", 940 dev->name,__FUNCTION__,__LINE__); 941#endif 942 CLAW_DBF_TEXT(4,trace,"rstrtwrt"); 943 return; 944 } 945 if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) { 946 clear_bit(0, (void *)&p_ch->IO_active); 947 printk(KERN_INFO "%s: Unit Exception " 948 "Occured in write channel\n", 949 dev->name); 950 } 951 if(!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || 952 (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || 953 (p_ch->irb->scsw.stctl == 954 (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) { 955#ifdef FUNCTRACE 956 printk(KERN_INFO "%s:%s Exit on line %d\n", 957 dev->name,__FUNCTION__,__LINE__); 958#endif 959 CLAW_DBF_TEXT(4,trace,"writeUE"); 960 return; 961 } 962 clear_bit(0, (void *)&p_ch->IO_active); 963 if (claw_test_and_setbit_busy(TB_TX,dev)==0) { 964 claw_write_next(p_ch); 965 claw_clearbit_busy(TB_TX,dev); 966 claw_clear_busy(dev); 967 } 968 p_ch_r=(struct chbk *)&privptr->channel[READ]; 969 if (test_and_set_bit(CLAW_BH_ACTIVE, 970 (void *)&p_ch_r->flag_a) == 0) { 971 tasklet_schedule(&p_ch_r->tasklet); 972 } 973 974#ifdef DEBUGMSG 975 printk(KERN_INFO "%s: process CLAW_START_WRITE exit\n", 976 dev->name); 977#endif 978#ifdef FUNCTRACE 979 printk(KERN_INFO "%s:%s Exit on line %d\n", 980 dev->name,__FUNCTION__,__LINE__); 981#endif 982 CLAW_DBF_TEXT(4,trace,"StWtExit"); 983 return; 984 default: 985 printk(KERN_WARNING "%s: wrong selection code - irq " 986 "state=%d\n",dev->name,p_ch->claw_state); 987#ifdef FUNCTRACE 988 printk(KERN_INFO "%s:%s Exit on line %d\n", 989 dev->name,__FUNCTION__,__LINE__); 990#endif 991 CLAW_DBF_TEXT(2,trace,"badIRQ"); 992 return; 993 } 994 995} /* end of claw_irq_handler */ 996 997 998/*-------------------------------------------------------------------* 999* claw_irq_tasklet * 1000* * 1001*--------------------------------------------------------------------*/ 1002static void 1003claw_irq_tasklet ( unsigned long data ) 1004{ 1005 struct chbk * p_ch; 1006 struct net_device *dev; 1007 struct claw_privbk * privptr; 1008 1009 p_ch = (struct chbk *) data; 1010 dev = (struct net_device *)p_ch->ndev; 1011#ifdef FUNCTRACE 1012 printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__); 1013#endif 1014#ifdef DEBUGMSG 1015 printk(KERN_INFO "%s: variable p_ch =\n",dev->name); 1016 dumpit((char *) p_ch, sizeof(struct chbk)); 1017#endif 1018 CLAW_DBF_TEXT(4,trace,"IRQtask"); 1019 1020 privptr = (struct claw_privbk *) dev->priv; 1021 1022#ifdef DEBUGMSG 1023 printk(KERN_INFO "%s: bh routine - state-%02x\n" , 1024 dev->name, p_ch->claw_state); 1025#endif 1026 1027 unpack_read(dev); 1028 clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a); 1029 CLAW_DBF_TEXT(4,trace,"TskletXt"); 1030#ifdef FUNCTRACE 1031 printk(KERN_INFO "%s:%s Exit on line %d\n", 1032 dev->name,__FUNCTION__,__LINE__); 1033#endif 1034 return; 1035} /* end of claw_irq_bh */ 1036 1037/*-------------------------------------------------------------------* 1038* claw_release * 1039* * 1040*--------------------------------------------------------------------*/ 1041static int 1042claw_release(struct net_device *dev) 1043{ 1044 int rc; 1045 int i; 1046 unsigned long saveflags; 1047 unsigned long parm; 1048 struct claw_privbk *privptr; 1049 DECLARE_WAITQUEUE(wait, current); 1050 struct ccwbk* p_this_ccw; 1051 struct ccwbk* p_buf; 1052 1053 if (!dev) 1054 return 0; 1055 privptr = (struct claw_privbk *) dev->priv; 1056 if (!privptr) 1057 return 0; 1058#ifdef FUNCTRACE 1059 printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__); 1060#endif 1061 CLAW_DBF_TEXT(4,trace,"release"); 1062#ifdef DEBUGMSG 1063 printk(KERN_INFO "%s: variable dev =\n",dev->name); 1064 dumpit((char *) dev, sizeof(struct net_device)); 1065 printk(KERN_INFO "Priv Buffalloc %d\n",privptr->buffs_alloc); 1066 printk(KERN_INFO "Priv p_buff_ccw = %p\n",&privptr->p_buff_ccw); 1067#endif 1068 privptr->release_pend=1; 1069 claw_setbit_busy(TB_STOP,dev); 1070 for ( i = 1; i >=0 ; i--) { 1071 spin_lock_irqsave( 1072 get_ccwdev_lock(privptr->channel[i].cdev), saveflags); 1073 /* del_timer(&privptr->channel[READ].timer); */ 1074 privptr->channel[i].claw_state = CLAW_STOP; 1075 privptr->channel[i].IO_active = 0; 1076 parm = (unsigned long) &privptr->channel[i]; 1077 if (i == WRITE) 1078 claw_purge_skb_queue( 1079 &privptr->channel[WRITE].collect_queue); 1080 rc = ccw_device_halt (privptr->channel[i].cdev, parm); 1081 if (privptr->system_validate_comp==0x00) /* never opened? */ 1082 init_waitqueue_head(&privptr->channel[i].wait); 1083 add_wait_queue(&privptr->channel[i].wait, &wait); 1084 set_current_state(TASK_INTERRUPTIBLE); 1085 spin_unlock_irqrestore( 1086 get_ccwdev_lock(privptr->channel[i].cdev), saveflags); 1087 schedule(); 1088 set_current_state(TASK_RUNNING); 1089 remove_wait_queue(&privptr->channel[i].wait, &wait); 1090 if (rc != 0) { 1091 ccw_check_return_code(privptr->channel[i].cdev, rc); 1092 } 1093 } 1094 if (privptr->pk_skb != NULL) { 1095 dev_kfree_skb(privptr->pk_skb); 1096 privptr->pk_skb = NULL; 1097 } 1098 if(privptr->buffs_alloc != 1) { 1099#ifdef FUNCTRACE 1100 printk(KERN_INFO "%s:%s Exit on line %d\n", 1101 dev->name,__FUNCTION__,__LINE__); 1102#endif 1103 CLAW_DBF_TEXT(4,trace,"none2fre"); 1104 return 0; 1105 } 1106 CLAW_DBF_TEXT(4,trace,"freebufs"); 1107 if (privptr->p_buff_ccw != NULL) { 1108 free_pages((unsigned long)privptr->p_buff_ccw, 1109 (int)pages_to_order_of_mag(privptr->p_buff_ccw_num)); 1110 } 1111 CLAW_DBF_TEXT(4,trace,"freeread"); 1112 if (privptr->p_env->read_size < PAGE_SIZE) { 1113 if (privptr->p_buff_read != NULL) { 1114 free_pages((unsigned long)privptr->p_buff_read, 1115 (int)pages_to_order_of_mag(privptr->p_buff_read_num)); 1116 } 1117 } 1118 else { 1119 p_buf=privptr->p_read_active_first; 1120 while (p_buf!=NULL) { 1121 free_pages((unsigned long)p_buf->p_buffer, 1122 (int)pages_to_order_of_mag( 1123 privptr->p_buff_pages_perread )); 1124 p_buf=p_buf->next; 1125 } 1126 } 1127 CLAW_DBF_TEXT(4,trace,"freewrit"); 1128 if (privptr->p_env->write_size < PAGE_SIZE ) { 1129 free_pages((unsigned long)privptr->p_buff_write, 1130 (int)pages_to_order_of_mag(privptr->p_buff_write_num)); 1131 } 1132 else { 1133 p_buf=privptr->p_write_active_first; 1134 while (p_buf!=NULL) { 1135 free_pages((unsigned long)p_buf->p_buffer, 1136 (int)pages_to_order_of_mag( 1137 privptr->p_buff_pages_perwrite )); 1138 p_buf=p_buf->next; 1139 } 1140 } 1141 CLAW_DBF_TEXT(4,trace,"clearptr"); 1142 privptr->buffs_alloc = 0; 1143 privptr->p_buff_ccw=NULL; 1144 privptr->p_buff_read=NULL; 1145 privptr->p_buff_write=NULL; 1146 privptr->system_validate_comp=0; 1147 privptr->release_pend=0; 1148 /* Remove any writes that were pending and reset all reads */ 1149 p_this_ccw=privptr->p_read_active_first; 1150 while (p_this_ccw!=NULL) { 1151 p_this_ccw->header.length=0xffff; 1152 p_this_ccw->header.opcode=0xff; 1153 p_this_ccw->header.flag=0x00; 1154 p_this_ccw=p_this_ccw->next; 1155 } 1156 1157 while (privptr->p_write_active_first!=NULL) { 1158 p_this_ccw=privptr->p_write_active_first; 1159 p_this_ccw->header.flag=CLAW_PENDING; 1160 privptr->p_write_active_first=p_this_ccw->next; 1161 p_this_ccw->next=privptr->p_write_free_chain; 1162 privptr->p_write_free_chain=p_this_ccw; 1163 ++privptr->write_free_count; 1164 } 1165 privptr->p_write_active_last=NULL; 1166 privptr->mtc_logical_link = -1; 1167 privptr->mtc_skipping = 1; 1168 privptr->mtc_offset=0; 1169 1170 if (((privptr->channel[READ].last_dstat | 1171 privptr->channel[WRITE].last_dstat) & 1172 ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) { 1173 printk(KERN_WARNING "%s: channel problems during close - " 1174 "read: %02x - write: %02x\n", 1175 dev->name, 1176 privptr->channel[READ].last_dstat, 1177 privptr->channel[WRITE].last_dstat); 1178 CLAW_DBF_TEXT(2,trace,"badclose"); 1179 } 1180#ifdef FUNCTRACE 1181 printk(KERN_INFO "%s:%s Exit on line %d\n", 1182 dev->name,__FUNCTION__,__LINE__); 1183#endif 1184 CLAW_DBF_TEXT(4,trace,"rlsexit"); 1185 return 0; 1186} /* end of claw_release */ 1187 1188 1189 1190/*-------------------------------------------------------------------* 1191* claw_write_retry * 1192* * 1193*--------------------------------------------------------------------*/ 1194 1195static void 1196claw_write_retry ( struct chbk *p_ch ) 1197{ 1198 1199 struct net_device *dev=p_ch->ndev; 1200 1201 1202#ifdef FUNCTRACE 1203 printk(KERN_INFO "%s:%s Enter\n",dev->name,__FUNCTION__); 1204 printk(KERN_INFO "claw: variable p_ch =\n"); 1205 dumpit((char *) p_ch, sizeof(struct chbk)); 1206#endif 1207 CLAW_DBF_TEXT(4,trace,"w_retry"); 1208 if (p_ch->claw_state == CLAW_STOP) { 1209#ifdef FUNCTRACE 1210 printk(KERN_INFO "%s:%s Exit on line %d\n", 1211 dev->name,__FUNCTION__,__LINE__); 1212#endif 1213 return; 1214 } 1215#ifdef DEBUGMSG 1216 printk( KERN_INFO "%s:%s state-%02x\n" , 1217 dev->name, 1218 __FUNCTION__, 1219 p_ch->claw_state); 1220#endif 1221 claw_strt_out_IO( dev ); 1222#ifdef FUNCTRACE 1223 printk(KERN_INFO "%s:%s Exit on line %d\n", 1224 dev->name,__FUNCTION__,__LINE__); 1225#endif 1226 CLAW_DBF_TEXT(4,trace,"rtry_xit"); 1227 return; 1228} /* end of claw_write_retry */ 1229 1230 1231/*-------------------------------------------------------------------* 1232* claw_write_next * 1233* * 1234*--------------------------------------------------------------------*/ 1235 1236static void 1237claw_write_next ( struct chbk * p_ch ) 1238{ 1239 1240 struct net_device *dev; 1241 struct claw_privbk *privptr=NULL; 1242 struct sk_buff *pk_skb; 1243 int rc; 1244 1245#ifdef FUNCTRACE 1246 printk(KERN_INFO "%s:%s Enter \n",p_ch->ndev->name,__FUNCTION__); 1247 printk(KERN_INFO "%s: variable p_ch =\n",p_ch->ndev->name); 1248 dumpit((char *) p_ch, sizeof(struct chbk)); 1249#endif 1250 CLAW_DBF_TEXT(4,trace,"claw_wrt"); 1251 if (p_ch->claw_state == CLAW_STOP) 1252 return; 1253 dev = (struct net_device *) p_ch->ndev; 1254 privptr = (struct claw_privbk *) dev->priv; 1255 claw_free_wrt_buf( dev ); 1256 if ((privptr->write_free_count > 0) && 1257 (skb_queue_len(&p_ch->collect_queue) > 0)) { 1258 pk_skb = claw_pack_skb(privptr); 1259 while (pk_skb != NULL) { 1260 rc = claw_hw_tx( pk_skb, dev,1); 1261 if (privptr->write_free_count > 0) { 1262 pk_skb = claw_pack_skb(privptr); 1263 } else 1264 pk_skb = NULL; 1265 } 1266 } 1267 if (privptr->p_write_active_first!=NULL) { 1268 claw_strt_out_IO(dev); 1269 } 1270 1271#ifdef FUNCTRACE 1272 printk(KERN_INFO "%s:%s Exit on line %d\n", 1273 dev->name,__FUNCTION__,__LINE__); 1274#endif 1275 return; 1276} /* end of claw_write_next */ 1277 1278/*-------------------------------------------------------------------* 1279* * 1280* claw_timer * 1281*--------------------------------------------------------------------*/ 1282 1283static void 1284claw_timer ( struct chbk * p_ch ) 1285{ 1286#ifdef FUNCTRACE 1287 printk(KERN_INFO "%s:%s Entry\n",p_ch->ndev->name,__FUNCTION__); 1288 printk(KERN_INFO "%s: variable p_ch =\n",p_ch->ndev->name); 1289 dumpit((char *) p_ch, sizeof(struct chbk)); 1290#endif 1291 CLAW_DBF_TEXT(4,trace,"timer"); 1292 p_ch->flag |= CLAW_TIMER; 1293 wake_up(&p_ch->wait); 1294#ifdef FUNCTRACE 1295 printk(KERN_INFO "%s:%s Exit on line %d\n", 1296 p_ch->ndev->name,__FUNCTION__,__LINE__); 1297#endif 1298 return; 1299} /* end of claw_timer */ 1300 1301 1302/* 1303* 1304* functions 1305*/ 1306 1307 1308/*-------------------------------------------------------------------* 1309* * 1310* pages_to_order_of_mag * 1311* * 1312* takes a number of pages from 1 to 512 and returns the * 1313* log(num_pages)/log(2) get_free_pages() needs a base 2 order * 1314* of magnitude get_free_pages() has an upper order of 9 * 1315*--------------------------------------------------------------------*/ 1316 1317static int inline 1318pages_to_order_of_mag(int num_of_pages) 1319{ 1320 int order_of_mag=1; /* assume 2 pages */ 1321 int nump=2; 1322#ifdef FUNCTRACE 1323 printk(KERN_INFO "%s Enter pages = %d \n",__FUNCTION__,num_of_pages); 1324#endif 1325 CLAW_DBF_TEXT_(5,trace,"pages%d",num_of_pages); 1326 if (num_of_pages == 1) {return 0; } /* magnitude of 0 = 1 page */ 1327 /* 512 pages = 2Meg on 4k page systems */ 1328 if (num_of_pages >= 512) {return 9; } 1329 /* we have two or more pages order is at least 1 */ 1330 for (nump=2 ;nump <= 512;nump*=2) { 1331 if (num_of_pages <= nump) 1332 break; 1333 order_of_mag +=1; 1334 } 1335 if (order_of_mag > 9) { order_of_mag = 9; } /* I know it's paranoid */ 1336#ifdef FUNCTRACE 1337 printk(KERN_INFO "%s Exit on line %d, order = %d\n", 1338 __FUNCTION__,__LINE__, order_of_mag); 1339#endif 1340 CLAW_DBF_TEXT_(5,trace,"mag%d",order_of_mag); 1341 return order_of_mag; 1342} 1343 1344/*-------------------------------------------------------------------* 1345* * 1346* add_claw_reads * 1347* * 1348*--------------------------------------------------------------------*/ 1349static int 1350add_claw_reads(struct net_device *dev, struct ccwbk* p_first, 1351 struct ccwbk* p_last) 1352{ 1353 struct claw_privbk *privptr; 1354 struct ccw1 temp_ccw; 1355 struct endccw * p_end; 1356#ifdef IOTRACE 1357 struct ccwbk* p_buf; 1358#endif 1359#ifdef FUNCTRACE 1360 printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__); 1361#endif 1362#ifdef DEBUGMSG 1363 printk(KERN_INFO "dev\n"); 1364 dumpit((char *) dev, sizeof(struct net_device)); 1365 printk(KERN_INFO "p_first\n"); 1366 dumpit((char *) p_first, sizeof(struct ccwbk)); 1367 printk(KERN_INFO "p_last\n"); 1368 dumpit((char *) p_last, sizeof(struct ccwbk)); 1369#endif 1370 CLAW_DBF_TEXT(4,trace,"addreads"); 1371 privptr = dev->priv; 1372 p_end = privptr->p_end_ccw; 1373 1374 /* first CCW and last CCW contains a new set of read channel programs 1375 * to apend the running channel programs 1376 */ 1377 if ( p_first==NULL) { 1378#ifdef FUNCTRACE 1379 printk(KERN_INFO "%s:%s Exit on line %d\n", 1380 dev->name,__FUNCTION__,__LINE__); 1381#endif 1382 CLAW_DBF_TEXT(4,trace,"addexit"); 1383 return 0; 1384 } 1385 1386 /* set up ending CCW sequence for this segment */ 1387 if (p_end->read1) { 1388 p_end->read1=0x00; /* second ending CCW is now active */ 1389 /* reset ending CCWs and setup TIC CCWs */ 1390 p_end->read2_nop2.cmd_code = CCW_CLAW_CMD_READFF; 1391 p_end->read2_nop2.flags = CCW_FLAG_SLI | CCW_FLAG_SKIP; 1392 p_last->r_TIC_1.cda =(__u32)__pa(&p_end->read2_nop1); 1393 p_last->r_TIC_2.cda =(__u32)__pa(&p_end->read2_nop1); 1394 p_end->read2_nop2.cda=0; 1395 p_end->read2_nop2.count=1; 1396 } 1397 else { 1398 p_end->read1=0x01; /* first ending CCW is now active */ 1399 /* reset ending CCWs and setup TIC CCWs */ 1400 p_end->read1_nop2.cmd_code = CCW_CLAW_CMD_READFF; 1401 p_end->read1_nop2.flags = CCW_FLAG_SLI | CCW_FLAG_SKIP; 1402 p_last->r_TIC_1.cda = (__u32)__pa(&p_end->read1_nop1); 1403 p_last->r_TIC_2.cda = (__u32)__pa(&p_end->read1_nop1); 1404 p_end->read1_nop2.cda=0; 1405 p_end->read1_nop2.count=1; 1406 } 1407 1408 if ( privptr-> p_read_active_first ==NULL ) { 1409#ifdef DEBUGMSG 1410 printk(KERN_INFO "%s:%s p_read_active_frist == NULL \n", 1411 dev->name,__FUNCTION__); 1412 printk(KERN_INFO "%s:%s Read active first/last changed \n", 1413 dev->name,__FUNCTION__); 1414#endif 1415 privptr-> p_read_active_first= p_first; /* set new first */ 1416 privptr-> p_read_active_last = p_last; /* set new last */ 1417 } 1418 else { 1419 1420#ifdef DEBUGMSG 1421 printk(KERN_INFO "%s:%s Read in progress \n", 1422 dev->name,__FUNCTION__); 1423#endif 1424 /* set up TIC ccw */ 1425 temp_ccw.cda= (__u32)__pa(&p_first->read); 1426 temp_ccw.count=0; 1427 temp_ccw.flags=0; 1428 temp_ccw.cmd_code = CCW_CLAW_CMD_TIC; 1429 1430 1431 if (p_end->read1) { 1432 1433 /* first set of CCW's is chained to the new read */ 1434 /* chain, so the second set is chained to the active chain. */ 1435 /* Therefore modify the second set to point to the new */ 1436 /* read chain set up TIC CCWs */ 1437 /* make sure we update the CCW so channel doesn't fetch it */ 1438 /* when it's only half done */ 1439 memcpy( &p_end->read2_nop2, &temp_ccw , 1440 sizeof(struct ccw1)); 1441 privptr->p_read_active_last->r_TIC_1.cda= 1442 (__u32)__pa(&p_first->read); 1443 privptr->p_read_active_last->r_TIC_2.cda= 1444 (__u32)__pa(&p_first->read); 1445 } 1446 else { 1447 /* make sure we update the CCW so channel doesn't */ 1448 /* fetch it when it is only half done */ 1449 memcpy( &p_end->read1_nop2, &temp_ccw , 1450 sizeof(struct ccw1)); 1451 privptr->p_read_active_last->r_TIC_1.cda= 1452 (__u32)__pa(&p_first->read); 1453 privptr->p_read_active_last->r_TIC_2.cda= 1454 (__u32)__pa(&p_first->read); 1455 } 1456 /* chain in new set of blocks */ 1457 privptr->p_read_active_last->next = p_first; 1458 privptr->p_read_active_last=p_last; 1459 } /* end of if ( privptr-> p_read_active_first ==NULL) */ 1460#ifdef IOTRACE 1461 printk(KERN_INFO "%s:%s dump p_last CCW BK \n",dev->name,__FUNCTION__); 1462 dumpit((char *)p_last, sizeof(struct ccwbk)); 1463 printk(KERN_INFO "%s:%s dump p_end CCW BK \n",dev->name,__FUNCTION__); 1464 dumpit((char *)p_end, sizeof(struct endccw)); 1465 1466 printk(KERN_INFO "%s:%s dump p_first CCW BK \n",dev->name,__FUNCTION__); 1467 dumpit((char *)p_first, sizeof(struct ccwbk)); 1468 printk(KERN_INFO "%s:%s Dump Active CCW chain \n", 1469 dev->name,__FUNCTION__); 1470 p_buf=privptr->p_read_active_first; 1471 while (p_buf!=NULL) { 1472 dumpit((char *)p_buf, sizeof(struct ccwbk)); 1473 p_buf=p_buf->next; 1474 } 1475#endif 1476#ifdef FUNCTRACE 1477 printk(KERN_INFO "%s:%s Exit on line %d\n", 1478 dev->name,__FUNCTION__,__LINE__); 1479#endif 1480 CLAW_DBF_TEXT(4,trace,"addexit"); 1481 return 0; 1482} /* end of add_claw_reads */ 1483 1484/*-------------------------------------------------------------------* 1485 * ccw_check_return_code * 1486 * * 1487 *-------------------------------------------------------------------*/ 1488 1489static void inline 1490ccw_check_return_code(struct ccw_device *cdev, int return_code) 1491{ 1492#ifdef FUNCTRACE 1493 printk(KERN_INFO "%s: %s() > enter \n", 1494 cdev->dev.bus_id,__FUNCTION__); 1495#endif 1496 CLAW_DBF_TEXT(4,trace,"ccwret"); 1497#ifdef DEBUGMSG 1498 printk(KERN_INFO "variable cdev =\n"); 1499 dumpit((char *) cdev, sizeof(struct ccw_device)); 1500 printk(KERN_INFO "variable return_code = %d\n",return_code); 1501#endif 1502 if (return_code != 0) { 1503 switch (return_code) { 1504 case -EBUSY: 1505 printk(KERN_INFO "%s: Busy !\n", 1506 cdev->dev.bus_id); 1507 break; 1508 case -ENODEV: 1509 printk(KERN_EMERG "%s: Missing device called " 1510 "for IO ENODEV\n", cdev->dev.bus_id); 1511 break; 1512 case -EIO: 1513 printk(KERN_EMERG "%s: Status pending... EIO \n", 1514 cdev->dev.bus_id); 1515 break; 1516 case -EINVAL: 1517 printk(KERN_EMERG "%s: Invalid Dev State EINVAL \n", 1518 cdev->dev.bus_id); 1519 break; 1520 default: 1521 printk(KERN_EMERG "%s: Unknown error in " 1522 "Do_IO %d\n",cdev->dev.bus_id, return_code); 1523 } 1524 } 1525#ifdef FUNCTRACE 1526 printk(KERN_INFO "%s: %s() > exit on line %d\n", 1527 cdev->dev.bus_id,__FUNCTION__,__LINE__); 1528#endif 1529 CLAW_DBF_TEXT(4,trace,"ccwret"); 1530} /* end of ccw_check_return_code */ 1531 1532/*-------------------------------------------------------------------* 1533* ccw_check_unit_check * 1534*--------------------------------------------------------------------*/ 1535 1536static void inline 1537ccw_check_unit_check(struct chbk * p_ch, unsigned char sense ) 1538{ 1539 struct net_device *dev = p_ch->ndev; 1540 1541#ifdef FUNCTRACE 1542 printk(KERN_INFO "%s: %s() > enter\n",dev->name,__FUNCTION__); 1543#endif 1544#ifdef DEBUGMSG 1545 printk(KERN_INFO "%s: variable dev =\n",dev->name); 1546 dumpit((char *)dev, sizeof(struct net_device)); 1547 printk(KERN_INFO "%s: variable sense =\n",dev->name); 1548 dumpit((char *)&sense, 2); 1549#endif 1550 CLAW_DBF_TEXT(4,trace,"unitchek"); 1551 1552 printk(KERN_INFO "%s: Unit Check with sense byte:0x%04x\n", 1553 dev->name, sense); 1554 1555 if (sense & 0x40) { 1556 if (sense & 0x01) { 1557 printk(KERN_WARNING "%s: Interface disconnect or " 1558 "Selective reset " 1559 "occurred (remote side)\n", dev->name); 1560 } 1561 else { 1562 printk(KERN_WARNING "%s: System reset occured" 1563 " (remote side)\n", dev->name); 1564 } 1565 } 1566 else if (sense & 0x20) { 1567 if (sense & 0x04) { 1568 printk(KERN_WARNING "%s: Data-streaming " 1569 "timeout)\n", dev->name); 1570 } 1571 else { 1572 printk(KERN_WARNING "%s: Data-transfer parity" 1573 " error\n", dev->name); 1574 } 1575 } 1576 else if (sense & 0x10) { 1577 if (sense & 0x20) { 1578 printk(KERN_WARNING "%s: Hardware malfunction " 1579 "(remote side)\n", dev->name); 1580 } 1581 else { 1582 printk(KERN_WARNING "%s: read-data parity error " 1583 "(remote side)\n", dev->name); 1584 } 1585 } 1586 1587#ifdef FUNCTRACE 1588 printk(KERN_INFO "%s: %s() exit on line %d\n", 1589 dev->name,__FUNCTION__,__LINE__); 1590#endif 1591} /* end of ccw_check_unit_check */ 1592 1593 1594 1595/*-------------------------------------------------------------------* 1596* Dump buffer format * 1597* * 1598*--------------------------------------------------------------------*/ 1599#ifdef DEBUG 1600static void 1601dumpit(char* buf, int len) 1602{ 1603 1604 __u32 ct, sw, rm, dup; 1605 char *ptr, *rptr; 1606 char tbuf[82], tdup[82]; 1607#if (CONFIG_ARCH_S390X) 1608 char addr[22]; 1609#else 1610 char addr[12]; 1611#endif 1612 char boff[12]; 1613 char bhex[82], duphex[82]; 1614 char basc[40]; 1615 1616 sw = 0; 1617 rptr =ptr=buf; 1618 rm = 16; 1619 duphex[0] = 0x00; 1620 dup = 0; 1621 for ( ct=0; ct < len; ct++, ptr++, rptr++ ) { 1622 if (sw == 0) { 1623#if (CONFIG_ARCH_S390X) 1624 sprintf(addr, "%16.16lX",(unsigned long)rptr); 1625#else 1626 sprintf(addr, "%8.8X",(__u32)rptr); 1627#endif 1628 sprintf(boff, "%4.4X", (__u32)ct); 1629 bhex[0] = '\0'; 1630 basc[0] = '\0'; 1631 } 1632 if ((sw == 4) || (sw == 12)) { 1633 strcat(bhex, " "); 1634 } 1635 if (sw == 8) { 1636 strcat(bhex, " "); 1637 } 1638#if (CONFIG_ARCH_S390X) 1639 sprintf(tbuf,"%2.2lX", (unsigned long)*ptr); 1640#else 1641 sprintf(tbuf,"%2.2X", (__u32)*ptr); 1642#endif 1643 tbuf[2] = '\0'; 1644 strcat(bhex, tbuf); 1645 if ((0!=isprint(*ptr)) && (*ptr >= 0x20)) { 1646 basc[sw] = *ptr; 1647 } 1648 else { 1649 basc[sw] = '.'; 1650 } 1651 basc[sw+1] = '\0'; 1652 sw++; 1653 rm--; 1654 if (sw==16) { 1655 if ((strcmp(duphex, bhex)) !=0) { 1656 if (dup !=0) { 1657 sprintf(tdup,"Duplicate as above to" 1658 " %s", addr); 1659 printk( KERN_INFO " " 1660 " --- %s ---\n",tdup); 1661 } 1662 printk( KERN_INFO " %s (+%s) : %s [%s]\n", 1663 addr, boff, bhex, basc); 1664 dup = 0; 1665 strcpy(duphex, bhex); 1666 } 1667 else { 1668 dup++; 1669 } 1670 sw = 0; 1671 rm = 16; 1672 } 1673 } /* endfor */ 1674 1675 if (sw != 0) { 1676 for ( ; rm > 0; rm--, sw++ ) { 1677 if ((sw==4) || (sw==12)) strcat(bhex, " "); 1678 if (sw==8) strcat(bhex, " "); 1679 strcat(bhex, " "); 1680 strcat(basc, " "); 1681 } 1682 if (dup !=0) { 1683 sprintf(tdup,"Duplicate as above to %s", addr); 1684 printk( KERN_INFO " --- %s ---\n", 1685 tdup); 1686 } 1687 printk( KERN_INFO " %s (+%s) : %s [%s]\n", 1688 addr, boff, bhex, basc); 1689 } 1690 else { 1691 if (dup >=1) { 1692 sprintf(tdup,"Duplicate as above to %s", addr); 1693 printk( KERN_INFO " --- %s ---\n", 1694 tdup); 1695 } 1696 if (dup !=0) { 1697 printk( KERN_INFO " %s (+%s) : %s [%s]\n", 1698 addr, boff, bhex, basc); 1699 } 1700 } 1701 return; 1702 1703} /* end of dumpit */ 1704#endif 1705 1706/*-------------------------------------------------------------------* 1707* find_link * 1708*--------------------------------------------------------------------*/ 1709static int 1710find_link(struct net_device *dev, char *host_name, char *ws_name ) 1711{ 1712 struct claw_privbk *privptr; 1713 struct claw_env *p_env; 1714 int rc=0; 1715 1716#ifdef FUNCTRACE 1717 printk(KERN_INFO "%s:%s > enter \n",dev->name,__FUNCTION__); 1718#endif 1719 CLAW_DBF_TEXT(2,setup,"findlink"); 1720#ifdef DEBUGMSG 1721 printk(KERN_INFO "%s: variable dev = \n",dev->name); 1722 dumpit((char *) dev, sizeof(struct net_device)); 1723 printk(KERN_INFO "%s: variable host_name = %s\n",dev->name, host_name); 1724 printk(KERN_INFO "%s: variable ws_name = %s\n",dev->name, ws_name); 1725#endif 1726 privptr=dev->priv; 1727 p_env=privptr->p_env; 1728 switch (p_env->packing) 1729 { 1730 case PACKING_ASK: 1731 if ((memcmp(WS_APPL_NAME_PACKED, host_name, 8)!=0) || 1732 (memcmp(WS_APPL_NAME_PACKED, ws_name, 8)!=0 )) 1733 rc = EINVAL; 1734 break; 1735 case DO_PACKED: 1736 case PACK_SEND: 1737 if ((memcmp(WS_APPL_NAME_IP_NAME, host_name, 8)!=0) || 1738 (memcmp(WS_APPL_NAME_IP_NAME, ws_name, 8)!=0 )) 1739 rc = EINVAL; 1740 break; 1741 default: 1742 if ((memcmp(HOST_APPL_NAME, host_name, 8)!=0) || 1743 (memcmp(p_env->api_type , ws_name, 8)!=0)) 1744 rc = EINVAL; 1745 break; 1746 } 1747 1748#ifdef FUNCTRACE 1749 printk(KERN_INFO "%s:%s Exit on line %d\n", 1750 dev->name,__FUNCTION__,__LINE__); 1751#endif 1752 return 0; 1753} /* end of find_link */ 1754 1755/*-------------------------------------------------------------------* 1756 * claw_hw_tx * 1757 * * 1758 * * 1759 *-------------------------------------------------------------------*/ 1760 1761static int 1762claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid) 1763{ 1764 int rc=0; 1765 struct claw_privbk *privptr; 1766 struct ccwbk *p_this_ccw; 1767 struct ccwbk *p_first_ccw; 1768 struct ccwbk *p_last_ccw; 1769 __u32 numBuffers; 1770 signed long len_of_data; 1771 unsigned long bytesInThisBuffer; 1772 unsigned char *pDataAddress; 1773 struct endccw *pEnd; 1774 struct ccw1 tempCCW; 1775 struct chbk *p_ch; 1776 struct claw_env *p_env; 1777 int lock; 1778 struct clawph *pk_head; 1779 struct chbk *ch; 1780#ifdef IOTRACE 1781 struct ccwbk *p_buf; 1782#endif 1783#ifdef FUNCTRACE 1784 printk(KERN_INFO "%s: %s() > enter\n",dev->name,__FUNCTION__); 1785#endif 1786 CLAW_DBF_TEXT(4,trace,"hw_tx"); 1787#ifdef DEBUGMSG 1788 printk(KERN_INFO "%s: variable dev skb =\n",dev->name); 1789 dumpit((char *) skb, sizeof(struct sk_buff)); 1790 printk(KERN_INFO "%s: variable dev =\n",dev->name); 1791 dumpit((char *) dev, sizeof(struct net_device)); 1792 printk(KERN_INFO "%s: variable linkid = %ld\n",dev->name,linkid); 1793#endif 1794 privptr = (struct claw_privbk *) (dev->priv); 1795 p_ch=(struct chbk *)&privptr->channel[WRITE]; 1796 p_env =privptr->p_env; 1797#ifdef IOTRACE 1798 printk(KERN_INFO "%s: %s() dump sk_buff \n",dev->name,__FUNCTION__); 1799 dumpit((char *)skb ,sizeof(struct sk_buff)); 1800#endif 1801 claw_free_wrt_buf(dev); /* Clean up free chain if posible */ 1802 /* scan the write queue to free any completed write packets */ 1803 p_first_ccw=NULL; 1804 p_last_ccw=NULL; 1805 if ((p_env->packing >= PACK_SEND) && 1806 (skb->cb[1] != 'P')) { 1807 skb_push(skb,sizeof(struct clawph)); 1808 pk_head=(struct clawph *)skb->data; 1809 pk_head->len=skb->len-sizeof(struct clawph); 1810 if (pk_head->len%4) { 1811 pk_head->len+= 4-(pk_head->len%4); 1812 skb_pad(skb,4-(pk_head->len%4)); 1813 skb_put(skb,4-(pk_head->len%4)); 1814 } 1815 if (p_env->packing == DO_PACKED) 1816 pk_head->link_num = linkid; 1817 else 1818 pk_head->link_num = 0; 1819 pk_head->flag = 0x00; 1820 skb_pad(skb,4); 1821 skb->cb[1] = 'P'; 1822 } 1823 if (linkid == 0) { 1824 if (claw_check_busy(dev)) { 1825 if (privptr->write_free_count!=0) { 1826 claw_clear_busy(dev); 1827 } 1828 else { 1829 claw_strt_out_IO(dev ); 1830 claw_free_wrt_buf( dev ); 1831 if (privptr->write_free_count==0) { 1832#ifdef IOTRACE 1833 printk(KERN_INFO "%s: " 1834 "(claw_check_busy) no free write " 1835 "buffers\n", dev->name); 1836#endif 1837 ch = &privptr->channel[WRITE]; 1838 atomic_inc(&skb->users); 1839 skb_queue_tail(&ch->collect_queue, skb); 1840 goto Done; 1841 } 1842 else { 1843 claw_clear_busy(dev); 1844 } 1845 } 1846 } 1847 /* tx lock */ 1848 if (claw_test_and_setbit_busy(TB_TX,dev)) { /* set to busy */ 1849#ifdef DEBUGMSG 1850 printk(KERN_INFO "%s: busy (claw_test_and_setbit_" 1851 "busy)\n", dev->name); 1852#endif 1853 ch = &privptr->channel[WRITE]; 1854 atomic_inc(&skb->users); 1855 skb_queue_tail(&ch->collect_queue, skb); 1856 claw_strt_out_IO(dev ); 1857 rc=-EBUSY; 1858 goto Done2; 1859 } 1860 } 1861 /* See how many write buffers are required to hold this data */ 1862 numBuffers= ( skb->len + privptr->p_env->write_size - 1) / 1863 ( privptr->p_env->write_size); 1864 1865 /* If that number of buffers isn't available, give up for now */ 1866 if (privptr->write_free_count < numBuffers || 1867 privptr->p_write_free_chain == NULL ) { 1868 1869 claw_setbit_busy(TB_NOBUFFER,dev); 1870 1871#ifdef DEBUGMSG 1872 printk(KERN_INFO "%s: busy (claw_setbit_busy" 1873 "(TB_NOBUFFER))\n", dev->name); 1874 printk(KERN_INFO " free_count: %d, numBuffers : %d\n", 1875 (int)privptr->write_free_count,(int) numBuffers ); 1876#endif 1877 ch = &privptr->channel[WRITE]; 1878 atomic_inc(&skb->users); 1879 skb_queue_tail(&ch->collect_queue, skb); 1880 CLAW_DBF_TEXT(2,trace,"clawbusy"); 1881 goto Done2; 1882 } 1883 pDataAddress=skb->data; 1884 len_of_data=skb->len; 1885 1886 while (len_of_data > 0) { 1887#ifdef DEBUGMSG 1888 printk(KERN_INFO "%s: %s() length-of-data is %ld \n", 1889 dev->name ,__FUNCTION__,len_of_data); 1890 dumpit((char *)pDataAddress ,64); 1891#endif 1892 p_this_ccw=privptr->p_write_free_chain; /* get a block */ 1893 if (p_this_ccw == NULL) { /* lost the race */ 1894 ch = &privptr->channel[WRITE]; 1895 atomic_inc(&skb->users); 1896 skb_queue_tail(&ch->collect_queue, skb); 1897 goto Done2; 1898 } 1899 privptr->p_write_free_chain=p_this_ccw->next; 1900 p_this_ccw->next=NULL; 1901 --privptr->write_free_count; /* -1 */ 1902 bytesInThisBuffer=len_of_data; 1903 memcpy( p_this_ccw->p_buffer,pDataAddress, bytesInThisBuffer); 1904 len_of_data-=bytesInThisBuffer; 1905 pDataAddress+=(unsigned long)bytesInThisBuffer; 1906 /* setup write CCW */ 1907 p_this_ccw->write.cmd_code = (linkid * 8) +1; 1908 if (len_of_data>0) { 1909 p_this_ccw->write.cmd_code+=MORE_to_COME_FLAG; 1910 } 1911 p_this_ccw->write.count=bytesInThisBuffer; 1912 /* now add to end of this chain */ 1913 if (p_first_ccw==NULL) { 1914 p_first_ccw=p_this_ccw; 1915 } 1916 if (p_last_ccw!=NULL) { 1917 p_last_ccw->next=p_this_ccw; 1918 /* set up TIC ccws */ 1919 p_last_ccw->w_TIC_1.cda= 1920 (__u32)__pa(&p_this_ccw->write); 1921 } 1922 p_last_ccw=p_this_ccw; /* save new last block */ 1923#ifdef IOTRACE 1924 printk(KERN_INFO "%s: %s() > CCW and Buffer %ld bytes long \n", 1925 dev->name,__FUNCTION__,bytesInThisBuffer); 1926 dumpit((char *)p_this_ccw, sizeof(struct ccwbk)); 1927 dumpit((char *)p_this_ccw->p_buffer, 64); 1928#endif 1929 } 1930 1931 /* FirstCCW and LastCCW now contain a new set of write channel 1932 * programs to append to the running channel program 1933 */ 1934 1935 if (p_first_ccw!=NULL) { 1936 /* setup ending ccw sequence for this segment */ 1937 pEnd=privptr->p_end_ccw; 1938 if (pEnd->write1) { 1939 pEnd->write1=0x00; /* second end ccw is now active */ 1940 /* set up Tic CCWs */ 1941 p_last_ccw->w_TIC_1.cda= 1942 (__u32)__pa(&pEnd->write2_nop1); 1943 pEnd->write2_nop2.cmd_code = CCW_CLAW_CMD_READFF; 1944 pEnd->write2_nop2.flags = 1945 CCW_FLAG_SLI | CCW_FLAG_SKIP; 1946 pEnd->write2_nop2.cda=0; 1947 pEnd->write2_nop2.count=1; 1948 } 1949 else { /* end of if (pEnd->write1)*/ 1950 pEnd->write1=0x01; /* first end ccw is now active */ 1951 /* set up Tic CCWs */ 1952 p_last_ccw->w_TIC_1.cda= 1953 (__u32)__pa(&pEnd->write1_nop1); 1954 pEnd->write1_nop2.cmd_code = CCW_CLAW_CMD_READFF; 1955 pEnd->write1_nop2.flags = 1956 CCW_FLAG_SLI | CCW_FLAG_SKIP; 1957 pEnd->write1_nop2.cda=0; 1958 pEnd->write1_nop2.count=1; 1959 } /* end if if (pEnd->write1) */ 1960 1961 1962 if (privptr->p_write_active_first==NULL ) { 1963 privptr->p_write_active_first=p_first_ccw; 1964 privptr->p_write_active_last=p_last_ccw; 1965 } 1966 else { 1967 1968 /* set up Tic CCWs */ 1969 1970 tempCCW.cda=(__u32)__pa(&p_first_ccw->write); 1971 tempCCW.count=0; 1972 tempCCW.flags=0; 1973 tempCCW.cmd_code=CCW_CLAW_CMD_TIC; 1974 1975 if (pEnd->write1) { 1976 1977 /* 1978 * first set of ending CCW's is chained to the new write 1979 * chain, so the second set is chained to the active chain 1980 * Therefore modify the second set to point the new write chain. 1981 * make sure we update the CCW atomically 1982 * so channel does not fetch it when it's only half done 1983 */ 1984 memcpy( &pEnd->write2_nop2, &tempCCW , 1985 sizeof(struct ccw1)); 1986 privptr->p_write_active_last->w_TIC_1.cda= 1987 (__u32)__pa(&p_first_ccw->write); 1988 } 1989 else { 1990 1991 /*make sure we update the CCW atomically 1992 *so channel does not fetch it when it's only half done 1993 */ 1994 memcpy(&pEnd->write1_nop2, &tempCCW , 1995 sizeof(struct ccw1)); 1996 privptr->p_write_active_last->w_TIC_1.cda= 1997 (__u32)__pa(&p_first_ccw->write); 1998 1999 } /* end if if (pEnd->write1) */ 2000 2001 privptr->p_write_active_last->next=p_first_ccw; 2002 privptr->p_write_active_last=p_last_ccw; 2003 } 2004 2005 } /* endif (p_first_ccw!=NULL) */ 2006 2007 2008#ifdef IOTRACE 2009 printk(KERN_INFO "%s: %s() > Dump Active CCW chain \n", 2010 dev->name,__FUNCTION__); 2011 p_buf=privptr->p_write_active_first; 2012 while (p_buf!=NULL) { 2013 dumpit((char *)p_buf, sizeof(struct ccwbk)); 2014 p_buf=p_buf->next; 2015 } 2016 p_buf=(struct ccwbk*)privptr->p_end_ccw; 2017 dumpit((char *)p_buf, sizeof(struct endccw)); 2018#endif 2019 dev_kfree_skb(skb); 2020 if (linkid==0) { 2021 lock=LOCK_NO; 2022 } 2023 else { 2024 lock=LOCK_YES; 2025 } 2026 claw_strt_out_IO(dev ); 2027 /* if write free count is zero , set NOBUFFER */ 2028#ifdef DEBUGMSG 2029 printk(KERN_INFO "%s: %s() > free_count is %d\n", 2030 dev->name,__FUNCTION__, 2031 (int) privptr->write_free_count ); 2032#endif 2033 if (privptr->write_free_count==0) { 2034 claw_setbit_busy(TB_NOBUFFER,dev); 2035 } 2036Done2: 2037 claw_clearbit_busy(TB_TX,dev); 2038Done: 2039#ifdef FUNCTRACE 2040 printk(KERN_INFO "%s: %s() > exit on line %d, rc = %d \n", 2041 dev->name,__FUNCTION__,__LINE__, rc); 2042#endif 2043 return(rc); 2044} /* end of claw_hw_tx */ 2045 2046/*-------------------------------------------------------------------* 2047* * 2048* init_ccw_bk * 2049* * 2050*--------------------------------------------------------------------*/ 2051 2052static int 2053init_ccw_bk(struct net_device *dev) 2054{ 2055 2056 __u32 ccw_blocks_required; 2057 __u32 ccw_blocks_perpage; 2058 __u32 ccw_pages_required; 2059 __u32 claw_reads_perpage=1; 2060 __u32 claw_read_pages; 2061 __u32 claw_writes_perpage=1; 2062 __u32 claw_write_pages; 2063 void *p_buff=NULL; 2064 struct ccwbk*p_free_chain; 2065 struct ccwbk*p_buf; 2066 struct ccwbk*p_last_CCWB; 2067 struct ccwbk*p_first_CCWB; 2068 struct endccw *p_endccw=NULL; 2069 addr_t real_address; 2070 struct claw_privbk *privptr=dev->priv; 2071 struct clawh *pClawH=NULL; 2072 addr_t real_TIC_address; 2073 int i,j; 2074#ifdef FUNCTRACE 2075 printk(KERN_INFO "%s: %s() enter \n",dev->name,__FUNCTION__); 2076#endif 2077 CLAW_DBF_TEXT(4,trace,"init_ccw"); 2078#ifdef DEBUGMSG 2079 printk(KERN_INFO "%s: variable dev =\n",dev->name); 2080 dumpit((char *) dev, sizeof(struct net_device)); 2081#endif 2082 2083 /* initialize statistics field */ 2084 privptr->active_link_ID=0; 2085 /* initialize ccwbk pointers */ 2086 privptr->p_write_free_chain=NULL; /* pointer to free ccw chain*/ 2087 privptr->p_write_active_first=NULL; /* pointer to the first write ccw*/ 2088 privptr->p_write_active_last=NULL; /* pointer to the last write ccw*/ 2089 privptr->p_read_active_first=NULL; /* pointer to the first read ccw*/ 2090 privptr->p_read_active_last=NULL; /* pointer to the last read ccw */ 2091 privptr->p_end_ccw=NULL; /* pointer to ending ccw */ 2092 privptr->p_claw_signal_blk=NULL; /* pointer to signal block */ 2093 privptr->buffs_alloc = 0; 2094 memset(&privptr->end_ccw, 0x00, sizeof(struct endccw)); 2095 memset(&privptr->ctl_bk, 0x00, sizeof(struct clawctl)); 2096 /* initialize free write ccwbk counter */ 2097 privptr->write_free_count=0; /* number of free bufs on write chain */ 2098 p_last_CCWB = NULL; 2099 p_first_CCWB= NULL; 2100 /* 2101 * We need 1 CCW block for each read buffer, 1 for each 2102 * write buffer, plus 1 for ClawSignalBlock 2103 */ 2104 ccw_blocks_required = 2105 privptr->p_env->read_buffers+privptr->p_env->write_buffers+1; 2106#ifdef DEBUGMSG 2107 printk(KERN_INFO "%s: %s() " 2108 "ccw_blocks_required=%d\n", 2109 dev->name,__FUNCTION__, 2110 ccw_blocks_required); 2111 printk(KERN_INFO "%s: %s() " 2112 "PAGE_SIZE=0x%x\n", 2113 dev->name,__FUNCTION__, 2114 (unsigned int)PAGE_SIZE); 2115 printk(KERN_INFO "%s: %s() > " 2116 "PAGE_MASK=0x%x\n", 2117 dev->name,__FUNCTION__, 2118 (unsigned int)PAGE_MASK); 2119#endif 2120 /* 2121 * compute number of CCW blocks that will fit in a page 2122 */ 2123 ccw_blocks_perpage= PAGE_SIZE / CCWBK_SIZE; 2124 ccw_pages_required= 2125 (ccw_blocks_required+ccw_blocks_perpage -1) / 2126 ccw_blocks_perpage; 2127 2128#ifdef DEBUGMSG 2129 printk(KERN_INFO "%s: %s() > ccw_blocks_perpage=%d\n", 2130 dev->name,__FUNCTION__, 2131 ccw_blocks_perpage); 2132 printk(KERN_INFO "%s: %s() > ccw_pages_required=%d\n", 2133 dev->name,__FUNCTION__, 2134 ccw_pages_required); 2135#endif 2136 /* 2137 * read and write sizes are set by 2 constants in claw.h 2138 * 4k and 32k. Unpacked values other than 4k are not going to 2139 * provide good performance. With packing buffers support 32k 2140 * buffers are used. 2141 */ 2142 if (privptr->p_env->read_size < PAGE_SIZE) { 2143 claw_reads_perpage= PAGE_SIZE / privptr->p_env->read_size; 2144 claw_read_pages= (privptr->p_env->read_buffers + 2145 claw_reads_perpage -1) / claw_reads_perpage; 2146 } 2147 else { /* > or equal */ 2148 privptr->p_buff_pages_perread= 2149 (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE; 2150 claw_read_pages= 2151 privptr->p_env->read_buffers * privptr->p_buff_pages_perread; 2152 } 2153 if (privptr->p_env->write_size < PAGE_SIZE) { 2154 claw_writes_perpage= 2155 PAGE_SIZE / privptr->p_env->write_size; 2156 claw_write_pages= 2157 (privptr->p_env->write_buffers + claw_writes_perpage -1) / 2158 claw_writes_perpage; 2159 2160 } 2161 else { /* > or equal */ 2162 privptr->p_buff_pages_perwrite= 2163 (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE; 2164 claw_write_pages= 2165 privptr->p_env->write_buffers * privptr->p_buff_pages_perwrite; 2166 } 2167#ifdef DEBUGMSG 2168 if (privptr->p_env->read_size < PAGE_SIZE) { 2169 printk(KERN_INFO "%s: %s() reads_perpage=%d\n", 2170 dev->name,__FUNCTION__, 2171 claw_reads_perpage); 2172 } 2173 else { 2174 printk(KERN_INFO "%s: %s() pages_perread=%d\n", 2175 dev->name,__FUNCTION__, 2176 privptr->p_buff_pages_perread); 2177 } 2178 printk(KERN_INFO "%s: %s() read_pages=%d\n", 2179 dev->name,__FUNCTION__, 2180 claw_read_pages); 2181 if (privptr->p_env->write_size < PAGE_SIZE) { 2182 printk(KERN_INFO "%s: %s() writes_perpage=%d\n", 2183 dev->name,__FUNCTION__, 2184 claw_writes_perpage); 2185 } 2186 else { 2187 printk(KERN_INFO "%s: %s() pages_perwrite=%d\n", 2188 dev->name,__FUNCTION__, 2189 privptr->p_buff_pages_perwrite); 2190 } 2191 printk(KERN_INFO "%s: %s() write_pages=%d\n", 2192 dev->name,__FUNCTION__, 2193 claw_write_pages); 2194#endif 2195 2196 2197 /* 2198 * allocate ccw_pages_required 2199 */ 2200 if (privptr->p_buff_ccw==NULL) { 2201 privptr->p_buff_ccw= 2202 (void *)__get_free_pages(__GFP_DMA, 2203 (int)pages_to_order_of_mag(ccw_pages_required )); 2204 if (privptr->p_buff_ccw==NULL) { 2205 printk(KERN_INFO "%s: %s() " 2206 "__get_free_pages for CCWs failed : " 2207 "pages is %d\n", 2208 dev->name,__FUNCTION__, 2209 ccw_pages_required ); 2210#ifdef FUNCTRACE 2211 printk(KERN_INFO "%s: %s() > " 2212 "exit on line %d, rc = ENOMEM\n", 2213 dev->name,__FUNCTION__, 2214 __LINE__); 2215#endif 2216 return -ENOMEM; 2217 } 2218 privptr->p_buff_ccw_num=ccw_pages_required; 2219 } 2220 memset(privptr->p_buff_ccw, 0x00, 2221 privptr->p_buff_ccw_num * PAGE_SIZE); 2222 2223 /* 2224 * obtain ending ccw block address 2225 * 2226 */ 2227 privptr->p_end_ccw = (struct endccw *)&privptr->end_ccw; 2228 real_address = (__u32)__pa(privptr->p_end_ccw); 2229 /* Initialize ending CCW block */ 2230#ifdef DEBUGMSG 2231 printk(KERN_INFO "%s: %s() begin initialize ending CCW blocks\n", 2232 dev->name,__FUNCTION__); 2233#endif 2234 2235 p_endccw=privptr->p_end_ccw; 2236 p_endccw->real=real_address; 2237 p_endccw->write1=0x00; 2238 p_endccw->read1=0x00; 2239 2240 /* write1_nop1 */ 2241 p_endccw->write1_nop1.cmd_code = CCW_CLAW_CMD_NOP; 2242 p_endccw->write1_nop1.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2243 p_endccw->write1_nop1.count = 1; 2244 p_endccw->write1_nop1.cda = 0; 2245 2246 /* write1_nop2 */ 2247 p_endccw->write1_nop2.cmd_code = CCW_CLAW_CMD_READFF; 2248 p_endccw->write1_nop2.flags = CCW_FLAG_SLI | CCW_FLAG_SKIP; 2249 p_endccw->write1_nop2.count = 1; 2250 p_endccw->write1_nop2.cda = 0; 2251 2252 /* write2_nop1 */ 2253 p_endccw->write2_nop1.cmd_code = CCW_CLAW_CMD_NOP; 2254 p_endccw->write2_nop1.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2255 p_endccw->write2_nop1.count = 1; 2256 p_endccw->write2_nop1.cda = 0; 2257 2258 /* write2_nop2 */ 2259 p_endccw->write2_nop2.cmd_code = CCW_CLAW_CMD_READFF; 2260 p_endccw->write2_nop2.flags = CCW_FLAG_SLI | CCW_FLAG_SKIP; 2261 p_endccw->write2_nop2.count = 1; 2262 p_endccw->write2_nop2.cda = 0; 2263 2264 /* read1_nop1 */ 2265 p_endccw->read1_nop1.cmd_code = CCW_CLAW_CMD_NOP; 2266 p_endccw->read1_nop1.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2267 p_endccw->read1_nop1.count = 1; 2268 p_endccw->read1_nop1.cda = 0; 2269 2270 /* read1_nop2 */ 2271 p_endccw->read1_nop2.cmd_code = CCW_CLAW_CMD_READFF; 2272 p_endccw->read1_nop2.flags = CCW_FLAG_SLI | CCW_FLAG_SKIP; 2273 p_endccw->read1_nop2.count = 1; 2274 p_endccw->read1_nop2.cda = 0; 2275 2276 /* read2_nop1 */ 2277 p_endccw->read2_nop1.cmd_code = CCW_CLAW_CMD_NOP; 2278 p_endccw->read2_nop1.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2279 p_endccw->read2_nop1.count = 1; 2280 p_endccw->read2_nop1.cda = 0; 2281 2282 /* read2_nop2 */ 2283 p_endccw->read2_nop2.cmd_code = CCW_CLAW_CMD_READFF; 2284 p_endccw->read2_nop2.flags = CCW_FLAG_SLI | CCW_FLAG_SKIP; 2285 p_endccw->read2_nop2.count = 1; 2286 p_endccw->read2_nop2.cda = 0; 2287 2288#ifdef IOTRACE 2289 printk(KERN_INFO "%s: %s() dump claw ending CCW BK \n", 2290 dev->name,__FUNCTION__); 2291 dumpit((char *)p_endccw, sizeof(struct endccw)); 2292#endif 2293 2294 /* 2295 * Build a chain of CCWs 2296 * 2297 */ 2298 2299#ifdef DEBUGMSG 2300 printk(KERN_INFO "%s: %s() Begin build a chain of CCW buffer \n", 2301 dev->name,__FUNCTION__); 2302#endif 2303 p_buff=privptr->p_buff_ccw; 2304 2305 p_free_chain=NULL; 2306 for (i=0 ; i < ccw_pages_required; i++ ) { 2307 real_address = (__u32)__pa(p_buff); 2308 p_buf=p_buff; 2309 for (j=0 ; j < ccw_blocks_perpage ; j++) { 2310 p_buf->next = p_free_chain; 2311 p_free_chain = p_buf; 2312 p_buf->real=(__u32)__pa(p_buf); 2313 ++p_buf; 2314 } 2315 p_buff+=PAGE_SIZE; 2316 } 2317#ifdef DEBUGMSG 2318 printk(KERN_INFO "%s: %s() " 2319 "End build a chain of CCW buffer \n", 2320 dev->name,__FUNCTION__); 2321 p_buf=p_free_chain; 2322 while (p_buf!=NULL) { 2323 dumpit((char *)p_buf, sizeof(struct ccwbk)); 2324 p_buf=p_buf->next; 2325 } 2326#endif 2327 2328 /* 2329 * Initialize ClawSignalBlock 2330 * 2331 */ 2332#ifdef DEBUGMSG 2333 printk(KERN_INFO "%s: %s() " 2334 "Begin initialize ClawSignalBlock \n", 2335 dev->name,__FUNCTION__); 2336#endif 2337 if (privptr->p_claw_signal_blk==NULL) { 2338 privptr->p_claw_signal_blk=p_free_chain; 2339 p_free_chain=p_free_chain->next; 2340 pClawH=(struct clawh *)privptr->p_claw_signal_blk; 2341 pClawH->length=0xffff; 2342 pClawH->opcode=0xff; 2343 pClawH->flag=CLAW_BUSY; 2344 } 2345#ifdef DEBUGMSG 2346 printk(KERN_INFO "%s: %s() > End initialize " 2347 "ClawSignalBlock\n", 2348 dev->name,__FUNCTION__); 2349 dumpit((char *)privptr->p_claw_signal_blk, sizeof(struct ccwbk)); 2350#endif 2351 2352 /* 2353 * allocate write_pages_required and add to free chain 2354 */ 2355 if (privptr->p_buff_write==NULL) { 2356 if (privptr->p_env->write_size < PAGE_SIZE) { 2357 privptr->p_buff_write= 2358 (void *)__get_free_pages(__GFP_DMA, 2359 (int)pages_to_order_of_mag(claw_write_pages )); 2360 if (privptr->p_buff_write==NULL) { 2361 printk(KERN_INFO "%s: %s() __get_free_pages for write" 2362 " bufs failed : get is for %d pages\n", 2363 dev->name,__FUNCTION__,claw_write_pages ); 2364 free_pages((unsigned long)privptr->p_buff_ccw, 2365 (int)pages_to_order_of_mag(privptr->p_buff_ccw_num)); 2366 privptr->p_buff_ccw=NULL; 2367#ifdef FUNCTRACE 2368 printk(KERN_INFO "%s: %s() > exit on line %d," 2369 "rc = ENOMEM\n", 2370 dev->name,__FUNCTION__,__LINE__); 2371#endif 2372 return -ENOMEM; 2373 } 2374 /* 2375 * Build CLAW write free chain 2376 * 2377 */ 2378 2379 memset(privptr->p_buff_write, 0x00, 2380 ccw_pages_required * PAGE_SIZE); 2381#ifdef DEBUGMSG 2382 printk(KERN_INFO "%s: %s() Begin build claw write free " 2383 "chain \n",dev->name,__FUNCTION__); 2384#endif 2385 privptr->p_write_free_chain=NULL; 2386 2387 p_buff=privptr->p_buff_write; 2388 2389 for (i=0 ; i< privptr->p_env->write_buffers ; i++) { 2390 p_buf = p_free_chain; /* get a CCW */ 2391 p_free_chain = p_buf->next; 2392 p_buf->next =privptr->p_write_free_chain; 2393 privptr->p_write_free_chain = p_buf; 2394 p_buf-> p_buffer = (struct clawbuf *)p_buff; 2395 p_buf-> write.cda = (__u32)__pa(p_buff); 2396 p_buf-> write.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2397 p_buf-> w_read_FF.cmd_code = CCW_CLAW_CMD_READFF; 2398 p_buf-> w_read_FF.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2399 p_buf-> w_read_FF.count = 1; 2400 p_buf-> w_read_FF.cda = 2401 (__u32)__pa(&p_buf-> header.flag); 2402 p_buf-> w_TIC_1.cmd_code = CCW_CLAW_CMD_TIC; 2403 p_buf-> w_TIC_1.flags = 0; 2404 p_buf-> w_TIC_1.count = 0; 2405 2406 if (((unsigned long)p_buff+privptr->p_env->write_size) >= 2407 ((unsigned long)(p_buff+2* 2408 (privptr->p_env->write_size) -1) & PAGE_MASK)) { 2409 p_buff= p_buff+privptr->p_env->write_size; 2410 } 2411 } 2412 } 2413 else /* Buffers are => PAGE_SIZE. 1 buff per get_free_pages */ 2414 { 2415 privptr->p_write_free_chain=NULL; 2416 for (i = 0; i< privptr->p_env->write_buffers ; i++) { 2417 p_buff=(void *)__get_free_pages(__GFP_DMA, 2418 (int)pages_to_order_of_mag( 2419 privptr->p_buff_pages_perwrite) ); 2420#ifdef IOTRACE 2421 printk(KERN_INFO "%s:%s __get_free_pages " 2422 "for writes buf: get for %d pages\n", 2423 dev->name,__FUNCTION__, 2424 privptr->p_buff_pages_perwrite); 2425#endif 2426 if (p_buff==NULL) { 2427 printk(KERN_INFO "%s:%s __get_free_pages" 2428 "for writes buf failed : get is for %d pages\n", 2429 dev->name, 2430 __FUNCTION__, 2431 privptr->p_buff_pages_perwrite ); 2432 free_pages((unsigned long)privptr->p_buff_ccw, 2433 (int)pages_to_order_of_mag( 2434 privptr->p_buff_ccw_num)); 2435 privptr->p_buff_ccw=NULL; 2436 p_buf=privptr->p_buff_write; 2437 while (p_buf!=NULL) { 2438 free_pages((unsigned long) 2439 p_buf->p_buffer, 2440 (int)pages_to_order_of_mag( 2441 privptr->p_buff_pages_perwrite)); 2442 p_buf=p_buf->next; 2443 } 2444#ifdef FUNCTRACE 2445 printk(KERN_INFO "%s: %s exit on line %d, rc = ENOMEM\n", 2446 dev->name, 2447 __FUNCTION__, 2448 __LINE__); 2449#endif 2450 return -ENOMEM; 2451 } /* Error on get_pages */ 2452 memset(p_buff, 0x00, privptr->p_env->write_size ); 2453 p_buf = p_free_chain; 2454 p_free_chain = p_buf->next; 2455 p_buf->next = privptr->p_write_free_chain; 2456 privptr->p_write_free_chain = p_buf; 2457 privptr->p_buff_write = p_buf; 2458 p_buf->p_buffer=(struct clawbuf *)p_buff; 2459 p_buf-> write.cda = (__u32)__pa(p_buff); 2460 p_buf-> write.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2461 p_buf-> w_read_FF.cmd_code = CCW_CLAW_CMD_READFF; 2462 p_buf-> w_read_FF.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2463 p_buf-> w_read_FF.count = 1; 2464 p_buf-> w_read_FF.cda = 2465 (__u32)__pa(&p_buf-> header.flag); 2466 p_buf-> w_TIC_1.cmd_code = CCW_CLAW_CMD_TIC; 2467 p_buf-> w_TIC_1.flags = 0; 2468 p_buf-> w_TIC_1.count = 0; 2469 } /* for all write_buffers */ 2470 2471 } /* else buffers are PAGE_SIZE or bigger */ 2472 2473 } 2474 privptr->p_buff_write_num=claw_write_pages; 2475 privptr->write_free_count=privptr->p_env->write_buffers; 2476 2477 2478#ifdef DEBUGMSG 2479 printk(KERN_INFO "%s:%s End build claw write free chain \n", 2480 dev->name,__FUNCTION__); 2481 p_buf=privptr->p_write_free_chain; 2482 while (p_buf!=NULL) { 2483 dumpit((char *)p_buf, sizeof(struct ccwbk)); 2484 p_buf=p_buf->next; 2485 } 2486#endif 2487 /* 2488 * allocate read_pages_required and chain to free chain 2489 */ 2490 if (privptr->p_buff_read==NULL) { 2491 if (privptr->p_env->read_size < PAGE_SIZE) { 2492 privptr->p_buff_read= 2493 (void *)__get_free_pages(__GFP_DMA, 2494 (int)pages_to_order_of_mag(claw_read_pages) ); 2495 if (privptr->p_buff_read==NULL) { 2496 printk(KERN_INFO "%s: %s() " 2497 "__get_free_pages for read buf failed : " 2498 "get is for %d pages\n", 2499 dev->name,__FUNCTION__,claw_read_pages ); 2500 free_pages((unsigned long)privptr->p_buff_ccw, 2501 (int)pages_to_order_of_mag( 2502 privptr->p_buff_ccw_num)); 2503 /* free the write pages size is < page size */ 2504 free_pages((unsigned long)privptr->p_buff_write, 2505 (int)pages_to_order_of_mag( 2506 privptr->p_buff_write_num)); 2507 privptr->p_buff_ccw=NULL; 2508 privptr->p_buff_write=NULL; 2509#ifdef FUNCTRACE 2510 printk(KERN_INFO "%s: %s() > exit on line %d, rc =" 2511 " ENOMEM\n",dev->name,__FUNCTION__,__LINE__); 2512#endif 2513 return -ENOMEM; 2514 } 2515 memset(privptr->p_buff_read, 0x00, claw_read_pages * PAGE_SIZE); 2516 privptr->p_buff_read_num=claw_read_pages; 2517 /* 2518 * Build CLAW read free chain 2519 * 2520 */ 2521#ifdef DEBUGMSG 2522 printk(KERN_INFO "%s: %s() Begin build claw read free chain \n", 2523 dev->name,__FUNCTION__); 2524#endif 2525 p_buff=privptr->p_buff_read; 2526 for (i=0 ; i< privptr->p_env->read_buffers ; i++) { 2527 p_buf = p_free_chain; 2528 p_free_chain = p_buf->next; 2529 2530 if (p_last_CCWB==NULL) { 2531 p_buf->next=NULL; 2532 real_TIC_address=0; 2533 p_last_CCWB=p_buf; 2534 } 2535 else { 2536 p_buf->next=p_first_CCWB; 2537 real_TIC_address= 2538 (__u32)__pa(&p_first_CCWB -> read ); 2539 } 2540 2541 p_first_CCWB=p_buf; 2542 2543 p_buf->p_buffer=(struct clawbuf *)p_buff; 2544 /* initialize read command */ 2545 p_buf-> read.cmd_code = CCW_CLAW_CMD_READ; 2546 p_buf-> read.cda = (__u32)__pa(p_buff); 2547 p_buf-> read.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2548 p_buf-> read.count = privptr->p_env->read_size; 2549 2550 /* initialize read_h command */ 2551 p_buf-> read_h.cmd_code = CCW_CLAW_CMD_READHEADER; 2552 p_buf-> read_h.cda = 2553 (__u32)__pa(&(p_buf->header)); 2554 p_buf-> read_h.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2555 p_buf-> read_h.count = sizeof(struct clawh); 2556 2557 /* initialize Signal command */ 2558 p_buf-> signal.cmd_code = CCW_CLAW_CMD_SIGNAL_SMOD; 2559 p_buf-> signal.cda = 2560 (__u32)__pa(&(pClawH->flag)); 2561 p_buf-> signal.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2562 p_buf-> signal.count = 1; 2563 2564 /* initialize r_TIC_1 command */ 2565 p_buf-> r_TIC_1.cmd_code = CCW_CLAW_CMD_TIC; 2566 p_buf-> r_TIC_1.cda = (__u32)real_TIC_address; 2567 p_buf-> r_TIC_1.flags = 0; 2568 p_buf-> r_TIC_1.count = 0; 2569 2570 /* initialize r_read_FF command */ 2571 p_buf-> r_read_FF.cmd_code = CCW_CLAW_CMD_READFF; 2572 p_buf-> r_read_FF.cda = 2573 (__u32)__pa(&(pClawH->flag)); 2574 p_buf-> r_read_FF.flags = 2575 CCW_FLAG_SLI | CCW_FLAG_CC | CCW_FLAG_PCI; 2576 p_buf-> r_read_FF.count = 1; 2577 2578 /* initialize r_TIC_2 */ 2579 memcpy(&p_buf->r_TIC_2, 2580 &p_buf->r_TIC_1, sizeof(struct ccw1)); 2581 2582 /* initialize Header */ 2583 p_buf->header.length=0xffff; 2584 p_buf->header.opcode=0xff; 2585 p_buf->header.flag=CLAW_PENDING; 2586 2587 if (((unsigned long)p_buff+privptr->p_env->read_size) >= 2588 ((unsigned long)(p_buff+2*(privptr->p_env->read_size) -1) 2589 & PAGE_MASK) ) { 2590 p_buff= p_buff+privptr->p_env->read_size; 2591 } 2592 else { 2593 p_buff= 2594 (void *)((unsigned long) 2595 (p_buff+2*(privptr->p_env->read_size) -1) 2596 & PAGE_MASK) ; 2597 } 2598 } /* for read_buffers */ 2599 } /* read_size < PAGE_SIZE */ 2600 else { /* read Size >= PAGE_SIZE */ 2601 2602#ifdef DEBUGMSG 2603 printk(KERN_INFO "%s: %s() Begin build claw read free chain \n", 2604 dev->name,__FUNCTION__); 2605#endif 2606 for (i=0 ; i< privptr->p_env->read_buffers ; i++) { 2607 p_buff = (void *)__get_free_pages(__GFP_DMA, 2608 (int)pages_to_order_of_mag(privptr->p_buff_pages_perread) ); 2609 if (p_buff==NULL) { 2610 printk(KERN_INFO "%s: %s() __get_free_pages for read " 2611 "buf failed : get is for %d pages\n", 2612 dev->name,__FUNCTION__, 2613 privptr->p_buff_pages_perread ); 2614 free_pages((unsigned long)privptr->p_buff_ccw, 2615 (int)pages_to_order_of_mag(privptr->p_buff_ccw_num)); 2616 /* free the write pages */ 2617 p_buf=privptr->p_buff_write; 2618 while (p_buf!=NULL) { 2619 free_pages((unsigned long)p_buf->p_buffer, 2620 (int)pages_to_order_of_mag( 2621 privptr->p_buff_pages_perwrite )); 2622 p_buf=p_buf->next; 2623 } 2624 /* free any read pages already alloc */ 2625 p_buf=privptr->p_buff_read; 2626 while (p_buf!=NULL) { 2627 free_pages((unsigned long)p_buf->p_buffer, 2628 (int)pages_to_order_of_mag( 2629 privptr->p_buff_pages_perread )); 2630 p_buf=p_buf->next; 2631 } 2632 privptr->p_buff_ccw=NULL; 2633 privptr->p_buff_write=NULL; 2634#ifdef FUNCTRACE 2635 printk(KERN_INFO "%s: %s() exit on line %d, rc = ENOMEM\n", 2636 dev->name,__FUNCTION__, 2637 __LINE__); 2638#endif 2639 return -ENOMEM; 2640 } 2641 memset(p_buff, 0x00, privptr->p_env->read_size); 2642 p_buf = p_free_chain; 2643 privptr->p_buff_read = p_buf; 2644 p_free_chain = p_buf->next; 2645 2646 if (p_last_CCWB==NULL) { 2647 p_buf->next=NULL; 2648 real_TIC_address=0; 2649 p_last_CCWB=p_buf; 2650 } 2651 else { 2652 p_buf->next=p_first_CCWB; 2653 real_TIC_address= 2654 (addr_t)__pa( 2655 &p_first_CCWB -> read ); 2656 } 2657 2658 p_first_CCWB=p_buf; 2659 /* save buff address */ 2660 p_buf->p_buffer=(struct clawbuf *)p_buff; 2661 /* initialize read command */ 2662 p_buf-> read.cmd_code = CCW_CLAW_CMD_READ; 2663 p_buf-> read.cda = (__u32)__pa(p_buff); 2664 p_buf-> read.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2665 p_buf-> read.count = privptr->p_env->read_size; 2666 2667 /* initialize read_h command */ 2668 p_buf-> read_h.cmd_code = CCW_CLAW_CMD_READHEADER; 2669 p_buf-> read_h.cda = 2670 (__u32)__pa(&(p_buf->header)); 2671 p_buf-> read_h.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2672 p_buf-> read_h.count = sizeof(struct clawh); 2673 2674 /* initialize Signal command */ 2675 p_buf-> signal.cmd_code = CCW_CLAW_CMD_SIGNAL_SMOD; 2676 p_buf-> signal.cda = 2677 (__u32)__pa(&(pClawH->flag)); 2678 p_buf-> signal.flags = CCW_FLAG_SLI | CCW_FLAG_CC; 2679 p_buf-> signal.count = 1; 2680 2681 /* initialize r_TIC_1 command */ 2682 p_buf-> r_TIC_1.cmd_code = CCW_CLAW_CMD_TIC; 2683 p_buf-> r_TIC_1.cda = (__u32)real_TIC_address; 2684 p_buf-> r_TIC_1.flags = 0; 2685 p_buf-> r_TIC_1.count = 0; 2686 2687 /* initialize r_read_FF command */ 2688 p_buf-> r_read_FF.cmd_code = CCW_CLAW_CMD_READFF; 2689 p_buf-> r_read_FF.cda = 2690 (__u32)__pa(&(pClawH->flag)); 2691 p_buf-> r_read_FF.flags = 2692 CCW_FLAG_SLI | CCW_FLAG_CC | CCW_FLAG_PCI; 2693 p_buf-> r_read_FF.count = 1; 2694 2695 /* initialize r_TIC_2 */ 2696 memcpy(&p_buf->r_TIC_2, &p_buf->r_TIC_1, 2697 sizeof(struct ccw1)); 2698 2699 /* initialize Header */ 2700 p_buf->header.length=0xffff; 2701 p_buf->header.opcode=0xff; 2702 p_buf->header.flag=CLAW_PENDING; 2703 2704 } /* For read_buffers */ 2705 } /* read_size >= PAGE_SIZE */ 2706 } /* pBuffread = NULL */ 2707#ifdef DEBUGMSG 2708 printk(KERN_INFO "%s: %s() > End build claw read free chain \n", 2709 dev->name,__FUNCTION__); 2710 p_buf=p_first_CCWB; 2711 while (p_buf!=NULL) { 2712 dumpit((char *)p_buf, sizeof(struct ccwbk)); 2713 p_buf=p_buf->next; 2714 } 2715 2716#endif 2717 add_claw_reads( dev ,p_first_CCWB , p_last_CCWB); 2718 privptr->buffs_alloc = 1; 2719#ifdef FUNCTRACE 2720 printk(KERN_INFO "%s: %s() exit on line %d\n", 2721 dev->name,__FUNCTION__,__LINE__); 2722#endif 2723 return 0; 2724} /* end of init_ccw_bk */ 2725 2726/*-------------------------------------------------------------------* 2727* * 2728* probe_error * 2729* * 2730*--------------------------------------------------------------------*/ 2731 2732static void 2733probe_error( struct ccwgroup_device *cgdev) 2734{ 2735 struct claw_privbk *privptr; 2736#ifdef FUNCTRACE 2737 printk(KERN_INFO "%s enter \n",__FUNCTION__); 2738#endif 2739 CLAW_DBF_TEXT(4,trace,"proberr"); 2740#ifdef DEBUGMSG 2741 printk(KERN_INFO "%s variable cgdev =\n",__FUNCTION__); 2742 dumpit((char *) cgdev, sizeof(struct ccwgroup_device)); 2743#endif 2744 privptr=(struct claw_privbk *)cgdev->dev.driver_data; 2745 if (privptr!=NULL) { 2746 if (privptr->p_env != NULL) { 2747 kfree(privptr->p_env); 2748 privptr->p_env=NULL; 2749 } 2750 if (privptr->p_mtc_envelope!=NULL) { 2751 kfree(privptr->p_mtc_envelope); 2752 privptr->p_mtc_envelope=NULL; 2753 } 2754 kfree(privptr); 2755 privptr=NULL; 2756 } 2757#ifdef FUNCTRACE 2758 printk(KERN_INFO "%s > exit on line %d\n", 2759 __FUNCTION__,__LINE__); 2760#endif 2761 2762 return; 2763} /* probe_error */ 2764 2765 2766 2767/*-------------------------------------------------------------------* 2768* claw_process_control * 2769* * 2770* * 2771*--------------------------------------------------------------------*/ 2772 2773static int 2774claw_process_control( struct net_device *dev, struct ccwbk * p_ccw) 2775{ 2776 2777 struct clawbuf *p_buf; 2778 struct clawctl ctlbk; 2779 struct clawctl *p_ctlbk; 2780 char temp_host_name[8]; 2781 char temp_ws_name[8]; 2782 struct claw_privbk *privptr; 2783 struct claw_env *p_env; 2784 struct sysval *p_sysval; 2785 struct conncmd *p_connect=NULL; 2786 int rc; 2787 struct chbk *p_ch = NULL; 2788#ifdef FUNCTRACE 2789 printk(KERN_INFO "%s: %s() > enter \n", 2790 dev->name,__FUNCTION__); 2791#endif 2792 CLAW_DBF_TEXT(2,setup,"clw_cntl"); 2793#ifdef DEBUGMSG 2794 printk(KERN_INFO "%s: variable dev =\n",dev->name); 2795 dumpit((char *) dev, sizeof(struct net_device)); 2796 printk(KERN_INFO "%s: variable p_ccw =\n",dev->name); 2797 dumpit((char *) p_ccw, sizeof(struct ccwbk *)); 2798#endif 2799 udelay(1000); /* Wait a ms for the control packets to 2800 *catch up to each other */ 2801 privptr=dev->priv; 2802 p_env=privptr->p_env; 2803 memcpy( &temp_host_name, p_env->host_name, 8); 2804 memcpy( &temp_ws_name, p_env->adapter_name , 8); 2805 printk(KERN_INFO "%s: CLAW device %.8s: " 2806 "Received Control Packet\n", 2807 dev->name, temp_ws_name); 2808 if (privptr->release_pend==1) { 2809#ifdef FUNCTRACE 2810 printk(KERN_INFO "%s: %s() > " 2811 "exit on line %d, rc=0\n", 2812 dev->name,__FUNCTION__,__LINE__); 2813#endif 2814 return 0; 2815 } 2816 p_buf=p_ccw->p_buffer; 2817 p_ctlbk=&ctlbk; 2818 if (p_env->packing == DO_PACKED) { /* packing in progress?*/ 2819 memcpy(p_ctlbk, &p_buf->buffer[4], sizeof(struct clawctl)); 2820 } else { 2821 memcpy(p_ctlbk, p_buf, sizeof(struct clawctl)); 2822 } 2823#ifdef IOTRACE 2824 printk(KERN_INFO "%s: dump claw control data inbound\n",dev->name); 2825 dumpit((char *)p_ctlbk, sizeof(struct clawctl)); 2826#endif 2827 switch (p_ctlbk->command) 2828 { 2829 case SYSTEM_VALIDATE_REQUEST: 2830 if (p_ctlbk->version!=CLAW_VERSION_ID) { 2831 claw_snd_sys_validate_rsp(dev, p_ctlbk, 2832 CLAW_RC_WRONG_VERSION ); 2833 printk("%s: %d is wrong version id. " 2834 "Expected %d\n", 2835 dev->name, p_ctlbk->version, 2836 CLAW_VERSION_ID); 2837 } 2838 p_sysval=(struct sysval *)&(p_ctlbk->data); 2839 printk( "%s: Recv Sys Validate Request: " 2840 "Vers=%d,link_id=%d,Corr=%d,WS name=%." 2841 "8s,Host name=%.8s\n", 2842 dev->name, p_ctlbk->version, 2843 p_ctlbk->linkid, 2844 p_ctlbk->correlator, 2845 p_sysval->WS_name, 2846 p_sysval->host_name); 2847 if (0!=memcmp(temp_host_name,p_sysval->host_name,8)) { 2848 claw_snd_sys_validate_rsp(dev, p_ctlbk, 2849 CLAW_RC_NAME_MISMATCH ); 2850 CLAW_DBF_TEXT(2,setup,"HSTBAD"); 2851 CLAW_DBF_TEXT_(2,setup,"%s",p_sysval->host_name); 2852 CLAW_DBF_TEXT_(2,setup,"%s",temp_host_name); 2853 printk(KERN_INFO "%s: Host name mismatch\n", 2854 dev->name); 2855 printk(KERN_INFO "%s: Received :%s: " 2856 "expected :%s: \n", 2857 dev->name, 2858 p_sysval->host_name, 2859 temp_host_name); 2860 } 2861 if (0!=memcmp(temp_ws_name,p_sysval->WS_name,8)) { 2862 claw_snd_sys_validate_rsp(dev, p_ctlbk, 2863 CLAW_RC_NAME_MISMATCH ); 2864 CLAW_DBF_TEXT(2,setup,"WSNBAD"); 2865 CLAW_DBF_TEXT_(2,setup,"%s",p_sysval->WS_name); 2866 CLAW_DBF_TEXT_(2,setup,"%s",temp_ws_name); 2867 printk(KERN_INFO "%s: WS name mismatch\n", 2868 dev->name); 2869 printk(KERN_INFO "%s: Received :%s: " 2870 "expected :%s: \n", 2871 dev->name, 2872 p_sysval->WS_name, 2873 temp_ws_name); 2874 } 2875 if (( p_sysval->write_frame_size < p_env->write_size) && 2876 ( p_env->packing == 0)) { 2877 claw_snd_sys_validate_rsp(dev, p_ctlbk, 2878 CLAW_RC_HOST_RCV_TOO_SMALL ); 2879 printk(KERN_INFO "%s: host write size is too " 2880 "small\n", dev->name); 2881 CLAW_DBF_TEXT(2,setup,"wrtszbad"); 2882 } 2883 if (( p_sysval->read_frame_size < p_env->read_size) && 2884 ( p_env->packing == 0)) { 2885 claw_snd_sys_validate_rsp(dev, p_ctlbk, 2886 CLAW_RC_HOST_RCV_TOO_SMALL ); 2887 printk(KERN_INFO "%s: host read size is too " 2888 "small\n", dev->name); 2889 CLAW_DBF_TEXT(2,setup,"rdsizbad"); 2890 } 2891 claw_snd_sys_validate_rsp(dev, p_ctlbk, 0 ); 2892 printk("%s: CLAW device %.8s: System validate" 2893 " completed.\n",dev->name, temp_ws_name); 2894 printk("%s: sys Validate Rsize:%d Wsize:%d\n",dev->name, 2895 p_sysval->read_frame_size,p_sysval->write_frame_size); 2896 privptr->system_validate_comp=1; 2897 if(strncmp(p_env->api_type,WS_APPL_NAME_PACKED,6) == 0) { 2898 p_env->packing = PACKING_ASK; 2899 } 2900 claw_strt_conn_req(dev); 2901 break; 2902 2903 case SYSTEM_VALIDATE_RESPONSE: 2904 p_sysval=(struct sysval *)&(p_ctlbk->data); 2905 printk("%s: Recv Sys Validate Resp: Vers=%d,Corr=%d,RC=%d," 2906 "WS name=%.8s,Host name=%.8s\n", 2907 dev->name, 2908 p_ctlbk->version, 2909 p_ctlbk->correlator, 2910 p_ctlbk->rc, 2911 p_sysval->WS_name, 2912 p_sysval->host_name); 2913 switch (p_ctlbk->rc) 2914 { 2915 case 0: 2916 printk(KERN_INFO "%s: CLAW device " 2917 "%.8s: System validate " 2918 "completed.\n", 2919 dev->name, temp_ws_name); 2920 if (privptr->system_validate_comp == 0) 2921 claw_strt_conn_req(dev); 2922 privptr->system_validate_comp=1; 2923 break; 2924 case CLAW_RC_NAME_MISMATCH: 2925 printk(KERN_INFO "%s: Sys Validate " 2926 "Resp : Host, WS name is " 2927 "mismatch\n", 2928 dev->name); 2929 break; 2930 case CLAW_RC_WRONG_VERSION: 2931 printk(KERN_INFO "%s: Sys Validate " 2932 "Resp : Wrong version\n", 2933 dev->name); 2934 break; 2935 case CLAW_RC_HOST_RCV_TOO_SMALL: 2936 printk(KERN_INFO "%s: Sys Validate " 2937 "Resp : bad frame size\n", 2938 dev->name); 2939 break; 2940 default: 2941 printk(KERN_INFO "%s: Sys Validate " 2942 "error code=%d \n", 2943 dev->name, p_ctlbk->rc ); 2944 break; 2945 } 2946 break; 2947 2948 case CONNECTION_REQUEST: 2949 p_connect=(struct conncmd *)&(p_ctlbk->data); 2950 printk(KERN_INFO "%s: Recv Conn Req: Vers=%d,link_id=%d," 2951 "Corr=%d,HOST appl=%.8s,WS appl=%.8s\n", 2952 dev->name, 2953 p_ctlbk->version, 2954 p_ctlbk->linkid, 2955 p_ctlbk->correlator, 2956 p_connect->host_name, 2957 p_connect->WS_name); 2958 if (privptr->active_link_ID!=0 ) { 2959 claw_snd_disc(dev, p_ctlbk); 2960 printk(KERN_INFO "%s: Conn Req error : " 2961 "already logical link is active \n", 2962 dev->name); 2963 } 2964 if (p_ctlbk->linkid!=1 ) { 2965 claw_snd_disc(dev, p_ctlbk); 2966 printk(KERN_INFO "%s: Conn Req error : " 2967 "req logical link id is not 1\n", 2968 dev->name); 2969 } 2970 rc=find_link(dev, 2971 p_connect->host_name, p_connect->WS_name); 2972 if (rc!=0) { 2973 claw_snd_disc(dev, p_ctlbk); 2974 printk(KERN_INFO "%s: Conn Req error : " 2975 "req appl name does not match\n", 2976 dev->name); 2977 } 2978 claw_send_control(dev, 2979 CONNECTION_CONFIRM, p_ctlbk->linkid, 2980 p_ctlbk->correlator, 2981 0, p_connect->host_name, 2982 p_connect->WS_name); 2983 if (p_env->packing == PACKING_ASK) { 2984 printk("%s: Now Pack ask\n",dev->name); 2985 p_env->packing = PACK_SEND; 2986 claw_snd_conn_req(dev,0); 2987 } 2988 printk(KERN_INFO "%s: CLAW device %.8s: Connection " 2989 "completed link_id=%d.\n", 2990 dev->name, temp_ws_name, 2991 p_ctlbk->linkid); 2992 privptr->active_link_ID=p_ctlbk->linkid; 2993 p_ch=&privptr->channel[WRITE]; 2994 wake_up(&p_ch->wait); /* wake up claw_open ( WRITE) */ 2995 break; 2996 case CONNECTION_RESPONSE: 2997 p_connect=(struct conncmd *)&(p_ctlbk->data); 2998 printk(KERN_INFO "%s: Revc Conn Resp: Vers=%d,link_id=%d," 2999 "Corr=%d,RC=%d,Host appl=%.8s, WS appl=%.8s\n", 3000 dev->name, 3001 p_ctlbk->version, 3002 p_ctlbk->linkid, 3003 p_ctlbk->correlator, 3004 p_ctlbk->rc, 3005 p_connect->host_name, 3006 p_connect->WS_name); 3007 3008 if (p_ctlbk->rc !=0 ) { 3009 printk(KERN_INFO "%s: Conn Resp error: rc=%d \n", 3010 dev->name, p_ctlbk->rc); 3011 return 1; 3012 } 3013 rc=find_link(dev, 3014 p_connect->host_name, p_connect->WS_name); 3015 if (rc!=0) { 3016 claw_snd_disc(dev, p_ctlbk); 3017 printk(KERN_INFO "%s: Conn Resp error: " 3018 "req appl name does not match\n", 3019 dev->name); 3020 } 3021 /* should be until CONNECTION_CONFIRM */ 3022 privptr->active_link_ID = - (p_ctlbk->linkid); 3023 break; 3024 case CONNECTION_CONFIRM: 3025 p_connect=(struct conncmd *)&(p_ctlbk->data); 3026 printk(KERN_INFO "%s: Recv Conn Confirm:Vers=%d,link_id=%d," 3027 "Corr=%d,Host appl=%.8s,WS appl=%.8s\n", 3028 dev->name, 3029 p_ctlbk->version, 3030 p_ctlbk->linkid, 3031 p_ctlbk->correlator, 3032 p_connect->host_name, 3033 p_connect->WS_name); 3034 if (p_ctlbk->linkid== -(privptr->active_link_ID)) { 3035 privptr->active_link_ID=p_ctlbk->linkid; 3036 if (p_env->packing > PACKING_ASK) { 3037 printk(KERN_INFO "%s: Confirmed Now packing\n",dev->name); 3038 p_env->packing = DO_PACKED; 3039 } 3040 p_ch=&privptr->channel[WRITE]; 3041 wake_up(&p_ch->wait); 3042 } 3043 else { 3044 printk(KERN_INFO "%s: Conn confirm: " 3045 "unexpected linkid=%d \n", 3046 dev->name, p_ctlbk->linkid); 3047 claw_snd_disc(dev, p_ctlbk); 3048 } 3049 break; 3050 case DISCONNECT: 3051 printk(KERN_INFO "%s: Disconnect: " 3052 "Vers=%d,link_id=%d,Corr=%d\n", 3053 dev->name, p_ctlbk->version, 3054 p_ctlbk->linkid, p_ctlbk->correlator); 3055 if ((p_ctlbk->linkid == 2) && 3056 (p_env->packing == PACK_SEND)) { 3057 privptr->active_link_ID = 1; 3058 p_env->packing = DO_PACKED; 3059 } 3060 else 3061 privptr->active_link_ID=0; 3062 break; 3063 case CLAW_ERROR: 3064 printk(KERN_INFO "%s: CLAW ERROR detected\n", 3065 dev->name); 3066 break; 3067 default: 3068 printk(KERN_INFO "%s: Unexpected command code=%d \n", 3069 dev->name, p_ctlbk->command); 3070 break; 3071 } 3072 3073#ifdef FUNCTRACE 3074 printk(KERN_INFO "%s: %s() exit on line %d, rc = 0\n", 3075 dev->name,__FUNCTION__,__LINE__); 3076#endif 3077 3078 return 0; 3079} /* end of claw_process_control */ 3080 3081 3082/*-------------------------------------------------------------------* 3083* claw_send_control * 3084* * 3085*--------------------------------------------------------------------*/ 3086 3087static int 3088claw_send_control(struct net_device *dev, __u8 type, __u8 link, 3089 __u8 correlator, __u8 rc, char *local_name, char *remote_name) 3090{ 3091 struct claw_privbk *privptr; 3092 struct clawctl *p_ctl; 3093 struct sysval *p_sysval; 3094 struct conncmd *p_connect; 3095 struct sk_buff *skb; 3096 3097#ifdef FUNCTRACE 3098 printk(KERN_INFO "%s:%s > enter \n",dev->name,__FUNCTION__); 3099#endif 3100 CLAW_DBF_TEXT(2,setup,"sndcntl"); 3101#ifdef DEBUGMSG 3102 printk(KERN_INFO "%s: Sending Control Packet \n",dev->name); 3103 printk(KERN_INFO "%s: variable type = 0x%X, link = " 3104 "%d, correlator = %d, rc = %d\n", 3105 dev->name,type, link, correlator, rc); 3106 printk(KERN_INFO "%s: variable local_name = %s, " 3107 "remote_name = %s\n",dev->name, local_name, remote_name); 3108#endif 3109 privptr=dev->priv; 3110 p_ctl=(struct clawctl *)&privptr->ctl_bk; 3111 3112 p_ctl->command=type; 3113 p_ctl->version=CLAW_VERSION_ID; 3114 p_ctl->linkid=link; 3115 p_ctl->correlator=correlator; 3116 p_ctl->rc=rc; 3117 3118 p_sysval=(struct sysval *)&p_ctl->data; 3119 p_connect=(struct conncmd *)&p_ctl->data; 3120 3121 switch (p_ctl->command) { 3122 case SYSTEM_VALIDATE_REQUEST: 3123 case SYSTEM_VALIDATE_RESPONSE: 3124 memcpy(&p_sysval->host_name, local_name, 8); 3125 memcpy(&p_sysval->WS_name, remote_name, 8); 3126 if (privptr->p_env->packing > 0) { 3127 p_sysval->read_frame_size=DEF_PACK_BUFSIZE; 3128 p_sysval->write_frame_size=DEF_PACK_BUFSIZE; 3129 } else { 3130 /* how big is the piggest group of packets */ 3131 p_sysval->read_frame_size=privptr->p_env->read_size; 3132 p_sysval->write_frame_size=privptr->p_env->write_size; 3133 } 3134 memset(&p_sysval->reserved, 0x00, 4); 3135 break; 3136 case CONNECTION_REQUEST: 3137 case CONNECTION_RESPONSE: 3138 case CONNECTION_CONFIRM: 3139 case DISCONNECT: 3140 memcpy(&p_sysval->host_name, local_name, 8); 3141 memcpy(&p_sysval->WS_name, remote_name, 8); 3142 if (privptr->p_env->packing > 0) { 3143 /* How big is the biggest packet */ 3144 p_connect->reserved1[0]=CLAW_FRAME_SIZE; 3145 p_connect->reserved1[1]=CLAW_FRAME_SIZE; 3146 } else { 3147 memset(&p_connect->reserved1, 0x00, 4); 3148 memset(&p_connect->reserved2, 0x00, 4); 3149 } 3150 break; 3151 default: 3152 break; 3153 } 3154 3155 /* write Control Record to the device */ 3156 3157 3158 skb = dev_alloc_skb(sizeof(struct clawctl)); 3159 if (!skb) { 3160 printk( "%s:%s low on mem, returning...\n", 3161 dev->name,__FUNCTION__); 3162#ifdef DEBUG 3163 printk(KERN_INFO "%s:%s Exit, rc = ENOMEM\n", 3164 dev->name,__FUNCTION__); 3165#endif 3166 return -ENOMEM; 3167 } 3168 memcpy(skb_put(skb, sizeof(struct clawctl)), 3169 p_ctl, sizeof(struct clawctl)); 3170#ifdef IOTRACE 3171 printk(KERN_INFO "%s: outbnd claw cntl data \n",dev->name); 3172 dumpit((char *)p_ctl,sizeof(struct clawctl)); 3173#endif 3174 if (privptr->p_env->packing >= PACK_SEND) 3175 claw_hw_tx(skb, dev, 1); 3176 else 3177 claw_hw_tx(skb, dev, 0); 3178#ifdef FUNCTRACE 3179 printk(KERN_INFO "%s:%s Exit on line %d\n", 3180 dev->name,__FUNCTION__,__LINE__); 3181#endif 3182 3183 return 0; 3184} /* end of claw_send_control */ 3185 3186/*-------------------------------------------------------------------* 3187* claw_snd_conn_req * 3188* * 3189*--------------------------------------------------------------------*/ 3190static int 3191claw_snd_conn_req(struct net_device *dev, __u8 link) 3192{ 3193 int rc; 3194 struct claw_privbk *privptr=dev->priv; 3195 struct clawctl *p_ctl; 3196 3197#ifdef FUNCTRACE 3198 printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__); 3199#endif 3200 CLAW_DBF_TEXT(2,setup,"snd_conn"); 3201#ifdef DEBUGMSG 3202 printk(KERN_INFO "%s: variable link = %X, dev =\n",dev->name, link); 3203 dumpit((char *) dev, sizeof(struct net_device)); 3204#endif 3205 rc = 1; 3206 p_ctl=(struct clawctl *)&privptr->ctl_bk; 3207 p_ctl->linkid = link; 3208 if ( privptr->system_validate_comp==0x00 ) { 3209#ifdef FUNCTRACE 3210 printk(KERN_INFO "%s:%s Exit on line %d, rc = 1\n", 3211 dev->name,__FUNCTION__,__LINE__); 3212#endif 3213 return rc; 3214 } 3215 if (privptr->p_env->packing == PACKING_ASK ) 3216 rc=claw_send_control(dev, CONNECTION_REQUEST,0,0,0, 3217 WS_APPL_NAME_PACKED, WS_APPL_NAME_PACKED); 3218 if (privptr->p_env->packing == PACK_SEND) { 3219 rc=claw_send_control(dev, CONNECTION_REQUEST,0,0,0, 3220 WS_APPL_NAME_IP_NAME, WS_APPL_NAME_IP_NAME); 3221 } 3222 if (privptr->p_env->packing == 0) 3223 rc=claw_send_control(dev, CONNECTION_REQUEST,0,0,0, 3224 HOST_APPL_NAME, privptr->p_env->api_type); 3225#ifdef FUNCTRACE 3226 printk(KERN_INFO "%s:%s Exit on line %d, rc = %d\n", 3227 dev->name,__FUNCTION__,__LINE__, rc); 3228#endif 3229 return rc; 3230 3231} /* end of claw_snd_conn_req */ 3232 3233 3234/*-------------------------------------------------------------------* 3235* claw_snd_disc * 3236* * 3237*--------------------------------------------------------------------*/ 3238 3239static int 3240claw_snd_disc(struct net_device *dev, struct clawctl * p_ctl) 3241{ 3242 int rc; 3243 struct conncmd * p_connect; 3244 3245#ifdef FUNCTRACE 3246 printk(KERN_INFO "%s:%s Enter\n",dev->name,__FUNCTION__); 3247#endif 3248 CLAW_DBF_TEXT(2,setup,"snd_dsc"); 3249#ifdef DEBUGMSG 3250 printk(KERN_INFO "%s: variable dev =\n",dev->name); 3251 dumpit((char *) dev, sizeof(struct net_device)); 3252 printk(KERN_INFO "%s: variable p_ctl",dev->name); 3253 dumpit((char *) p_ctl, sizeof(struct clawctl)); 3254#endif 3255 p_connect=(struct conncmd *)&p_ctl->data; 3256 3257 rc=claw_send_control(dev, DISCONNECT, p_ctl->linkid, 3258 p_ctl->correlator, 0, 3259 p_connect->host_name, p_connect->WS_name); 3260#ifdef FUNCTRACE 3261 printk(KERN_INFO "%s:%s Exit on line %d, rc = %d\n", 3262 dev->name,__FUNCTION__, __LINE__, rc); 3263#endif 3264 return rc; 3265} /* end of claw_snd_disc */ 3266 3267 3268/*-------------------------------------------------------------------* 3269* claw_snd_sys_validate_rsp * 3270* * 3271*--------------------------------------------------------------------*/ 3272 3273static int 3274claw_snd_sys_validate_rsp(struct net_device *dev, 3275 struct clawctl *p_ctl, __u32 return_code) 3276{ 3277 struct claw_env * p_env; 3278 struct claw_privbk *privptr; 3279 int rc; 3280 3281#ifdef FUNCTRACE 3282 printk(KERN_INFO "%s:%s Enter\n", 3283 dev->name,__FUNCTION__); 3284#endif 3285 CLAW_DBF_TEXT(2,setup,"chkresp"); 3286#ifdef DEBUGMSG 3287 printk(KERN_INFO "%s: variable return_code = %d, dev =\n", 3288 dev->name, return_code); 3289 dumpit((char *) dev, sizeof(struct net_device)); 3290 printk(KERN_INFO "%s: variable p_ctl =\n",dev->name); 3291 dumpit((char *) p_ctl, sizeof(struct clawctl)); 3292#endif 3293 privptr = dev->priv; 3294 p_env=privptr->p_env; 3295 rc=claw_send_control(dev, SYSTEM_VALIDATE_RESPONSE, 3296 p_ctl->linkid, 3297 p_ctl->correlator, 3298 return_code, 3299 p_env->host_name, 3300 p_env->adapter_name ); 3301#ifdef FUNCTRACE 3302 printk(KERN_INFO "%s:%s Exit on line %d, rc = %d\n", 3303 dev->name,__FUNCTION__,__LINE__, rc); 3304#endif 3305 return rc; 3306} /* end of claw_snd_sys_validate_rsp */ 3307 3308/*-------------------------------------------------------------------* 3309* claw_strt_conn_req * 3310* * 3311*--------------------------------------------------------------------*/ 3312 3313static int 3314claw_strt_conn_req(struct net_device *dev ) 3315{ 3316 int rc; 3317 3318#ifdef FUNCTRACE 3319 printk(KERN_INFO "%s:%s Enter\n",dev->name,__FUNCTION__); 3320#endif 3321 CLAW_DBF_TEXT(2,setup,"conn_req"); 3322#ifdef DEBUGMSG 3323 printk(KERN_INFO "%s: variable dev =\n",dev->name); 3324 dumpit((char *) dev, sizeof(struct net_device)); 3325#endif 3326 rc=claw_snd_conn_req(dev, 1); 3327#ifdef FUNCTRACE 3328 printk(KERN_INFO "%s:%s Exit on line %d, rc = %d\n", 3329 dev->name,__FUNCTION__,__LINE__, rc); 3330#endif 3331 return rc; 3332} /* end of claw_strt_conn_req */ 3333 3334 3335 3336/*-------------------------------------------------------------------* 3337 * claw_stats * 3338 *-------------------------------------------------------------------*/ 3339 3340static struct 3341net_device_stats *claw_stats(struct net_device *dev) 3342{ 3343 struct claw_privbk *privptr; 3344#ifdef FUNCTRACE 3345 printk(KERN_INFO "%s:%s Enter\n",dev->name,__FUNCTION__); 3346#endif 3347 CLAW_DBF_TEXT(4,trace,"stats"); 3348 privptr = dev->priv; 3349#ifdef FUNCTRACE 3350 printk(KERN_INFO "%s:%s Exit on line %d\n", 3351 dev->name,__FUNCTION__,__LINE__); 3352#endif 3353 return &privptr->stats; 3354} /* end of claw_stats */ 3355 3356 3357/*-------------------------------------------------------------------* 3358* unpack_read * 3359* * 3360*--------------------------------------------------------------------*/ 3361static void 3362unpack_read(struct net_device *dev ) 3363{ 3364 struct sk_buff *skb; 3365 struct claw_privbk *privptr; 3366 struct claw_env *p_env; 3367 struct ccwbk *p_this_ccw; 3368 struct ccwbk *p_first_ccw; 3369 struct ccwbk *p_last_ccw; 3370 struct clawph *p_packh; 3371 void *p_packd; 3372 struct clawctl *p_ctlrec=NULL; 3373 3374 __u32 len_of_data; 3375 __u32 pack_off; 3376 __u8 link_num; 3377 __u8 mtc_this_frm=0; 3378 __u32 bytes_to_mov; 3379 struct chbk *p_ch = NULL; 3380 int i=0; 3381 int p=0; 3382 3383#ifdef FUNCTRACE 3384 printk(KERN_INFO "%s:%s enter \n",dev->name,__FUNCTION__); 3385#endif 3386 CLAW_DBF_TEXT(4,trace,"unpkread"); 3387 p_first_ccw=NULL; 3388 p_last_ccw=NULL; 3389 p_packh=NULL; 3390 p_packd=NULL; 3391 privptr=dev->priv; 3392 p_env = privptr->p_env; 3393 p_this_ccw=privptr->p_read_active_first; 3394 i=0; 3395 while (p_this_ccw!=NULL && p_this_ccw->header.flag!=CLAW_PENDING) { 3396#ifdef IOTRACE 3397 printk(KERN_INFO "%s p_this_ccw \n",dev->name); 3398 dumpit((char*)p_this_ccw, sizeof(struct ccwbk)); 3399 printk(KERN_INFO "%s Inbound p_this_ccw->p_buffer(64)" 3400 " pk=%d \n",dev->name,p_env->packing); 3401 dumpit((char *)p_this_ccw->p_buffer, 64 ); 3402#endif 3403 pack_off = 0; 3404 p = 0; 3405 p_this_ccw->header.flag=CLAW_PENDING; 3406 privptr->p_read_active_first=p_this_ccw->next; 3407 p_this_ccw->next=NULL; 3408 p_packh = (struct clawph *)p_this_ccw->p_buffer; 3409 if ((p_env->packing == PACK_SEND) && 3410 (p_packh->len == 32) && 3411 (p_packh->link_num == 0)) { /* is it a packed ctl rec? */ 3412 p_packh++; /* peek past pack header */ 3413 p_ctlrec = (struct clawctl *)p_packh; 3414 p_packh--; /* un peek */ 3415 if ((p_ctlrec->command == CONNECTION_RESPONSE) || 3416 (p_ctlrec->command == CONNECTION_CONFIRM)) 3417 p_env->packing = DO_PACKED; 3418 } 3419 if (p_env->packing == DO_PACKED) 3420 link_num=p_packh->link_num; 3421 else 3422 link_num=p_this_ccw->header.opcode / 8; 3423 if ((p_this_ccw->header.opcode & MORE_to_COME_FLAG)!=0) { 3424#ifdef DEBUGMSG 3425 printk(KERN_INFO "%s: %s > More_to_come is ON\n", 3426 dev->name,__FUNCTION__); 3427#endif 3428 mtc_this_frm=1; 3429 if (p_this_ccw->header.length!= 3430 privptr->p_env->read_size ) { 3431 printk(KERN_INFO " %s: Invalid frame detected " 3432 "length is %02x\n" , 3433 dev->name, p_this_ccw->header.length); 3434 } 3435 } 3436 3437 if (privptr->mtc_skipping) { 3438 /* 3439 * We're in the mode of skipping past a 3440 * multi-frame message 3441 * that we can't process for some reason or other. 3442 * The first frame without the More-To-Come flag is 3443 * the last frame of the skipped message. 3444 */ 3445 /* in case of More-To-Come not set in this frame */ 3446 if (mtc_this_frm==0) { 3447 privptr->mtc_skipping=0; /* Ok, the end */ 3448 privptr->mtc_logical_link=-1; 3449 } 3450#ifdef DEBUGMSG 3451 printk(KERN_INFO "%s:%s goto next " 3452 "frame from MoretoComeSkip \n", 3453 dev->name,__FUNCTION__); 3454#endif 3455 goto NextFrame; 3456 } 3457 3458 if (link_num==0) { 3459 claw_process_control(dev, p_this_ccw); 3460#ifdef DEBUGMSG 3461 printk(KERN_INFO "%s:%s goto next " 3462 "frame from claw_process_control \n", 3463 dev->name,__FUNCTION__); 3464#endif 3465 CLAW_DBF_TEXT(4,trace,"UnpkCntl"); 3466 goto NextFrame; 3467 } 3468unpack_next: 3469 if (p_env->packing == DO_PACKED) { 3470 if (pack_off > p_env->read_size) 3471 goto NextFrame; 3472 p_packd = p_this_ccw->p_buffer+pack_off; 3473 p_packh = (struct clawph *) p_packd; 3474 if ((p_packh->len == 0) || /* all done with this frame? */ 3475 (p_packh->flag != 0)) 3476 goto NextFrame; 3477 bytes_to_mov = p_packh->len; 3478 pack_off += bytes_to_mov+sizeof(struct clawph); 3479 p++; 3480 } else { 3481 bytes_to_mov=p_this_ccw->header.length; 3482 } 3483 if (privptr->mtc_logical_link<0) { 3484#ifdef DEBUGMSG 3485 printk(KERN_INFO "%s: %s mtc_logical_link < 0 \n", 3486 dev->name,__FUNCTION__); 3487#endif 3488 3489 /* 3490 * if More-To-Come is set in this frame then we don't know 3491 * length of entire message, and hence have to allocate 3492 * large buffer */ 3493 3494 /* We are starting a new envelope */ 3495 privptr->mtc_offset=0; 3496 privptr->mtc_logical_link=link_num; 3497 } 3498 3499 if (bytes_to_mov > (MAX_ENVELOPE_SIZE- privptr->mtc_offset) ) { 3500 /* error */ 3501#ifdef DEBUGMSG 3502 printk(KERN_INFO "%s: %s > goto next " 3503 "frame from MoretoComeSkip \n", 3504 dev->name, 3505 __FUNCTION__); 3506 printk(KERN_INFO " bytes_to_mov %d > (MAX_ENVELOPE_" 3507 "SIZE-privptr->mtc_offset %d)\n", 3508 bytes_to_mov,(MAX_ENVELOPE_SIZE- privptr->mtc_offset)); 3509#endif 3510 privptr->stats.rx_frame_errors++; 3511 goto NextFrame; 3512 } 3513 if (p_env->packing == DO_PACKED) { 3514 memcpy( privptr->p_mtc_envelope+ privptr->mtc_offset, 3515 p_packd+sizeof(struct clawph), bytes_to_mov); 3516 3517 } else { 3518 memcpy( privptr->p_mtc_envelope+ privptr->mtc_offset, 3519 p_this_ccw->p_buffer, bytes_to_mov); 3520 } 3521#ifdef DEBUGMSG 3522 printk(KERN_INFO "%s: %s() received data \n", 3523 dev->name,__FUNCTION__); 3524 if (p_env->packing == DO_PACKED) 3525 dumpit((char *)p_packd+sizeof(struct clawph),32); 3526 else 3527 dumpit((char *)p_this_ccw->p_buffer, 32); 3528 printk(KERN_INFO "%s: %s() bytelength %d \n", 3529 dev->name,__FUNCTION__,bytes_to_mov); 3530#endif 3531 if (mtc_this_frm==0) { 3532 len_of_data=privptr->mtc_offset+bytes_to_mov; 3533 skb=dev_alloc_skb(len_of_data); 3534 if (skb) { 3535 memcpy(skb_put(skb,len_of_data), 3536 privptr->p_mtc_envelope, 3537 len_of_data); 3538 skb->mac.raw=skb->data; 3539 skb->dev=dev; 3540 skb->protocol=htons(ETH_P_IP); 3541 skb->ip_summed=CHECKSUM_UNNECESSARY; 3542 privptr->stats.rx_packets++; 3543 privptr->stats.rx_bytes+=len_of_data; 3544 netif_rx(skb); 3545#ifdef DEBUGMSG 3546 printk(KERN_INFO "%s: %s() netif_" 3547 "rx(skb) completed \n", 3548 dev->name,__FUNCTION__); 3549#endif 3550 } 3551 else { 3552 privptr->stats.rx_dropped++; 3553 printk(KERN_WARNING "%s: %s() low on memory\n", 3554 dev->name,__FUNCTION__); 3555 } 3556 privptr->mtc_offset=0; 3557 privptr->mtc_logical_link=-1; 3558 } 3559 else { 3560 privptr->mtc_offset+=bytes_to_mov; 3561 } 3562 if (p_env->packing == DO_PACKED) 3563 goto unpack_next; 3564NextFrame: 3565 /* 3566 * Remove ThisCCWblock from active read queue, and add it 3567 * to queue of free blocks to be reused. 3568 */ 3569 i++; 3570 p_this_ccw->header.length=0xffff; 3571 p_this_ccw->header.opcode=0xff; 3572 /* 3573 * add this one to the free queue for later reuse 3574 */ 3575 if (p_first_ccw==NULL) { 3576 p_first_ccw = p_this_ccw; 3577 } 3578 else { 3579 p_last_ccw->next = p_this_ccw; 3580 } 3581 p_last_ccw = p_this_ccw; 3582 /* 3583 * chain to next block on active read queue 3584 */ 3585 p_this_ccw = privptr->p_read_active_first; 3586 CLAW_DBF_TEXT_(4,trace,"rxpkt %d",p); 3587 } /* end of while */ 3588 3589 /* check validity */ 3590 3591#ifdef IOTRACE 3592 printk(KERN_INFO "%s:%s processed frame is %d \n", 3593 dev->name,__FUNCTION__,i); 3594 printk(KERN_INFO "%s:%s F:%lx L:%lx\n", 3595 dev->name, 3596 __FUNCTION__, 3597 (unsigned long)p_first_ccw, 3598 (unsigned long)p_last_ccw); 3599#endif 3600 CLAW_DBF_TEXT_(4,trace,"rxfrm %d",i); 3601 add_claw_reads(dev, p_first_ccw, p_last_ccw); 3602 p_ch=&privptr->channel[READ]; 3603 claw_strt_read(dev, LOCK_YES); 3604#ifdef FUNCTRACE 3605 printk(KERN_INFO "%s: %s exit on line %d\n", 3606 dev->name, __FUNCTION__, __LINE__); 3607#endif 3608 return; 3609} /* end of unpack_read */ 3610 3611/*-------------------------------------------------------------------* 3612* claw_strt_read * 3613* * 3614*--------------------------------------------------------------------*/ 3615static void 3616claw_strt_read (struct net_device *dev, int lock ) 3617{ 3618 int rc = 0; 3619 __u32 parm; 3620 unsigned long saveflags = 0; 3621 struct claw_privbk *privptr=dev->priv; 3622 struct ccwbk*p_ccwbk; 3623 struct chbk *p_ch; 3624 struct clawh *p_clawh; 3625 p_ch=&privptr->channel[READ]; 3626 3627#ifdef FUNCTRACE 3628 printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__); 3629 printk(KERN_INFO "%s: variable lock = %d, dev =\n",dev->name, lock); 3630 dumpit((char *) dev, sizeof(struct net_device)); 3631#endif 3632 CLAW_DBF_TEXT(4,trace,"StRdNter"); 3633 p_clawh=(struct clawh *)privptr->p_claw_signal_blk; 3634 p_clawh->flag=CLAW_IDLE; /* 0x00 */ 3635 3636 if ((privptr->p_write_active_first!=NULL && 3637 privptr->p_write_active_first->header.flag!=CLAW_PENDING) || 3638 (privptr->p_read_active_first!=NULL && 3639 privptr->p_read_active_first->header.flag!=CLAW_PENDING )) { 3640 p_clawh->flag=CLAW_BUSY; /* 0xff */ 3641 } 3642#ifdef DEBUGMSG 3643 printk(KERN_INFO "%s:%s state-%02x\n" , 3644 dev->name,__FUNCTION__, p_ch->claw_state); 3645#endif 3646 if (lock==LOCK_YES) { 3647 spin_lock_irqsave(get_ccwdev_lock(p_ch->cdev), saveflags); 3648 } 3649 if (test_and_set_bit(0, (void *)&p_ch->IO_active) == 0) { 3650#ifdef DEBUGMSG 3651 printk(KERN_INFO "%s: HOT READ started in %s\n" , 3652 dev->name,__FUNCTION__); 3653 p_clawh=(struct clawh *)privptr->p_claw_signal_blk; 3654 dumpit((char *)&p_clawh->flag , 1); 3655#endif 3656 CLAW_DBF_TEXT(4,trace,"HotRead"); 3657 p_ccwbk=privptr->p_read_active_first; 3658 parm = (unsigned long) p_ch; 3659 rc = ccw_device_start (p_ch->cdev, &p_ccwbk->read, parm, 3660 0xff, 0); 3661 if (rc != 0) { 3662 ccw_check_return_code(p_ch->cdev, rc); 3663 } 3664 } 3665 else { 3666#ifdef DEBUGMSG 3667 printk(KERN_INFO "%s: No READ started by %s() In progress\n" , 3668 dev->name,__FUNCTION__); 3669#endif 3670 CLAW_DBF_TEXT(2,trace,"ReadAct"); 3671 } 3672 3673 if (lock==LOCK_YES) { 3674 spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags); 3675 } 3676#ifdef FUNCTRACE 3677 printk(KERN_INFO "%s:%s Exit on line %d\n", 3678 dev->name,__FUNCTION__,__LINE__); 3679#endif 3680 CLAW_DBF_TEXT(4,trace,"StRdExit"); 3681 return; 3682} /* end of claw_strt_read */ 3683 3684/*-------------------------------------------------------------------* 3685* claw_strt_out_IO * 3686* * 3687*--------------------------------------------------------------------*/ 3688 3689static void 3690claw_strt_out_IO( struct net_device *dev ) 3691{ 3692 int rc = 0; 3693 unsigned long parm; 3694 struct claw_privbk *privptr; 3695 struct chbk *p_ch; 3696 struct ccwbk *p_first_ccw; 3697 3698#ifdef FUNCTRACE 3699 printk(KERN_INFO "%s:%s Enter\n",dev->name,__FUNCTION__); 3700#endif 3701 if (!dev) { 3702 return; 3703 } 3704 privptr=(struct claw_privbk *)dev->priv; 3705 p_ch=&privptr->channel[WRITE]; 3706 3707#ifdef DEBUGMSG 3708 printk(KERN_INFO "%s:%s state-%02x\n" , 3709 dev->name,__FUNCTION__,p_ch->claw_state); 3710#endif 3711 CLAW_DBF_TEXT(4,trace,"strt_io"); 3712 p_first_ccw=privptr->p_write_active_first; 3713 3714 if (p_ch->claw_state == CLAW_STOP) 3715 return; 3716 if (p_first_ccw == NULL) { 3717#ifdef FUNCTRACE 3718 printk(KERN_INFO "%s:%s Exit on line %d\n", 3719 dev->name,__FUNCTION__,__LINE__); 3720#endif 3721 return; 3722 } 3723 if (test_and_set_bit(0, (void *)&p_ch->IO_active) == 0) { 3724 parm = (unsigned long) p_ch; 3725#ifdef DEBUGMSG 3726 printk(KERN_INFO "%s:%s do_io \n" ,dev->name,__FUNCTION__); 3727 dumpit((char *)p_first_ccw, sizeof(struct ccwbk)); 3728#endif 3729 CLAW_DBF_TEXT(2,trace,"StWrtIO"); 3730 rc = ccw_device_start (p_ch->cdev,&p_first_ccw->write, parm, 3731 0xff, 0); 3732 if (rc != 0) { 3733 ccw_check_return_code(p_ch->cdev, rc); 3734 } 3735 } 3736 dev->trans_start = jiffies; 3737#ifdef FUNCTRACE 3738 printk(KERN_INFO "%s:%s Exit on line %d\n", 3739 dev->name,__FUNCTION__,__LINE__); 3740#endif 3741 3742 return; 3743} /* end of claw_strt_out_IO */ 3744 3745/*-------------------------------------------------------------------* 3746* Free write buffers * 3747* * 3748*--------------------------------------------------------------------*/ 3749 3750static void 3751claw_free_wrt_buf( struct net_device *dev ) 3752{ 3753 3754 struct claw_privbk *privptr=(struct claw_privbk *)dev->priv; 3755 struct ccwbk*p_first_ccw; 3756 struct ccwbk*p_last_ccw; 3757 struct ccwbk*p_this_ccw; 3758 struct ccwbk*p_next_ccw; 3759#ifdef IOTRACE 3760 struct ccwbk*p_buf; 3761#endif 3762#ifdef FUNCTRACE 3763 printk(KERN_INFO "%s:%s Enter\n",dev->name,__FUNCTION__); 3764 printk(KERN_INFO "%s: free count = %d variable dev =\n", 3765 dev->name,privptr->write_free_count); 3766#endif 3767 CLAW_DBF_TEXT(4,trace,"freewrtb"); 3768 /* scan the write queue to free any completed write packets */ 3769 p_first_ccw=NULL; 3770 p_last_ccw=NULL; 3771#ifdef IOTRACE 3772 printk(KERN_INFO "%s: Dump current CCW chain \n",dev->name ); 3773 p_buf=privptr->p_write_active_first; 3774 while (p_buf!=NULL) { 3775 dumpit((char *)p_buf, sizeof(struct ccwbk)); 3776 p_buf=p_buf->next; 3777 } 3778 if (p_buf==NULL) { 3779 printk(KERN_INFO "%s: privptr->p_write_" 3780 "active_first==NULL\n",dev->name ); 3781 } 3782 p_buf=(struct ccwbk*)privptr->p_end_ccw; 3783 dumpit((char *)p_buf, sizeof(struct endccw)); 3784#endif 3785 p_this_ccw=privptr->p_write_active_first; 3786 while ( (p_this_ccw!=NULL) && (p_this_ccw->header.flag!=CLAW_PENDING)) 3787 { 3788 p_next_ccw = p_this_ccw->next; 3789 if (((p_next_ccw!=NULL) && 3790 (p_next_ccw->header.flag!=CLAW_PENDING)) || 3791 ((p_this_ccw == privptr->p_write_active_last) && 3792 (p_this_ccw->header.flag!=CLAW_PENDING))) { 3793 /* The next CCW is OK or this is */ 3794 /* the last CCW...free it @A1A */ 3795 privptr->p_write_active_first=p_this_ccw->next; 3796 p_this_ccw->header.flag=CLAW_PENDING; 3797 p_this_ccw->next=privptr->p_write_free_chain; 3798 privptr->p_write_free_chain=p_this_ccw; 3799 ++privptr->write_free_count; 3800 privptr->stats.tx_bytes+= p_this_ccw->write.count; 3801 p_this_ccw=privptr->p_write_active_first; 3802 privptr->stats.tx_packets++; 3803 } 3804 else { 3805 break; 3806 } 3807 } 3808 if (privptr->write_free_count!=0) { 3809 claw_clearbit_busy(TB_NOBUFFER,dev); 3810 } 3811 /* whole chain removed? */ 3812 if (privptr->p_write_active_first==NULL) { 3813 privptr->p_write_active_last=NULL; 3814#ifdef DEBUGMSG 3815 printk(KERN_INFO "%s:%s p_write_" 3816 "active_first==NULL\n",dev->name,__FUNCTION__); 3817#endif 3818 } 3819#ifdef IOTRACE 3820 printk(KERN_INFO "%s: Dump arranged CCW chain \n",dev->name ); 3821 p_buf=privptr->p_write_active_first; 3822 while (p_buf!=NULL) { 3823 dumpit((char *)p_buf, sizeof(struct ccwbk)); 3824 p_buf=p_buf->next; 3825 } 3826 if (p_buf==NULL) { 3827 printk(KERN_INFO "%s: privptr->p_write_active_" 3828 "first==NULL\n",dev->name ); 3829 } 3830 p_buf=(struct ccwbk*)privptr->p_end_ccw; 3831 dumpit((char *)p_buf, sizeof(struct endccw)); 3832#endif 3833 3834 CLAW_DBF_TEXT_(4,trace,"FWC=%d",privptr->write_free_count); 3835#ifdef FUNCTRACE 3836 printk(KERN_INFO "%s:%s Exit on line %d free_count =%d\n", 3837 dev->name,__FUNCTION__, __LINE__,privptr->write_free_count); 3838#endif 3839 return; 3840} 3841 3842/*-------------------------------------------------------------------* 3843* claw free netdevice * 3844* * 3845*--------------------------------------------------------------------*/ 3846static void 3847claw_free_netdevice(struct net_device * dev, int free_dev) 3848{ 3849 struct claw_privbk *privptr; 3850#ifdef FUNCTRACE 3851 printk(KERN_INFO "%s:%s Enter\n",dev->name,__FUNCTION__); 3852#endif 3853 CLAW_DBF_TEXT(2,setup,"free_dev"); 3854 3855 if (!dev) 3856 return; 3857 CLAW_DBF_TEXT_(2,setup,"%s",dev->name); 3858 privptr = dev->priv; 3859 if (dev->flags & IFF_RUNNING) 3860 claw_release(dev); 3861 if (privptr) { 3862 privptr->channel[READ].ndev = NULL; /* say it's free */ 3863 } 3864 dev->priv=NULL; 3865#ifdef MODULE 3866 if (free_dev) { 3867 free_netdev(dev); 3868 } 3869#endif 3870 CLAW_DBF_TEXT(2,setup,"feee_ok"); 3871#ifdef FUNCTRACE 3872 printk(KERN_INFO "%s:%s Exit\n",dev->name,__FUNCTION__); 3873#endif 3874} 3875 3876/** 3877 * Claw init netdevice 3878 * Initialize everything of the net device except the name and the 3879 * channel structs. 3880 */ 3881static void 3882claw_init_netdevice(struct net_device * dev) 3883{ 3884#ifdef FUNCTRACE 3885 printk(KERN_INFO "%s:%s Enter\n",dev->name,__FUNCTION__); 3886#endif 3887 CLAW_DBF_TEXT(2,setup,"init_dev"); 3888 CLAW_DBF_TEXT_(2,setup,"%s",dev->name); 3889 if (!dev) { 3890 printk(KERN_WARNING "claw:%s BAD Device exit line %d\n", 3891 __FUNCTION__,__LINE__); 3892 CLAW_DBF_TEXT(2,setup,"baddev"); 3893 return; 3894 } 3895 dev->mtu = CLAW_DEFAULT_MTU_SIZE; 3896 dev->hard_start_xmit = claw_tx; 3897 dev->open = claw_open; 3898 dev->stop = claw_release; 3899 dev->get_stats = claw_stats; 3900 dev->change_mtu = claw_change_mtu; 3901 dev->hard_header_len = 0; 3902 dev->addr_len = 0; 3903 dev->type = ARPHRD_SLIP; 3904 dev->tx_queue_len = 1300; 3905 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 3906 SET_MODULE_OWNER(dev); 3907#ifdef FUNCTRACE 3908 printk(KERN_INFO "%s:%s Exit\n",dev->name,__FUNCTION__); 3909#endif 3910 CLAW_DBF_TEXT(2,setup,"initok"); 3911 return; 3912} 3913 3914/** 3915 * Init a new channel in the privptr->channel[i]. 3916 * 3917 * @param cdev The ccw_device to be added. 3918 * 3919 * @return 0 on success, !0 on error. 3920 */ 3921static int 3922add_channel(struct ccw_device *cdev,int i,struct claw_privbk *privptr) 3923{ 3924 struct chbk *p_ch; 3925 3926#ifdef FUNCTRACE 3927 printk(KERN_INFO "%s:%s Enter\n",cdev->dev.bus_id,__FUNCTION__); 3928#endif 3929 CLAW_DBF_TEXT_(2,setup,"%s",cdev->dev.bus_id); 3930 privptr->channel[i].flag = i+1; /* Read is 1 Write is 2 */ 3931 p_ch = &privptr->channel[i]; 3932 p_ch->cdev = cdev; 3933 snprintf(p_ch->id, CLAW_ID_SIZE, "cl-%s", cdev->dev.bus_id); 3934 sscanf(cdev->dev.bus_id+4,"%x",&p_ch->devno); 3935 if ((p_ch->irb = kmalloc(sizeof (struct irb),GFP_KERNEL)) == NULL) { 3936 printk(KERN_WARNING "%s Out of memory in %s for irb\n", 3937 p_ch->id,__FUNCTION__); 3938#ifdef FUNCTRACE 3939 printk(KERN_INFO "%s:%s Exit on line %d\n", 3940 p_ch->id,__FUNCTION__,__LINE__); 3941#endif 3942 return -ENOMEM; 3943 } 3944 memset(p_ch->irb, 0, sizeof (struct irb)); 3945#ifdef FUNCTRACE 3946 printk(KERN_INFO "%s:%s Exit on line %d\n", 3947 cdev->dev.bus_id,__FUNCTION__,__LINE__); 3948#endif 3949 return 0; 3950} 3951 3952 3953/** 3954 * 3955 * Setup an interface. 3956 * 3957 * @param cgdev Device to be setup. 3958 * 3959 * @returns 0 on success, !0 on failure. 3960 */ 3961static int 3962claw_new_device(struct ccwgroup_device *cgdev) 3963{ 3964 struct claw_privbk *privptr; 3965 struct claw_env *p_env; 3966 struct net_device *dev; 3967 int ret; 3968 3969 pr_debug("%s() called\n", __FUNCTION__); 3970 printk(KERN_INFO "claw: add for %s\n",cgdev->cdev[READ]->dev.bus_id); 3971 CLAW_DBF_TEXT(2,setup,"new_dev"); 3972 privptr = cgdev->dev.driver_data; 3973 cgdev->cdev[READ]->dev.driver_data = privptr; 3974 cgdev->cdev[WRITE]->dev.driver_data = privptr; 3975 if (!privptr) 3976 return -ENODEV; 3977 p_env = privptr->p_env; 3978 sscanf(cgdev->cdev[READ]->dev.bus_id+4,"%x", 3979 &p_env->devno[READ]); 3980 sscanf(cgdev->cdev[WRITE]->dev.bus_id+4,"%x", 3981 &p_env->devno[WRITE]); 3982 ret = add_channel(cgdev->cdev[0],0,privptr); 3983 if (ret == 0) 3984 ret = add_channel(cgdev->cdev[1],1,privptr); 3985 if (ret != 0) { 3986 printk(KERN_WARNING 3987 "add channel failed " 3988 "with ret = %d\n", ret); 3989 goto out; 3990 } 3991 ret = ccw_device_set_online(cgdev->cdev[READ]); 3992 if (ret != 0) { 3993 printk(KERN_WARNING 3994 "claw: ccw_device_set_online %s READ failed " 3995 "with ret = %d\n",cgdev->cdev[READ]->dev.bus_id,ret); 3996 goto out; 3997 } 3998 ret = ccw_device_set_online(cgdev->cdev[WRITE]); 3999 if (ret != 0) { 4000 printk(KERN_WARNING 4001 "claw: ccw_device_set_online %s WRITE failed " 4002 "with ret = %d\n",cgdev->cdev[WRITE]->dev.bus_id, ret); 4003 goto out; 4004 } 4005 dev = alloc_netdev(0,"claw%d",claw_init_netdevice); 4006 if (!dev) { 4007 printk(KERN_WARNING "%s:alloc_netdev failed\n",__FUNCTION__); 4008 goto out; 4009 } 4010 dev->priv = privptr; 4011 cgdev->dev.driver_data = privptr; 4012 cgdev->cdev[READ]->dev.driver_data = privptr; 4013 cgdev->cdev[WRITE]->dev.driver_data = privptr; 4014 /* sysfs magic */ 4015 SET_NETDEV_DEV(dev, &cgdev->dev); 4016 if (register_netdev(dev) != 0) { 4017 claw_free_netdevice(dev, 1); 4018 CLAW_DBF_TEXT(2,trace,"regfail"); 4019 goto out; 4020 } 4021 dev->flags &=~IFF_RUNNING; 4022 if (privptr->buffs_alloc == 0) { 4023 ret=init_ccw_bk(dev); 4024 if (ret !=0) { 4025 printk(KERN_WARNING 4026 "claw: init_ccw_bk failed with ret=%d\n", ret); 4027 unregister_netdev(dev); 4028 claw_free_netdevice(dev,1); 4029 CLAW_DBF_TEXT(2,trace,"ccwmem"); 4030 goto out; 4031 } 4032 } 4033 privptr->channel[READ].ndev = dev; 4034 privptr->channel[WRITE].ndev = dev; 4035 privptr->p_env->ndev = dev; 4036 4037 printk(KERN_INFO "%s:readsize=%d writesize=%d " 4038 "readbuffer=%d writebuffer=%d read=0x%04x write=0x%04x\n", 4039 dev->name, p_env->read_size, 4040 p_env->write_size, p_env->read_buffers, 4041 p_env->write_buffers, p_env->devno[READ], 4042 p_env->devno[WRITE]); 4043 printk(KERN_INFO "%s:host_name:%.8s, adapter_name " 4044 ":%.8s api_type: %.8s\n", 4045 dev->name, p_env->host_name, 4046 p_env->adapter_name , p_env->api_type); 4047 return 0; 4048out: 4049 ccw_device_set_offline(cgdev->cdev[1]); 4050 ccw_device_set_offline(cgdev->cdev[0]); 4051 4052 return -ENODEV; 4053} 4054 4055static void 4056claw_purge_skb_queue(struct sk_buff_head *q) 4057{ 4058 struct sk_buff *skb; 4059 4060 CLAW_DBF_TEXT(4,trace,"purgque"); 4061 4062 while ((skb = skb_dequeue(q))) { 4063 atomic_dec(&skb->users); 4064 dev_kfree_skb_irq(skb); 4065 } 4066} 4067 4068/** 4069 * Shutdown an interface. 4070 * 4071 * @param cgdev Device to be shut down. 4072 * 4073 * @returns 0 on success, !0 on failure. 4074 */ 4075static int 4076claw_shutdown_device(struct ccwgroup_device *cgdev) 4077{ 4078 struct claw_privbk *priv; 4079 struct net_device *ndev; 4080 int ret; 4081 4082 pr_debug("%s() called\n", __FUNCTION__); 4083 CLAW_DBF_TEXT_(2,setup,"%s",cgdev->dev.bus_id); 4084 priv = cgdev->dev.driver_data; 4085 if (!priv) 4086 return -ENODEV; 4087 ndev = priv->channel[READ].ndev; 4088 if (ndev) { 4089 /* Close the device */ 4090 printk(KERN_INFO 4091 "%s: shuting down \n",ndev->name); 4092 if (ndev->flags & IFF_RUNNING) 4093 ret = claw_release(ndev); 4094 ndev->flags &=~IFF_RUNNING; 4095 unregister_netdev(ndev); 4096 ndev->priv = NULL; /* cgdev data, not ndev's to free */ 4097 claw_free_netdevice(ndev, 1); 4098 priv->channel[READ].ndev = NULL; 4099 priv->channel[WRITE].ndev = NULL; 4100 priv->p_env->ndev = NULL; 4101 } 4102 ccw_device_set_offline(cgdev->cdev[1]); 4103 ccw_device_set_offline(cgdev->cdev[0]); 4104 return 0; 4105} 4106 4107static void 4108claw_remove_device(struct ccwgroup_device *cgdev) 4109{ 4110 struct claw_privbk *priv; 4111 4112 pr_debug("%s() called\n", __FUNCTION__); 4113 CLAW_DBF_TEXT_(2,setup,"%s",cgdev->dev.bus_id); 4114 priv = cgdev->dev.driver_data; 4115 if (!priv) { 4116 printk(KERN_WARNING "claw: %s() no Priv exiting\n",__FUNCTION__); 4117 return; 4118 } 4119 printk(KERN_INFO "claw: %s() called %s will be removed.\n", 4120 __FUNCTION__,cgdev->cdev[0]->dev.bus_id); 4121 if (cgdev->state == CCWGROUP_ONLINE) 4122 claw_shutdown_device(cgdev); 4123 claw_remove_files(&cgdev->dev); 4124 if (priv->p_mtc_envelope!=NULL) { 4125 kfree(priv->p_mtc_envelope); 4126 priv->p_mtc_envelope=NULL; 4127 } 4128 if (priv->p_env != NULL) { 4129 kfree(priv->p_env); 4130 priv->p_env=NULL; 4131 } 4132 if (priv->channel[0].irb != NULL) { 4133 kfree(priv->channel[0].irb); 4134 priv->channel[0].irb=NULL; 4135 } 4136 if (priv->channel[1].irb != NULL) { 4137 kfree(priv->channel[1].irb); 4138 priv->channel[1].irb=NULL; 4139 } 4140 kfree(priv); 4141 cgdev->dev.driver_data=NULL; 4142 cgdev->cdev[READ]->dev.driver_data = NULL; 4143 cgdev->cdev[WRITE]->dev.driver_data = NULL; 4144 put_device(&cgdev->dev); 4145} 4146 4147 4148/* 4149 * sysfs attributes 4150 */ 4151static ssize_t 4152claw_hname_show(struct device *dev, char *buf) 4153{ 4154 struct claw_privbk *priv; 4155 struct claw_env * p_env; 4156 4157 priv = dev->driver_data; 4158 if (!priv) 4159 return -ENODEV; 4160 p_env = priv->p_env; 4161 return sprintf(buf, "%s\n",p_env->host_name); 4162} 4163 4164static ssize_t 4165claw_hname_write(struct device *dev, const char *buf, size_t count) 4166{ 4167 struct claw_privbk *priv; 4168 struct claw_env * p_env; 4169 4170 priv = dev->driver_data; 4171 if (!priv) 4172 return -ENODEV; 4173 p_env = priv->p_env; 4174 if (count > MAX_NAME_LEN+1) 4175 return -EINVAL; 4176 memset(p_env->host_name, 0x20, MAX_NAME_LEN); 4177 strncpy(p_env->host_name,buf, count); 4178 p_env->host_name[count-1] = 0x20; /* clear extra 0x0a */ 4179 p_env->host_name[MAX_NAME_LEN] = 0x00; 4180 CLAW_DBF_TEXT(2,setup,"HstnSet"); 4181 CLAW_DBF_TEXT_(2,setup,"%s",p_env->host_name); 4182 4183 return count; 4184} 4185 4186static DEVICE_ATTR(host_name, 0644, claw_hname_show, claw_hname_write); 4187 4188static ssize_t 4189claw_adname_show(struct device *dev, char *buf) 4190{ 4191 struct claw_privbk *priv; 4192 struct claw_env * p_env; 4193 4194 priv = dev->driver_data; 4195 if (!priv) 4196 return -ENODEV; 4197 p_env = priv->p_env; 4198 return sprintf(buf, "%s\n",p_env->adapter_name); 4199} 4200 4201static ssize_t 4202claw_adname_write(struct device *dev, const char *buf, size_t count) 4203{ 4204 struct claw_privbk *priv; 4205 struct claw_env * p_env; 4206 4207 priv = dev->driver_data; 4208 if (!priv) 4209 return -ENODEV; 4210 p_env = priv->p_env; 4211 if (count > MAX_NAME_LEN+1) 4212 return -EINVAL; 4213 memset(p_env->adapter_name, 0x20, MAX_NAME_LEN); 4214 strncpy(p_env->adapter_name,buf, count); 4215 p_env->adapter_name[count-1] = 0x20; /* clear extra 0x0a */ 4216 p_env->adapter_name[MAX_NAME_LEN] = 0x00; 4217 CLAW_DBF_TEXT(2,setup,"AdnSet"); 4218 CLAW_DBF_TEXT_(2,setup,"%s",p_env->adapter_name); 4219 4220 return count; 4221} 4222 4223static DEVICE_ATTR(adapter_name, 0644, claw_adname_show, claw_adname_write); 4224 4225static ssize_t 4226claw_apname_show(struct device *dev, char *buf) 4227{ 4228 struct claw_privbk *priv; 4229 struct claw_env * p_env; 4230 4231 priv = dev->driver_data; 4232 if (!priv) 4233 return -ENODEV; 4234 p_env = priv->p_env; 4235 return sprintf(buf, "%s\n", 4236 p_env->api_type); 4237} 4238 4239static ssize_t 4240claw_apname_write(struct device *dev, const char *buf, size_t count) 4241{ 4242 struct claw_privbk *priv; 4243 struct claw_env * p_env; 4244 4245 priv = dev->driver_data; 4246 if (!priv) 4247 return -ENODEV; 4248 p_env = priv->p_env; 4249 if (count > MAX_NAME_LEN+1) 4250 return -EINVAL; 4251 memset(p_env->api_type, 0x20, MAX_NAME_LEN); 4252 strncpy(p_env->api_type,buf, count); 4253 p_env->api_type[count-1] = 0x20; /* we get a loose 0x0a */ 4254 p_env->api_type[MAX_NAME_LEN] = 0x00; 4255 if(strncmp(p_env->api_type,WS_APPL_NAME_PACKED,6) == 0) { 4256 p_env->read_size=DEF_PACK_BUFSIZE; 4257 p_env->write_size=DEF_PACK_BUFSIZE; 4258 p_env->packing=PACKING_ASK; 4259 CLAW_DBF_TEXT(2,setup,"PACKING"); 4260 } 4261 else { 4262 p_env->packing=0; 4263 p_env->read_size=CLAW_FRAME_SIZE; 4264 p_env->write_size=CLAW_FRAME_SIZE; 4265 CLAW_DBF_TEXT(2,setup,"ApiSet"); 4266 } 4267 CLAW_DBF_TEXT_(2,setup,"%s",p_env->api_type); 4268 return count; 4269} 4270 4271static DEVICE_ATTR(api_type, 0644, claw_apname_show, claw_apname_write); 4272 4273static ssize_t 4274claw_wbuff_show(struct device *dev, char *buf) 4275{ 4276 struct claw_privbk *priv; 4277 struct claw_env * p_env; 4278 4279 priv = dev->driver_data; 4280 if (!priv) 4281 return -ENODEV; 4282 p_env = priv->p_env; 4283 return sprintf(buf, "%d\n", p_env->write_buffers); 4284} 4285 4286static ssize_t 4287claw_wbuff_write(struct device *dev, const char *buf, size_t count) 4288{ 4289 struct claw_privbk *priv; 4290 struct claw_env * p_env; 4291 int nnn,max; 4292 4293 priv = dev->driver_data; 4294 if (!priv) 4295 return -ENODEV; 4296 p_env = priv->p_env; 4297 sscanf(buf, "%i", &nnn); 4298 if (p_env->packing) { 4299 max = 64; 4300 } 4301 else { 4302 max = 512; 4303 } 4304 if ((nnn > max ) || (nnn < 2)) 4305 return -EINVAL; 4306 p_env->write_buffers = nnn; 4307 CLAW_DBF_TEXT(2,setup,"Wbufset"); 4308 CLAW_DBF_TEXT_(2,setup,"WB=%d",p_env->write_buffers); 4309 return count; 4310} 4311 4312static DEVICE_ATTR(write_buffer, 0644, claw_wbuff_show, claw_wbuff_write); 4313 4314static ssize_t 4315claw_rbuff_show(struct device *dev, char *buf) 4316{ 4317 struct claw_privbk *priv; 4318 struct claw_env * p_env; 4319 4320 priv = dev->driver_data; 4321 if (!priv) 4322 return -ENODEV; 4323 p_env = priv->p_env; 4324 return sprintf(buf, "%d\n", p_env->read_buffers); 4325} 4326 4327static ssize_t 4328claw_rbuff_write(struct device *dev, const char *buf, size_t count) 4329{ 4330 struct claw_privbk *priv; 4331 struct claw_env *p_env; 4332 int nnn,max; 4333 4334 priv = dev->driver_data; 4335 if (!priv) 4336 return -ENODEV; 4337 p_env = priv->p_env; 4338 sscanf(buf, "%i", &nnn); 4339 if (p_env->packing) { 4340 max = 64; 4341 } 4342 else { 4343 max = 512; 4344 } 4345 if ((nnn > max ) || (nnn < 2)) 4346 return -EINVAL; 4347 p_env->read_buffers = nnn; 4348 CLAW_DBF_TEXT(2,setup,"Rbufset"); 4349 CLAW_DBF_TEXT_(2,setup,"RB=%d",p_env->read_buffers); 4350 return count; 4351} 4352 4353static DEVICE_ATTR(read_buffer, 0644, claw_rbuff_show, claw_rbuff_write); 4354 4355static struct attribute *claw_attr[] = { 4356 &dev_attr_read_buffer.attr, 4357 &dev_attr_write_buffer.attr, 4358 &dev_attr_adapter_name.attr, 4359 &dev_attr_api_type.attr, 4360 &dev_attr_host_name.attr, 4361 NULL, 4362}; 4363 4364static struct attribute_group claw_attr_group = { 4365 .attrs = claw_attr, 4366}; 4367 4368static int 4369claw_add_files(struct device *dev) 4370{ 4371 pr_debug("%s() called\n", __FUNCTION__); 4372 CLAW_DBF_TEXT(2,setup,"add_file"); 4373 return sysfs_create_group(&dev->kobj, &claw_attr_group); 4374} 4375 4376static void 4377claw_remove_files(struct device *dev) 4378{ 4379 pr_debug("%s() called\n", __FUNCTION__); 4380 CLAW_DBF_TEXT(2,setup,"rem_file"); 4381 sysfs_remove_group(&dev->kobj, &claw_attr_group); 4382} 4383 4384/*--------------------------------------------------------------------* 4385* claw_init and cleanup * 4386*---------------------------------------------------------------------*/ 4387 4388static void __exit 4389claw_cleanup(void) 4390{ 4391 unregister_cu3088_discipline(&claw_group_driver); 4392 claw_unregister_debug_facility(); 4393 printk(KERN_INFO "claw: Driver unloaded\n"); 4394 4395} 4396 4397/** 4398 * Initialize module. 4399 * This is called just after the module is loaded. 4400 * 4401 * @return 0 on success, !0 on error. 4402 */ 4403static int __init 4404claw_init(void) 4405{ 4406 int ret = 0; 4407 printk(KERN_INFO "claw: starting driver " 4408#ifdef MODULE 4409 "module " 4410#else 4411 "compiled into kernel " 4412#endif 4413 " $Revision: 1.35 $ $Date: 2005/03/24 12:25:38 $ \n"); 4414 4415 4416#ifdef FUNCTRACE 4417 printk(KERN_INFO "claw: %s() enter \n",__FUNCTION__); 4418#endif 4419 ret = claw_register_debug_facility(); 4420 if (ret) { 4421 printk(KERN_WARNING "claw: %s() debug_register failed %d\n", 4422 __FUNCTION__,ret); 4423 return ret; 4424 } 4425 CLAW_DBF_TEXT(2,setup,"init_mod"); 4426 ret = register_cu3088_discipline(&claw_group_driver); 4427 if (ret) { 4428 claw_unregister_debug_facility(); 4429 printk(KERN_WARNING "claw; %s() cu3088 register failed %d\n", 4430 __FUNCTION__,ret); 4431 } 4432#ifdef FUNCTRACE 4433 printk(KERN_INFO "claw: %s() exit \n",__FUNCTION__); 4434#endif 4435 return ret; 4436} 4437 4438module_init(claw_init); 4439module_exit(claw_cleanup); 4440 4441 4442 4443/*--------------------------------------------------------------------* 4444* End of File * 4445*---------------------------------------------------------------------*/ 4446 4447