📄 claw.c
字号:
p_env=privptr->p_env;#ifdef IOTRACE printk(KERN_INFO "%s: interrupt for device: %04x " "received c-%02x d-%02x state-%02x\n", dev->name, p_ch->devno, irb->scsw.cstat, irb->scsw.dstat, p_ch->claw_state);#endif /* Copy interruption response block. */ memcpy(p_ch->irb, irb, sizeof(struct irb)); /* Check for good subchannel return code, otherwise error message */ if (irb->scsw.cstat && !(irb->scsw.cstat & SCHN_STAT_PCI)) { printk(KERN_INFO "%s: subchannel check for device: %04x -" " Sch Stat %02x Dev Stat %02x CPA - %04x\n", dev->name, p_ch->devno, irb->scsw.cstat, irb->scsw.dstat,irb->scsw.cpa);#ifdef IOTRACE dumpit((char *)irb,sizeof(struct irb)); dumpit((char *)(unsigned long)irb->scsw.cpa, sizeof(struct ccw1));#endif#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(2,trace,"chanchk"); /* return; */ } /* Check the reason-code of a unit check */ if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { ccw_check_unit_check(p_ch, irb->ecw[0]); } /* State machine to bring the connection up, down and to restart */ p_ch->last_dstat = irb->scsw.dstat; switch (p_ch->claw_state) { case CLAW_STOP:/* HALT_IO by claw_release (halt sequence) */#ifdef DEBUGMSG printk(KERN_INFO "%s: CLAW_STOP enter\n", dev->name);#endif if (!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || (p_ch->irb->scsw.stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) {#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif return; } wake_up(&p_ch->wait); /* wake up claw_release */#ifdef DEBUGMSG printk(KERN_INFO "%s: CLAW_STOP exit\n", dev->name);#endif#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"stop"); return; case CLAW_START_HALT_IO: /* HALT_IO issued by claw_open */#ifdef DEBUGMSG printk(KERN_INFO "%s: process CLAW_STAT_HALT_IO\n", dev->name);#endif if (!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || (p_ch->irb->scsw.stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) {#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"haltio"); return; } if (p_ch->flag == CLAW_READ) { p_ch->claw_state = CLAW_START_READ; wake_up(&p_ch->wait); /* wake claw_open (READ)*/ } else if (p_ch->flag == CLAW_WRITE) { p_ch->claw_state = CLAW_START_WRITE; /* send SYSTEM_VALIDATE */ claw_strt_read(dev, LOCK_NO); claw_send_control(dev, SYSTEM_VALIDATE_REQUEST, 0, 0, 0, p_env->host_name, p_env->adapter_name ); } else { printk(KERN_WARNING "claw: unsolicited " "interrupt for device:" "%s received c-%02x d-%02x\n", cdev->dev.bus_id, irb->scsw.cstat, irb->scsw.dstat); return; }#ifdef DEBUGMSG printk(KERN_INFO "%s: process CLAW_STAT_HALT_IO exit\n", dev->name);#endif#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"haltio"); return; case CLAW_START_READ: CLAW_DBF_TEXT(4,trace,"ReadIRQ"); if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { clear_bit(0, (void *)&p_ch->IO_active); if ((p_ch->irb->ecw[0] & 0x41) == 0x41 || (p_ch->irb->ecw[0] & 0x40) == 0x40 || (p_ch->irb->ecw[0]) == 0) { privptr->stats.rx_errors++; printk(KERN_INFO "%s: Restart is " "required after remote " "side recovers \n", dev->name); }#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"notrdy"); return; } if ((p_ch->irb->scsw.cstat & SCHN_STAT_PCI) && (p_ch->irb->scsw.dstat==0)) { if (test_and_set_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a) == 0) { tasklet_schedule(&p_ch->tasklet); } else { CLAW_DBF_TEXT(4,trace,"PCINoBH"); }#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"PCI_read"); return; } if(!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || (p_ch->irb->scsw.stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) {#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"SPend_rd"); return; } clear_bit(0, (void *)&p_ch->IO_active); claw_clearbit_busy(TB_RETRY,dev); if (test_and_set_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a) == 0) { tasklet_schedule(&p_ch->tasklet); } else { CLAW_DBF_TEXT(4,trace,"RdBHAct"); }#ifdef DEBUGMSG printk(KERN_INFO "%s: process CLAW_START_READ exit\n", dev->name);#endif#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"RdIRQXit"); return; case CLAW_START_WRITE: if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_CHECK) { printk(KERN_INFO "%s: Unit Check Occured in " "write channel\n",dev->name); clear_bit(0, (void *)&p_ch->IO_active); if (p_ch->irb->ecw[0] & 0x80 ) { printk(KERN_INFO "%s: Resetting Event " "occurred:\n",dev->name); init_timer(&p_ch->timer); p_ch->timer.function = (void *)claw_write_retry; p_ch->timer.data = (unsigned long)p_ch; p_ch->timer.expires = jiffies + 10*HZ; add_timer(&p_ch->timer); printk(KERN_INFO "%s: write connection " "restarting\n",dev->name); }#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"rstrtwrt"); return; } if (p_ch->irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) { clear_bit(0, (void *)&p_ch->IO_active); printk(KERN_INFO "%s: Unit Exception " "Occured in write channel\n", dev->name); } if(!((p_ch->irb->scsw.stctl & SCSW_STCTL_SEC_STATUS) || (p_ch->irb->scsw.stctl == SCSW_STCTL_STATUS_PEND) || (p_ch->irb->scsw.stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)))) {#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"writeUE"); return; } clear_bit(0, (void *)&p_ch->IO_active); if (claw_test_and_setbit_busy(TB_TX,dev)==0) { claw_write_next(p_ch); claw_clearbit_busy(TB_TX,dev); claw_clear_busy(dev); } p_ch_r=(struct chbk *)&privptr->channel[READ]; if (test_and_set_bit(CLAW_BH_ACTIVE, (void *)&p_ch_r->flag_a) == 0) { tasklet_schedule(&p_ch_r->tasklet); }#ifdef DEBUGMSG printk(KERN_INFO "%s: process CLAW_START_WRITE exit\n", dev->name);#endif#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"StWtExit"); return; default: printk(KERN_WARNING "%s: wrong selection code - irq " "state=%d\n",dev->name,p_ch->claw_state);#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(2,trace,"badIRQ"); return; }} /* end of claw_irq_handler *//*-------------------------------------------------------------------** claw_irq_tasklet ** **--------------------------------------------------------------------*/static voidclaw_irq_tasklet ( unsigned long data ){ struct chbk * p_ch; struct net_device *dev; struct claw_privbk * privptr; p_ch = (struct chbk *) data; dev = (struct net_device *)p_ch->ndev;#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__);#endif#ifdef DEBUGMSG printk(KERN_INFO "%s: variable p_ch =\n",dev->name); dumpit((char *) p_ch, sizeof(struct chbk));#endif CLAW_DBF_TEXT(4,trace,"IRQtask"); privptr = (struct claw_privbk *) dev->priv;#ifdef DEBUGMSG printk(KERN_INFO "%s: bh routine - state-%02x\n" , dev->name, p_ch->claw_state);#endif unpack_read(dev); clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a); CLAW_DBF_TEXT(4,trace,"TskletXt");#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif return;} /* end of claw_irq_bh *//*-------------------------------------------------------------------** claw_release ** **--------------------------------------------------------------------*/static intclaw_release(struct net_device *dev){ int rc; int i; unsigned long saveflags; unsigned long parm; struct claw_privbk *privptr; DECLARE_WAITQUEUE(wait, current); struct ccwbk* p_this_ccw; struct ccwbk* p_buf; if (!dev) return 0; privptr = (struct claw_privbk *) dev->priv; if (!privptr) return 0;#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Enter \n",dev->name,__FUNCTION__);#endif CLAW_DBF_TEXT(4,trace,"release");#ifdef DEBUGMSG printk(KERN_INFO "%s: variable dev =\n",dev->name); dumpit((char *) dev, sizeof(struct net_device)); printk(KERN_INFO "Priv Buffalloc %d\n",privptr->buffs_alloc); printk(KERN_INFO "Priv p_buff_ccw = %p\n",&privptr->p_buff_ccw);#endif privptr->release_pend=1; claw_setbit_busy(TB_STOP,dev); for ( i = 1; i >=0 ; i--) { spin_lock_irqsave( get_ccwdev_lock(privptr->channel[i].cdev), saveflags); /* del_timer(&privptr->channel[READ].timer); */ privptr->channel[i].claw_state = CLAW_STOP; privptr->channel[i].IO_active = 0; parm = (unsigned long) &privptr->channel[i]; if (i == WRITE) claw_purge_skb_queue( &privptr->channel[WRITE].collect_queue); rc = ccw_device_halt (privptr->channel[i].cdev, parm); if (privptr->system_validate_comp==0x00) /* never opened? */ init_waitqueue_head(&privptr->channel[i].wait); add_wait_queue(&privptr->channel[i].wait, &wait); set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irqrestore( get_ccwdev_lock(privptr->channel[i].cdev), saveflags); schedule(); set_current_state(TASK_RUNNING); remove_wait_queue(&privptr->channel[i].wait, &wait); if (rc != 0) { ccw_check_return_code(privptr->channel[i].cdev, rc); } } if (privptr->pk_skb != NULL) { dev_kfree_skb_any(privptr->pk_skb); privptr->pk_skb = NULL; } if(privptr->buffs_alloc != 1) {#ifdef FUNCTRACE printk(KERN_INFO "%s:%s Exit on line %d\n", dev->name,__FUNCTION__,__LINE__);#endif CLAW_DBF_TEXT(4,trace,"none2fre"); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -