mc_pcmcia_cs.c

来自「canpie 一个can bus的协议栈 - CAN interface fo」· C语言 代码 · 共 633 行 · 第 1/2 页

C
633
字号
   link->conf.Vcc = conf.Vcc;      //----------------------------------------------------------------   // In this loop, we scan the CIS for configuration table entries,   // each of which describes a valid card configuration, including   // voltage, IO window, memory window, and interrupt settings.   //   tuple.DesiredTuple   = CISTPL_CFTABLE_ENTRY;   tuple.Attributes     = 0;   CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));   while (1)    {            if( pcmcia_get_tuple_data(handle, &tuple) != 0 ||          pcmcia_parse_tuple(handle, &tuple, &parse) != 0)      {         goto next_entry;      }            //--------------------------------------------------------      // IRQ settings      //      /*      if(cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)      {         link->conf.Attributes |= CONF_ENABLE_IRQ;      }      */            //--------------------------------------------------------      // I/O window settings      //      link->io.NumPorts1 = 0;      link->io.NumPorts2 = 0;      if( (cfg->io.nwin > 0) || (dflt.io.nwin > 0) )       {         cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;         link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;         if( !(io->flags & CISTPL_IO_8BIT) )         {            link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;         }         if( !(io->flags & CISTPL_IO_16BIT))         {            link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;         }                  link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;         link->io.BasePort1   = io->win[0].base;         link->io.NumPorts1   = io->win[0].len;         if(io->nwin > 1)          {            link->io.Attributes2 = link->io.Attributes1;            link->io.BasePort2   = io->win[1].base;            link->io.NumPorts2   = io->win[1].len;         }                  //------------------------------------------------         // This reserves IO space but doesn't actually          // enable it         //         if(pcmcia_request_io(link->handle, &link->io) != 0)         {            goto next_entry;         }               }          //-----------------------------------------------      // If we've got this far, we're done      //      break;         next_entry:      if(cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;      CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));   }   // link->irq.Attributes = IRQ_FORCED_PULSE;   //CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));   PK_DBG("Conf. I/O-Base=%04X I/O-Num=%02d  IRQ=%02d Attributes=%X",             link->io.BasePort1, link->io.NumPorts1,             link->irq.AssignedIRQ, link->irq.Attributes);   request_region(link->io.BasePort1, link->io.NumPorts1, CP_DRV_NAME);      CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));         sprintf(dev->node.dev_name, CP_DRV_NAME);   dev->node.major = 0;   dev->node.minor = 0;   dev->irg = 0;   dev->port = link->io.BasePort1;   link->dev = &dev->node;   //----------------------------------------------------------------   // reset the PCMCIA card   //   mc_pcmcia_set_info(link->priv);   mc_pcmcia_reset();   mc_pcmcia_task_start();   link->state &= ~DEV_CONFIG_PENDING;   return;    cs_failed:   cs_error(link->handle, last_fn, last_ret);// failed:   mc_pcmcia_release(link);   link->state &= ~DEV_CONFIG_PENDING;}//----------------------------------------------------------------------------//// mc_pcmcia_release()                                                        //// After a card is removed, mc_pcmcia_release() will unregister the device,   //// and release the PCMCIA configuration. If the device is still open,         //// this will be postponed until it is closed.                                 ////                                                                            ////----------------------------------------------------------------------------//void mc_pcmcia_release(dev_link_t *link){   PK_DBG("mc_pcmcia_release(0x%p)\n", link);   mc_pcmcia_task_stop();   if(link->open)   {      PK_DBG("release postponed, still open");      link->state |= DEV_STALE_CONFIG;      return;   }   if(link->win)   {      pcmcia_release_window(link->win);   }          //----------------------------------------------------------------   // release the open ports   //   release_region(link->io.BasePort1, link->io.NumPorts1);   free_irq(link->irq.AssignedIRQ, link->priv);         pcmcia_release_configuration(link->handle);      if(link->io.NumPorts1)   {      pcmcia_release_io(link->handle, &link->io);   }          link->state &= ~DEV_CONFIG; }//----------------------------------------------------------------------------//// mc_pcmcia_event()                                                          //// The card status event handler.  Mostly, this schedules other stuff to run  //// after an event is received. When a CARD_REMOVAL event is received, we      //// immediately set a private flag to block future accesses to this device.    //// All the functions that actually access the device should check this flag   //// to make sure the card is still present.//----------------------------------------------------------------------------//static int mc_pcmcia_event(event_t event, int priority,                            event_callback_args_t *args){   dev_link_t *      link  = args->client_data;   _TsMcPcmciaInfo * dev   = link->priv;       PK_DBG("mc_pcmcia_event()");       switch (event)   {      case CS_EVENT_CARD_REMOVAL:         PK_DBG("CS_EVENT_CARD_REMOVAL");         link->state &= ~DEV_PRESENT;         if(link->state & DEV_CONFIG)         {            mc_pcmcia_release(link);         }         break;      case CS_EVENT_CARD_INSERTION:         PK_DBG("CS_EVENT_CARD_INSERTION");         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;         mc_pcmcia_config(link);         break;      case CS_EVENT_PM_SUSPEND:         PK_DBG("CS_EVENT_PM_SUSPEND");         link->state |= DEV_SUSPEND;         //--- Fall through... --------      case CS_EVENT_RESET_PHYSICAL:         PK_DBG("CS_EVENT_RESET_PHYSICAL");         // Mark the device as stopped, to block IO until later         dev->stop = 1;         if(link->state & DEV_CONFIG)         {            pcmcia_release_configuration(link->handle);         }         break;      case CS_EVENT_PM_RESUME:         PK_DBG("CS_EVENT_PM_RESUME");         link->state &= ~DEV_SUSPEND;         /* Fall through... */      case CS_EVENT_CARD_RESET:         PK_DBG("CS_EVENT_CARD_RESET");         if(link->state & DEV_CONFIG)         {            pcmcia_request_configuration(link->handle, &link->conf);         }         dev->stop = 0;         /*         In a normal driver, additional code may go here to restore         the device state and restart IO.         */         break;   }   return 0;}#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)static struct pcmcia_device_id mc_pcmcia_cs_ids[] = {	PCMCIA_DEVICE_MANF_CARD(0x0000, 0xe386), /* CAN */	PCMCIA_DEVICE_NULL,};MODULE_DEVICE_TABLE(pcmcia, mc_pcmcia_cs_ids);#endif/*----------------------------------------------------------------------------*\** Initialization structures / functions                                      ****                                                                            **\*----------------------------------------------------------------------------*/static struct pcmcia_driver mc_pcmcia_driver = {   .owner	= THIS_MODULE,   .drv		= {      .name = "can_mc_pcmcia",   },#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)   .probe	     = mc_pcmcia_attach,   .remove	= mc_pcmcia_detach,   .id_table   = mc_pcmcia_cs_ids,#else	   .attach	= mc_pcmcia_attach,   .detach	= mc_pcmcia_detach,#endif};//----------------------------------------------------------------------------//// init_mc_pcmcia_cs()                                                        ////                                                                            ////----------------------------------------------------------------------------//static int __init init_mc_pcmcia_cs(void){   int   slStatusT;      PK_INF("Init driver for MicroControl PCMCIA CAN card ..");      //----------------------------------------------------------------   // register PCMCIA driver / services and assign   // the resources for the PCMCIA CAN interface   //   slStatusT = pcmcia_register_driver(&mc_pcmcia_driver);      //----------------------------------------------------------------   // start the CANpie driver for the CAN interface   //   mc_pcmcia_can_register(&auwMcPcmciaPortS[0]);      return(slStatusT);}//----------------------------------------------------------------------------//// exit_mc_pcmcia_cs()                                                        ////                                                                            ////----------------------------------------------------------------------------//static void __exit exit_mc_pcmcia_cs(void){   PK_INF("Remove driver for MicroControl PCMCIA CAN card ..");      mc_pcmcia_can_unregister();      pcmcia_unregister_driver(&mc_pcmcia_driver);}//----------------------------------------------------------------------------//// module_init()                                                              ////                                                                            ////----------------------------------------------------------------------------//module_init(init_mc_pcmcia_cs);//----------------------------------------------------------------------------//// module_exit()                                                              ////                                                                            ////----------------------------------------------------------------------------//module_exit(exit_mc_pcmcia_cs);

⌨️ 快捷键说明

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