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

📄 farsync.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		{			sppp_detach ( dev );			MOD_DEC_USE_COUNT;			return err;		}                break;        case FST_MONITOR:        case FST_RAW:                break;        default:                dbg ( DBG_OPEN,"open: Unknown proto %d\n", port->proto );                break;        }        fst_openport ( port );        netif_wake_queue ( dev );        return 0;}static intfst_close ( struct net_device *dev ){        struct fst_port_info *port;        port = dev->priv;        netif_stop_queue ( dev );        switch ( port->proto )        {        case FST_HDLC:        case FST_PPP:                sppp_close ( dev );                sppp_detach ( dev );                break;        case FST_MONITOR:        case FST_RAW:                break;        default:                dbg ( DBG_OPEN,"close: Unknown proto %d\n", port->proto );                break;        }        fst_closeport ( port );        MOD_DEC_USE_COUNT;        return 0;}static voidfst_tx_timeout ( struct net_device *dev ){        struct fst_port_info *port;        dbg ( DBG_INTR | DBG_TX,"tx_timeout\n");        port = dev->priv;        port->stats.tx_errors++;        port->stats.tx_aborted_errors++;        if ( port->txcnt > 0 )                fst_issue_cmd ( port, ABORTTX );        dev->trans_start = jiffies;        netif_wake_queue ( dev );}static intfst_start_xmit ( struct sk_buff *skb, struct net_device *dev ){        struct fst_card_info *card;        struct fst_port_info *port;        unsigned char dmabits;        unsigned long flags;        int pi;        int txp;        port = dev->priv;        card = port->card;        /* Drop packet if in monitor (rx only) mode */        if ( port->proto == FST_MONITOR )        {                dev_kfree_skb ( skb );                return 0;        }        /* Drop packet with error if we don't have carrier */        if ( ! netif_carrier_ok ( dev ))        {                dev_kfree_skb ( skb );                port->stats.tx_errors++;                port->stats.tx_carrier_errors++;                return 0;        }        /* Drop it if it's too big! MTU failure ? */        if ( skb->len > LEN_TX_BUFFER )        {                dbg ( DBG_TX,"Packet too large %d vs %d\n", skb->len,                                                LEN_TX_BUFFER );                dev_kfree_skb ( skb );                port->stats.tx_errors++;                return 0;        }        /* Check we have a buffer */        pi = port->index;        spin_lock_irqsave ( &card->card_lock, flags );        txp = port->txpos;        dmabits = FST_RDB ( card, txDescrRing[pi][txp].bits );        if ( dmabits & DMA_OWN )        {                spin_unlock_irqrestore ( &card->card_lock, flags );                dbg ( DBG_TX,"Out of Tx buffers\n");                dev_kfree_skb ( skb );                port->stats.tx_errors++;                return 0;        }        if ( ++port->txpos >= NUM_TX_BUFFER )                port->txpos = 0;        if ( ++port->txcnt >= NUM_TX_BUFFER )                netif_stop_queue ( dev );        /* Release the card lock before we copy the data as we now have         * exclusive access to the buffer.         */        spin_unlock_irqrestore ( &card->card_lock, flags );        /* Enqueue the packet */        memcpy_toio ( card->mem + BUF_OFFSET ( txBuffer[pi][txp][0]),                                                skb->data, skb->len );        FST_WRW ( card, txDescrRing[pi][txp].bcnt, cnv_bcnt ( skb->len ));        FST_WRB ( card, txDescrRing[pi][txp].bits, DMA_OWN | TX_STP | TX_ENP );        port->stats.tx_packets++;        port->stats.tx_bytes += skb->len;        dev_kfree_skb ( skb );        dev->trans_start = jiffies;        return 0;}static struct net_device_stats *fst_get_stats ( struct net_device *dev ){        struct fst_port_info *port;        if (( port = dev->priv ) != NULL )                return &port->stats;        else                return NULL;}/* *      Card setup having checked hardware resources. *      Should be pretty bizarre if we get an error here (kernel memory *      exhaustion is one possibility). If we do see a problem we report it *      via a printk and leave the corresponding interface and all that follow *      disabled. */static char *type_strings[] __devinitdata = {        "no hardware",                  /* Should never be seen */        "FarSync T2P",        "FarSync T4P"};static void __devinitfst_init_card ( struct fst_card_info *card ){        int i;        int err;        struct net_device *dev;        /* We're working on a number of ports based on the card ID. If the         * firmware detects something different later (should never happen)         * we'll have to revise it in some way then.         */        for ( i = 0 ; i < card->nports ; i++ )        {                card->ports[i].if_ptr = &card->ports[i].pppdev;                card->ports[i].card   = card;                card->ports[i].index  = i;                card->ports[i].proto  = FST_HDLC;                card->ports[i].run    = 0;                dev = kmalloc ( sizeof ( struct net_device ), GFP_KERNEL );                if ( dev == NULL )                {                        printk_err ("Cannot allocate net_device for port %d\n",                                        i );                        /* No point going any further */                        card->nports = i;                        break;                }                memset ( dev, 0, sizeof ( struct net_device ));                card->ports[i].dev = dev;                if ( dev_alloc_name ( dev, FST_NDEV_NAME "%d") < 0 )                {                        printk_err ("Cannot allocate i/f name for port %d\n",                                        i );                        kfree ( dev );                        card->nports = i;                        break;                }                /* Fill in remainder of the net device info */                                /* Since this is a PCI setup this is purely                                 * informational. Give them the buffer addresses                                 * and basic card I/O.                                 */                dev->mem_start   = card->phys_mem                                 + BUF_OFFSET ( txBuffer[i][0][0]);                dev->mem_end     = card->phys_mem                                 + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);                dev->rmem_start  = card->phys_mem                                 + BUF_OFFSET ( rxBuffer[i][0][0]);                dev->rmem_end    = card->phys_mem                                 + BUF_OFFSET ( rxBuffer[i][NUM_RX_BUFFER][0]);                dev->base_addr   = card->pci_conf;                dev->irq         = card->irq;                dev->get_stats          = fst_get_stats;                dev->mtu                = FST_DEF_MTU;                dev->change_mtu         = fst_change_mtu;                dev->priv               = &card->ports[i];                dev->tx_queue_len       = FST_TX_QUEUE_LEN;                dev->type               = ARPHRD_MYTYPE;                dev->addr_len           = 0;                dev->open               = fst_open;                dev->stop               = fst_close;                dev->hard_start_xmit    = fst_start_xmit;                dev->do_ioctl           = fst_ioctl;                dev->watchdog_timeo     = FST_TX_TIMEOUT;                dev->tx_timeout         = fst_tx_timeout;                dev->flags              = IFF_POINTOPOINT|IFF_NOARP;                if (( err = register_netdev ( dev )) < 0 )                {                        printk_err ("Cannot register %s (errno %d)\n",                                        dev->name, -err );                        kfree ( dev );                        card->nports = i;                        break;                }        }        spin_lock_init ( &card->card_lock );        printk ( KERN_INFO "%s-%s: %s IRQ%d, %d ports\n",                        card->ports[0].dev->name,                        card->ports[card->nports-1].dev->name,                        type_strings[card->type], card->irq, card->nports );}/* *      Initialise card when detected. *      Returns 0 to indicate success, or errno otherwise. */static int __devinitfst_add_one ( struct pci_dev *pdev, const struct pci_device_id *ent ){        static int firsttime_done = 0;        struct fst_card_info *card;        int err = 0;        if ( ! firsttime_done )        {                printk ( KERN_INFO "FarSync X21 driver " FST_USER_VERSION                                " (c) 2001 FarSite Communications Ltd.\n");                firsttime_done = 1;        }        /* Allocate driver private data */        card = kmalloc ( sizeof ( struct fst_card_info ),  GFP_KERNEL);        if (card == NULL)        {                printk_err ("FarSync card found but insufficient memory for"                                " driver storage\n");                return -ENOMEM;        }        memset ( card, 0, sizeof ( struct fst_card_info ));        /* Record info we need*/        card->irq         = pdev->irq;        card->pci_conf    = pci_resource_start ( pdev, 1 );        card->phys_mem    = pci_resource_start ( pdev, 2 );        card->phys_ctlmem = pci_resource_start ( pdev, 3 );        card->type        = ent->driver_data;        card->nports      = ( ent->driver_data == FST_TYPE_T2P ) ? 2 : 4;        card->state       = FST_UNINIT;        dbg ( DBG_PCI,"type %d nports %d irq %d\n", card->type,                        card->nports, card->irq );        dbg ( DBG_PCI,"conf %04x mem %08x ctlmem %08x\n",                        card->pci_conf, card->phys_mem, card->phys_ctlmem );        /* Check we can get access to the memory and I/O regions */        if ( ! request_region ( card->pci_conf, 0x80,"PLX config regs"))        {                printk_err ("Unable to get config I/O @ 0x%04X\n",                                                card->pci_conf );                err = -ENODEV;                goto error_free_card;        }        if ( ! request_mem_region ( card->phys_mem, FST_MEMSIZE,"Shared RAM"))        {                printk_err ("Unable to get main memory @ 0x%08X\n",                                                card->phys_mem );                err = -ENODEV;                goto error_release_io;        }        if ( ! request_mem_region ( card->phys_ctlmem, 0x10,"Control memory"))        {                printk_err ("Unable to get control memory @ 0x%08X\n",                                                card->phys_ctlmem );                err = -ENODEV;                goto error_release_mem;        }        /* Try to enable the device */        if (( err = pci_enable_device ( pdev )) != 0 )        {                printk_err ("Failed to enable card. Err %d\n", -err );                goto error_release_ctlmem;        }        /* Get virtual addresses of memory regions */        if (( card->mem = ioremap ( card->phys_mem, FST_MEMSIZE )) == NULL )        {                printk_err ("Physical memory remap failed\n");                err = -ENODEV;                goto error_release_ctlmem;        }        if (( card->ctlmem = ioremap ( card->phys_ctlmem, 0x10 )) == NULL )        {                printk_err ("Control memory remap failed\n");                err = -ENODEV;                goto error_unmap_mem;        }        dbg ( DBG_PCI,"kernel mem %p, ctlmem %p\n", card->mem, card->ctlmem);        /* Reset the card's processor */        fst_cpureset ( card );        card->state = FST_RESET;        /* Register the interrupt handler */        if ( request_irq ( card->irq, fst_intr, SA_SHIRQ, FST_DEV_NAME, card ))        {                printk_err ("Unable to register interrupt %d\n", card->irq );                err = -ENODEV;                goto error_unmap_ctlmem;        }        /* Record driver data for later use */        pci_set_drvdata(pdev, card);        /* Remainder of card setup */        fst_init_card ( card );        return 0;                       /* Success */                                        /* Failure. Release resources */error_unmap_ctlmem:        iounmap ( card->ctlmem );error_unmap_mem:        iounmap ( card->mem );error_release_ctlmem:        release_mem_region ( card->phys_ctlmem, 0x10 );error_release_mem:        release_mem_region ( card->phys_mem, FST_MEMSIZE );error_release_io:        release_region ( card->pci_conf, 0x80 );error_free_card:        kfree ( card );        return err;}/* *      Cleanup and close down a card */static void __devexitfst_remove_one ( struct pci_dev *pdev ){        struct fst_card_info *card;        int i;        card = pci_get_drvdata(pdev);        for ( i = 0 ; i < card->nports ; i++ )        {                unregister_netdev ( card->ports[i].dev );                kfree ( card->ports[i].dev );        }        fst_disable_intr ( card );        free_irq ( card->irq, card );        iounmap ( card->ctlmem );        iounmap ( card->mem );        release_mem_region ( card->phys_ctlmem, 0x10 );        release_mem_region ( card->phys_mem, FST_MEMSIZE );        release_region ( card->pci_conf, 0x80 );        kfree ( card );}static struct pci_driver fst_driver = {        name:           FST_NAME,        id_table:       fst_pci_dev_id,        probe:          fst_add_one,        remove:         __devexit_p(fst_remove_one),        suspend:        NULL,        resume:         NULL,};static int __initfst_init(void){        return pci_module_init ( &fst_driver );}static void __exitfst_cleanup_module(void){        pci_unregister_driver ( &fst_driver );}module_init ( fst_init );module_exit ( fst_cleanup_module );MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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