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

📄 toshoboe.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    );  self = (struct toshoboe_cb *) dev->priv;  ASSERT (self != NULL, return 0;    );  if (self->stopped)    return 0;  if (request_irq (self->io.irq, toshoboe_interrupt,                   SA_SHIRQ | SA_INTERRUPT, dev->name, (void *) self))    {      return -EAGAIN;    }  toshoboe_initbuffs (self);  toshoboe_enablebm (self);  toshoboe_startchip (self);  toshoboe_initptrs (self);  /* Ready to play! */  netif_start_queue(dev);    /*    * Open new IrLAP layer instance, now that everything should be   * initialized properly    */  self->irlap = irlap_open(dev, &self->qos);	  self->open = 1;	  MOD_INC_USE_COUNT;  return 0;}static inttoshoboe_net_close (struct net_device *dev){  struct toshoboe_cb *self;  IRDA_DEBUG (4, __FUNCTION__ "()\n");  ASSERT (dev != NULL, return -1;    );  self = (struct toshoboe_cb *) dev->priv;  /* Stop device */  netif_stop_queue(dev);      /* Stop and remove instance of IrLAP */  if (self->irlap)	  irlap_close(self->irlap);  self->irlap = NULL;  self->open = 0;  free_irq (self->io.irq, (void *) self);  if (!self->stopped)    {      toshoboe_stopchip (self);      toshoboe_disablebm (self);    }  MOD_DEC_USE_COUNT;  return 0;}/* * Function toshoboe_net_ioctl (dev, rq, cmd) * *    Process IOCTL commands for this device * */static int toshoboe_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd){	struct if_irda_req *irq = (struct if_irda_req *) rq;	struct toshoboe_cb *self;	unsigned long flags;	int ret = 0;	ASSERT(dev != NULL, return -1;);	self = dev->priv;	ASSERT(self != NULL, return -1;);	IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);		/* Disable interrupts & save flags */	save_flags(flags);	cli();		switch (cmd) {	case SIOCSBANDWIDTH: /* Set bandwidth */		if (!capable(CAP_NET_ADMIN))			return -EPERM;		/* toshoboe_setbaud(self, irq->ifr_baudrate); */                /* Just change speed once - inserted by Paul Bristow */	        self->new_speed = irq->ifr_baudrate;		break;	case SIOCSMEDIABUSY: /* Set media busy */		if (!capable(CAP_NET_ADMIN))			return -EPERM;		irda_device_set_media_busy(self->netdev, TRUE);		break;	case SIOCGRECEIVING: /* Check if we are receiving right now */		irq->ifr_receiving = 0; /* Can't tell */		break;	default:		ret = -EOPNOTSUPP;	}		restore_flags(flags);		return ret;}#ifdef MODULEMODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");MODULE_PARM (max_baud, "i");MODULE_PARM_DESC(max_baus, "Maximum baud rate");static inttoshoboe_close (struct toshoboe_cb *self){  int i;  IRDA_DEBUG (4, __FUNCTION__ "()\n");  ASSERT (self != NULL, return -1;    );  if (!self->stopped)    {      toshoboe_stopchip (self);      toshoboe_disablebm (self);    }  release_region (self->io.sir_base, self->io.sir_ext);  for (i = 0; i < TX_SLOTS; ++i)    {      kfree (self->xmit_bufs[i]);      self->xmit_bufs[i] = NULL;    }  for (i = 0; i < RX_SLOTS; ++i)    {      kfree (self->recv_bufs[i]);      self->recv_bufs[i] = NULL;    }  if (self->netdev) {	  /* Remove netdevice */	  rtnl_lock();	  unregister_netdevice(self->netdev);	  rtnl_unlock();  }  kfree (self->taskfilebuf);  self->taskfilebuf = NULL;  self->taskfile = NULL;  return (0);}#endifstatic inttoshoboe_open (struct pci_dev *pci_dev){  struct toshoboe_cb *self;  struct net_device *dev;  struct pm_dev *pmdev;  int i = 0;  int ok = 0;  int err;  IRDA_DEBUG (4, __FUNCTION__ "()\n");  while (dev_self[i])    i++;  if (i == NSELFS)    {      printk (KERN_ERR "Oboe: No more instances available");      return -ENOMEM;    }  self = kmalloc (sizeof (struct toshoboe_cb), GFP_KERNEL);  if (self == NULL)    {      printk (KERN_ERR "IrDA: Can't allocate memory for "              "IrDA control block!\n");      return -ENOMEM;    }  memset (self, 0, sizeof (struct toshoboe_cb));  dev_self[i] = self;           /*This needs moving if we ever get more than one chip */  self->open = 0;  self->stopped = 0;  self->pdev = pci_dev;  self->base = pci_dev->resource[0].start;  self->io.sir_base = self->base;  self->io.irq = pci_dev->irq;  self->io.sir_ext = CHIP_IO_EXTENT;  self->io.speed = 9600;  /* Lock the port that we need */  i = check_region (self->io.sir_base, self->io.sir_ext);  if (i < 0)    {      IRDA_DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",             self->io.sir_base);      dev_self[i] = NULL;      kfree (self);      return -ENODEV;    }  irda_init_max_qos_capabilies (&self->qos);  self->qos.baud_rate.bits = 0;  if (max_baud >= 2400)    self->qos.baud_rate.bits |= IR_2400;  /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */  if (max_baud >= 9600)    self->qos.baud_rate.bits |= IR_9600;  if (max_baud >= 19200)    self->qos.baud_rate.bits |= IR_19200;  if (max_baud >= 115200)    self->qos.baud_rate.bits |= IR_115200;#ifdef ENABLE_FAST  if (max_baud >= 576000)    self->qos.baud_rate.bits |= IR_576000;  if (max_baud >= 1152000)    self->qos.baud_rate.bits |= IR_1152000;  if (max_baud >= 4000000)    self->qos.baud_rate.bits |= (IR_4000000 << 8);#endif  self->qos.min_turn_time.bits = 0xff;  /*FIXME: what does this do? */  irda_qos_bits_to_value (&self->qos);  self->flags = IFF_SIR | IFF_DMA | IFF_PIO;#ifdef ENABLE_FAST  if (max_baud >= 576000)    self->flags |= IFF_FIR;#endif  /* Now setup the endless buffers we need */  self->txs = 0;  self->rxs = 0;  self->taskfilebuf = kmalloc (OBOE_TASK_BUF_LEN, GFP_KERNEL);  if (!self->taskfilebuf)    {      printk (KERN_ERR "toshoboe: kmalloc for DMA failed()\n");      kfree (self);      return -ENOMEM;    }  memset (self->taskfilebuf, 0, OBOE_TASK_BUF_LEN);  /*We need to align the taskfile on a taskfile size boundary */  {    __u32 addr;    addr = (__u32) self->taskfilebuf;    addr &= ~(sizeof (struct OboeTaskFile) - 1);    addr += sizeof (struct OboeTaskFile);    self->taskfile = (struct OboeTaskFile *) addr;  }  for (i = 0; i < TX_SLOTS; ++i)    {      self->xmit_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);      if (self->xmit_bufs[i])        ok++;    }  for (i = 0; i < RX_SLOTS; ++i)    {      self->recv_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);      if (self->recv_bufs[i])        ok++;    }  if (ok != RX_SLOTS + TX_SLOTS)    {      printk (KERN_ERR "toshoboe: kmalloc for buffers failed()\n");      for (i = 0; i < TX_SLOTS; ++i)        if (self->xmit_bufs[i])          kfree (self->xmit_bufs[i]);      for (i = 0; i < RX_SLOTS; ++i)        if (self->recv_bufs[i])          kfree (self->recv_bufs[i]);      kfree (self);      return -ENOMEM;    }  request_region (self->io.sir_base, self->io.sir_ext, driver_name);  if (!(dev = dev_alloc("irda%d", &err))) {	  ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");	  return -ENOMEM;  }  dev->priv = (void *) self;  self->netdev = dev;    MESSAGE("IrDA: Registered device %s\n", dev->name);  dev->init = toshoboe_net_init;  dev->hard_start_xmit = toshoboe_hard_xmit;  dev->open = toshoboe_net_open;  dev->stop = toshoboe_net_close;  dev->do_ioctl = toshoboe_net_ioctl;  rtnl_lock();  err = register_netdevice(dev);  rtnl_unlock();  if (err) {	  ERROR(__FUNCTION__ "(), register_netdev() failed!\n");	  return -1;  }  pmdev = pm_register (PM_PCI_DEV, PM_PCI_ID(pci_dev), toshoboe_pmproc);  if (pmdev)	  pmdev->data = self;  printk (KERN_WARNING "ToshOboe: Using ");#ifdef ONETASK  printk ("single");#else  printk ("multiple");#endif  printk (" tasks, version %s\n", rcsid);  return (0);}static void toshoboe_gotosleep (struct toshoboe_cb *self){  int i = 10;  printk (KERN_WARNING "ToshOboe: suspending\n");  if (self->stopped)    return;  self->stopped = 1;  if (!self->open)    return;/*FIXME: can't sleep here wait one second */  while ((i--) && (self->txpending))    mdelay (100);  toshoboe_stopchip (self);  toshoboe_disablebm (self);  self->txpending = 0;}static void toshoboe_wakeup (struct toshoboe_cb *self){  unsigned long flags;  if (!self->stopped)    return;  if (!self->open)    {      self->stopped = 0;      return;    }  save_flags (flags);  cli ();  toshoboe_initbuffs (self);  toshoboe_enablebm (self);  toshoboe_startchip (self);  toshoboe_setbaud (self, self->io.speed);  toshoboe_initptrs (self);  netif_wake_queue(self->netdev);  restore_flags (flags);  printk (KERN_WARNING "ToshOboe: waking up\n");}static int toshoboe_pmproc (struct pm_dev *dev, pm_request_t rqst, void *data){  struct toshoboe_cb *self = (struct toshoboe_cb *) dev->data;  if (self) {	  switch (rqst) {	  case PM_SUSPEND:		  toshoboe_gotosleep (self);		  break;	  case PM_RESUME:		  toshoboe_wakeup (self);		  break;	  }  }  return 0;}int __init toshoboe_init (void){  struct pci_dev *pci_dev = NULL;  int found = 0;  do    {      pci_dev = pci_find_device (PCI_VENDOR_ID_TOSHIBA,                                 PCI_DEVICE_ID_FIR701, pci_dev);      if (pci_dev)        {          printk (KERN_WARNING "ToshOboe: Found 701 chip at 0x%0lx irq %d\n",		  pci_dev->resource[0].start,                  pci_dev->irq);          if (!toshoboe_open (pci_dev))	      found++;        }    }  while (pci_dev);  if (found)    {      return 0;    }  return -ENODEV;}#ifdef MODULEstatic voidtoshoboe_cleanup (void){  int i;  IRDA_DEBUG (4, __FUNCTION__ "()\n");  for (i = 0; i < 4; i++)    {      if (dev_self[i])        toshoboe_close (dev_self[i]);    }  pm_unregister_all (toshoboe_pmproc);}intinit_module (void){  return toshoboe_init ();}voidcleanup_module (void){  toshoboe_cleanup ();}#endif

⌨️ 快捷键说明

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