⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 farsync.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 4 页
字号:
                        break;                default:                        printk_err ("intr: unknown card event code. ignored\n");                        break;                }                /* Bump and wrap the index */                if ( ++rdidx >= MAX_CIRBUFF )                        rdidx = 0;        }        FST_WRB ( card, interruptEvent.rdindex, rdidx );        for ( pi = 0, port = card->ports ; pi < card->nports ; pi++, port++ )        {                if ( ! port->run )                        continue;                /* Check for rx completions */                while ( ! ( FST_RDB ( card, rxDescrRing[pi][port->rxpos].bits )                                                                & DMA_OWN ))                {                        fst_intr_rx ( card, port );                }                /* Check for Tx completions */                while ( port->txcnt > 0 && ! ( FST_RDB ( card,                        txDescrRing[pi][port->txipos].bits ) & DMA_OWN ))                {                        --port->txcnt;                        if ( ++port->txipos >= NUM_TX_BUFFER )                                port->txipos = 0;                        netif_wake_queue ( port_to_dev ( port ));                }        }        spin_unlock ( &card->card_lock );}/*      Check that the shared memory configuration is one that we can handle *      and that some basic parameters are correct */static voidcheck_started_ok ( struct fst_card_info *card ){        int i;        /* Check structure version and end marker */        if ( FST_RDW ( card, smcVersion ) != SMC_VERSION )        {                printk_err ("Bad shared memory version %d expected %d\n",                                FST_RDW ( card, smcVersion ), SMC_VERSION );                card->state = FST_BADVERSION;                return;        }        if ( FST_RDL ( card, endOfSmcSignature ) != END_SIG )        {                printk_err ("Missing shared memory signature\n");                card->state = FST_BADVERSION;                return;        }        /* Firmware status flag, 0x00 = initialising, 0x01 = OK, 0xFF = fail */        if (( i = FST_RDB ( card, taskStatus )) == 0x01 )        {                card->state = FST_RUNNING;        }        else if ( i == 0xFF )        {                printk_err ("Firmware initialisation failed. Card halted\n");                card->state = FST_HALTED;                return;        }        else if ( i != 0x00 )        {                printk_err ("Unknown firmware status 0x%x\n", i );                card->state = FST_HALTED;                return;        }        /* Finally check the number of ports reported by firmware against the         * number we assumed at card detection. Should never happen with         * existing firmware etc so we just report it for the moment.         */        if ( FST_RDL ( card, numberOfPorts ) != card->nports )        {                printk_warn ("Port count mismatch."                                " Firmware thinks %d we say %d\n",                                FST_RDL ( card, numberOfPorts ), card->nports );        }}static intset_conf_from_info ( struct fst_card_info *card, struct fst_port_info *port,                struct fstioc_info *info ){        int err;        /* Set things according to the user set valid flags.         * Several of the old options have been invalidated/replaced by the         * generic HDLC package.         */        err = 0;        if ( info->valid & FSTVAL_PROTO )                err = -EINVAL;        if ( info->valid & FSTVAL_CABLE )                err = -EINVAL;        if ( info->valid & FSTVAL_SPEED )                err = -EINVAL;        if ( info->valid & FSTVAL_MODE )                FST_WRW ( card, cardMode, info->cardMode );#if FST_DEBUG        if ( info->valid & FSTVAL_DEBUG )                fst_debug_mask = info->debug;#endif        return err;}static voidgather_conf_info ( struct fst_card_info *card, struct fst_port_info *port,                struct fstioc_info *info ){        int i;        memset ( info, 0, sizeof ( struct fstioc_info ));        i = port->index;        info->nports = card->nports;        info->type   = card->type;        info->state  = card->state;        info->proto  = FST_GEN_HDLC;        info->index  = i;#if FST_DEBUG        info->debug  = fst_debug_mask;#endif        /* Only mark information as valid if card is running.         * Copy the data anyway in case it is useful for diagnostics         */        info->valid                = (( card->state == FST_RUNNING ) ? FSTVAL_ALL : FSTVAL_CARD )#if FST_DEBUG                | FSTVAL_DEBUG#endif                ;        info->lineInterface = FST_RDW ( card, portConfig[i].lineInterface );        info->internalClock = FST_RDB ( card, portConfig[i].internalClock );        info->lineSpeed     = FST_RDL ( card, portConfig[i].lineSpeed );        info->v24IpSts      = FST_RDL ( card, v24IpSts[i] );        info->v24OpSts      = FST_RDL ( card, v24OpSts[i] );        info->clockStatus   = FST_RDW ( card, clockStatus[i] );        info->cableStatus   = FST_RDW ( card, cableStatus );        info->cardMode      = FST_RDW ( card, cardMode );        info->smcFirmwareVersion  = FST_RDL ( card, smcFirmwareVersion );}static intfst_set_iface ( struct fst_card_info *card, struct fst_port_info *port,                struct ifreq *ifr ){        sync_serial_settings sync;        int i;        if (copy_from_user (&sync, ifr->ifr_settings.ifs_ifsu.sync,			    sizeof (sync)))                return -EFAULT;        if ( sync.loopback )                return -EINVAL;        i = port->index;        switch (ifr->ifr_settings.type)        {        case IF_IFACE_V35:                FST_WRW ( card, portConfig[i].lineInterface, V35 );                port->hwif = V35;                break;        case IF_IFACE_V24:                FST_WRW ( card, portConfig[i].lineInterface, V24 );                port->hwif = V24;                break;        case IF_IFACE_X21:                FST_WRW ( card, portConfig[i].lineInterface, X21 );                port->hwif = X21;                break;        case IF_IFACE_SYNC_SERIAL:                break;        default:                return -EINVAL;        }        switch ( sync.clock_type )        {        case CLOCK_EXT:                FST_WRB ( card, portConfig[i].internalClock, EXTCLK );                break;        case CLOCK_INT:                FST_WRB ( card, portConfig[i].internalClock, INTCLK );                break;        default:                return -EINVAL;        }        FST_WRL ( card, portConfig[i].lineSpeed, sync.clock_rate );        return 0;}static intfst_get_iface ( struct fst_card_info *card, struct fst_port_info *port,                struct ifreq *ifr ){        sync_serial_settings sync;        int i;        /* First check what line type is set, we'll default to reporting X.21         * if nothing is set as IF_IFACE_SYNC_SERIAL implies it can't be         * changed         */        switch ( port->hwif )        {        case V35:                ifr->ifr_settings.type = IF_IFACE_V35;                break;        case V24:                ifr->ifr_settings.type = IF_IFACE_V24;                break;        case X21:        default:                ifr->ifr_settings.type = IF_IFACE_X21;                break;        }	if (ifr->ifr_settings.size < sizeof(sync)) {		ifr->ifr_settings.size = sizeof(sync); /* data size wanted */		return -ENOBUFS;	}        i = port->index;        sync.clock_rate = FST_RDL ( card, portConfig[i].lineSpeed );        /* Lucky card and linux use same encoding here */        sync.clock_type = FST_RDB ( card, portConfig[i].internalClock );        sync.loopback = 0;        if (copy_to_user (ifr->ifr_settings.ifs_ifsu.sync, &sync,			  sizeof(sync)))                return -EFAULT;        return 0;}static intfst_ioctl ( struct net_device *dev, struct ifreq *ifr, int cmd ){        struct fst_card_info *card;        struct fst_port_info *port;        struct fstioc_write wrthdr;        struct fstioc_info info;        unsigned long flags;        dbg ( DBG_IOCTL,"ioctl: %x, %p\n", cmd, ifr->ifr_data );        port = dev_to_port ( dev );        card = port->card;        if ( !capable ( CAP_NET_ADMIN ))                return -EPERM;        switch ( cmd )        {        case FSTCPURESET:                fst_cpureset ( card );                card->state = FST_RESET;                return 0;        case FSTCPURELEASE:                fst_cpurelease ( card );                card->state = FST_STARTING;                return 0;        case FSTWRITE:                  /* Code write (download) */                /* First copy in the header with the length and offset of data                 * to write                 */                if ( ifr->ifr_data == NULL )                {                        return -EINVAL;                }                if ( copy_from_user ( &wrthdr, ifr->ifr_data,                                        sizeof ( struct fstioc_write )))                {                        return -EFAULT;                }                /* Sanity check the parameters. We don't support partial writes                 * when going over the top                 */                if ( wrthdr.size > FST_MEMSIZE || wrthdr.offset > FST_MEMSIZE				|| wrthdr.size + wrthdr.offset > FST_MEMSIZE )                {                        return -ENXIO;                }                /* Now copy the data to the card.                 * This will probably break on some architectures.                 * I'll fix it when I have something to test on.                 */                if ( copy_from_user ( card->mem + wrthdr.offset,                                ifr->ifr_data + sizeof ( struct fstioc_write ),                                wrthdr.size ))                {                        return -EFAULT;                }                /* Writes to the memory of a card in the reset state constitute                 * a download                 */                if ( card->state == FST_RESET )                {                        card->state = FST_DOWNLOAD;                }                return 0;        case FSTGETCONF:                /* If card has just been started check the shared memory config                 * version and marker                 */                if ( card->state == FST_STARTING )                {                        check_started_ok ( card );                        /* If everything checked out enable card interrupts */                        if ( card->state == FST_RUNNING )                        {                                spin_lock_irqsave ( &card->card_lock, flags );                                fst_clear_intr ( card );                                FST_WRB ( card, interruptHandshake, 0xEE );                                spin_unlock_irqrestore ( &card->card_lock,                                                                flags );                        }                }                if ( ifr->ifr_data == NULL )                {                        return -EINVAL;                }                gather_conf_info ( card, port, &info );                if ( copy_to_user ( ifr->ifr_data, &info, sizeof ( info )))                {                        return -EFAULT;                }                return 0;        case FSTSETCONF:                /* Most of the setting have been moved to the generic ioctls                 * this just covers debug and board ident mode now                 */                if ( copy_from_user ( &info,  ifr->ifr_data, sizeof ( info )))                {                        return -EFAULT;                }                return set_conf_from_info ( card, port, &info );        case SIOCWANDEV:                switch (ifr->ifr_settings.type)                {                case IF_GET_IFACE:                        return fst_get_iface ( card, port, ifr );                case IF_IFACE_SYNC_SERIAL:                case IF_IFACE_V35:                case IF_IFACE_V24:                case IF_IFACE_X21:                        return fst_set_iface ( card, port, ifr );                default:                        return hdlc_ioctl ( dev, ifr, cmd );                }        default:                /* Not one of ours. Pass through to HDLC package */                return hdlc_ioctl ( dev, ifr, cmd );        }}static voidfst_openport ( struct fst_port_info *port ){        int signals;        /* Only init things if card is actually running. This allows open to         * succeed for downloads etc.         */        if ( port->card->state == FST_RUNNING )        {                if ( port->run )                {                        dbg ( DBG_OPEN,"open: found port already running\n");                        fst_issue_cmd ( port, STOPPORT );                        port->run = 0;                }                fst_rx_config ( port );                fst_tx_config ( port );                fst_op_raise ( port, OPSTS_RTS | OPSTS_DTR );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -