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

📄 cb20_cb.c

📁 vt6656驱动代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  remove_proc_entry("SSID",v_info->device);  remove_proc_entry("Status",v_info->device);  remove_proc_entry(dev->name,cb20_entry);#else  proc_unregister(&cb20_entry,v_info->proc_ssid_entry.low_ino);  proc_unregister(&cb20_entry,status_entry.low_ino);  proc_unregister(&proc_root,cb20_entry.low_ino);#endif  return 0;}static  ssize_t proc_read( struct file *file,char *buffer,size_t len,loff_t *offset ){  int i;  int pos;  struct proc_data *priv = (struct proc_data*)file->private_data;	  if( !priv->rbuffer ) return -EINVAL;    pos = *offset;    for( i = 0; i+pos < priv->readlen && i < len; i++ ) {    put_user( priv->rbuffer[i+pos], buffer+i );  }  *offset += i;  return i;}/* *  The write routine is generic, it fills in a preallocated rbuffer *  to supply the data. */static  ssize_t proc_write( struct file *file,const char *buffer,size_t len,loff_t *offset ) {  int i;  int pos;  struct proc_data *priv = (struct proc_data*)file->private_data;      if ( !priv->wbuffer ) {    return -EINVAL;  }	  pos = *offset;    for( i = 0; i + pos <  priv->maxwritelen &&	 i < len; i++ ) {    get_user( priv->wbuffer[i+pos], buffer + i );  }  if ( i+pos > priv->writelen ) priv->writelen = i+file->f_pos;    *offset += i;  return i;}static  int proc_close( struct inode *inode, struct file *file ) {  struct proc_data *data = (struct proc_data *)file->private_data;    if ( data->on_close != NULL ) data->on_close( inode, file );  MOD_DEC_USE_COUNT;  if ( data->rbuffer ) kfree( data->rbuffer );  if ( data->wbuffer ) kfree( data->wbuffer );  kfree( data );  return 0;}static  void proc_ssid_on_close( struct inode *inode, struct file *file ) {  struct proc_data *data = (struct proc_data *)file->private_data;  struct proc_dir_entry *dp = inode->u.generic_ip;  struct net_device *dev = dp->data;  struct cb20_info *vi = (struct cb20_info*)dev->priv;  PC3500_SID_LIST *SSID_rid;  char ssidp[200];	  int i;  int offset = 0;	  SSID_rid = (PC3500_SID_LIST *)ssidp;    if ( !data->writelen ) return;    memset( SSID_rid, 0, sizeof( SSID_rid ) );    for( i = 0; i < 3; i++ ) {    int j;    for( j = 0; j+offset < data->writelen && j < 32 &&	   data->wbuffer[offset+j] != '\n'; j++ ) {      SSID_rid->aSsid[i].Ssid[j] = data->wbuffer[offset+j];    }    if ( j == 0 ) break;    SSID_rid->aSsid[i].SsidLen = cpu_to_le16(j);    offset += j;    while( data->wbuffer[offset] != '\n' && 	   offset < data->writelen ) offset++;    offset++;  }  SSID_rid->u16RidLen = sizeof(PC3500_SID_LIST) * i;  vwriterid(vi, RID_SSID, (unsigned char *)SSID_rid,sizeof(PC3500_SID_LIST) * i);}static  int proc_ssid_open( struct inode *inode, struct file *file ) {  struct proc_data *data;  struct proc_dir_entry *dp = inode->u.generic_ip;  struct net_device *dev = dp->data;  struct cb20_info *vi = (struct cb20_info*)dev->priv;  int i;  char *ptr,blargbuf[1023];    PC3500_SID_LIST *SSID_rid;	  SSID_rid = (PC3500_SID_LIST *)blargbuf;    MOD_INC_USE_COUNT;    dp = (struct proc_dir_entry *) inode->u.generic_ip;    file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL);  memset(file->private_data, 0, sizeof(struct proc_data));  data = (struct proc_data *)file->private_data;  data->rbuffer = kmalloc( 104, GFP_KERNEL );  data->writelen = 0;  data->maxwritelen = 33*3;  data->wbuffer = kmalloc( 33*3, GFP_KERNEL );  memset( data->wbuffer, 0, 33*3 );  data->on_close = proc_ssid_on_close;	  vreadrid(vi,RID_SSLIST,(unsigned char *)SSID_rid, sizeof(SSID_rid));    ptr = data->rbuffer;    for( i = 0; i < 3; i++ ) {    int j;    if ( !SSID_rid->aSsid[i].SsidLen ) break;    for( j = 0; j < 32 && j < le16_to_cpu(SSID_rid->aSsid[i].SsidLen) 	   && SSID_rid->aSsid[i].Ssid[j]; j++ ) {      *ptr++ = SSID_rid->aSsid[i].Ssid[j];     }    *ptr++ = '\n';  }  *ptr = '\0';  data->readlen = strlen( data->rbuffer );  return 0;}/*  * Status open Changed 10/4/02 for proper display of  * channel. */static  int proc_status_open( struct inode *inode, struct file *file ) {  struct   proc_data *data;  struct   proc_dir_entry *dp = inode->u.generic_ip;  struct   net_device *dev = dp->data;  struct   cb20_info *vi = (struct cb20_info *)dev->priv;  STCAPS   cap_rid;  StatRid  status_rid;  MOD_INC_USE_COUNT;	  dp = (struct proc_dir_entry *) inode->u.generic_ip;    file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL);  memset(file->private_data, 0, sizeof(struct proc_data));  data = (struct proc_data *)file->private_data;  data->rbuffer = kmalloc( 2048, GFP_KERNEL );	  vreadrid(vi,RID_STATUS,(unsigned char *)&status_rid, sizeof(status_rid));  vreadrid(vi,RID_CAPABILITIES,(unsigned char *)&cap_rid, sizeof(cap_rid));  sprintf( data->rbuffer, "Mode: %x\n"	   "Signal Strength: %d\n"	   "Signal Quality: %d\n"	   "SSID: %-.*s\n"	   "AP: %-.16s\n"	   "Channel: %d\n"	   "BitRate: %dmbs\n"	   "Driver Version: %s\n"	   "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"	   "Radio type: %x\nCountry: %x\nHardware Version: %x\n"	   "Software Version: %x\nSoftware Subversion: %x\n"	   "Boot block version: %x\n",	   (int)le16_to_cpu(status_rid.mode),	   (int)le16_to_cpu(status_rid.normalizedSignalStrength),	   (int)le16_to_cpu(status_rid.signalQuality),	   (int)status_rid.SSIDlen,	   status_rid.SSID,	   status_rid.apName,	   (int)le16_to_cpu(status_rid.frq.u16DsChannel),	   (int)le16_to_cpu(status_rid.currentXmitRate)/2,	   version,	   cap_rid.au8ProductName,	   cap_rid.au8ManufacturerName,	   cap_rid.au8ProductVersion,	   le16_to_cpu(cap_rid.u16RadioType),	   le16_to_cpu(cap_rid.u16RegDomain),	   le16_to_cpu(cap_rid.u16HardwareVersion),	   (int)le16_to_cpu(cap_rid.u16SoftwareVersion),	   (int)le16_to_cpu(cap_rid.u16SoftwareSubVersion),	   (int)le16_to_cpu(cap_rid.u16BootBlockVersion) );	data->readlen = strlen( data->rbuffer );	return 0;}/* * @vreadrid * Return 0 on sucess or other on failure . Uses the len value of all rids  * in the first 2 bytes . */static  int vreadrid(struct cb20_info *v_info,unsigned short rid,unsigned char *ridp, int len){  Cmd            cmd;  Resp           rsp;  int            status;  unsigned short *ridlen;  CARD_RID_DESC  *cardDes;  cardDes = (CARD_RID_DESC *)v_info->ConfigDesc.CardRamOff;  memset(&rsp,0,sizeof(rsp));  memset(&cmd,0,sizeof(cmd));  v_info->ConfigDesc.RIDDesc.valid   = 0;  v_info->ConfigDesc.RIDDesc.length  = 1024;  v_info->ConfigDesc.RIDDesc.RID     = rid;  cmd.cmd   = CMD_X500_AccessRIDRead;  cmd.parm0 = rid;  memcpy((char *)v_info->ConfigDesc.CardRamOff,	 (char *)&v_info->ConfigDesc.RIDDesc,sizeof(CARD_RID_DESC));  cardDes->valid=1;  status = cb20command(v_info,&cmd,&rsp);  /* If status error return qualifier   */  if((rsp.status & 0x7f00) !=0 )    return rsp.rsp0;  /* return error qualifier */  if(!status){    ridlen = VADDR(unsigned short,v_info->ConfigDesc);    *ridlen = (*ridlen > len) ? len : *ridlen;    memcpy((char *)ridp,(char *)v_info->ConfigDesc.VirtualHostAddress,*ridlen);  }  return status;}/* * @writerid * */static  int vwriterid(struct cb20_info *v_info,unsigned short rid,unsigned char *ridp,int len){  Cmd            cmd;  Resp           rsp;  ConfigRid      *cfg;  int            status;  int            irqstate;  u16 *ridlen,rlen;  CARD_RID_DESC *carddesc = (CARD_RID_DESC*)v_info->ConfigDesc.CardRamOff;  memset(&rsp,0,sizeof(rsp));  memset(&cmd,0,sizeof(cmd));  irqstate = cb20in(v_info,V_EVINTEN);  cb20out(v_info,V_EVINTEN,0);  mac_disable(v_info );  /*    * Check for addhoc change in cfg. MIC needs    * to know about it.   */    if(rid == RID_CONFIG){    cfg = (ConfigRid *)ridp;    if((cfg->opmode & 1)==0)      v_info->flags |= ADHOC;    else      v_info->flags &= ~(ADHOC);  }  v_info->ConfigDesc.RIDDesc.valid   = 1;    v_info->ConfigDesc.RIDDesc.length  = len;   v_info->ConfigDesc.RIDDesc.RID     = 0;    cmd.cmd   = CMD_X500_AccessRIDWrite;  cmd.parm0 = rid;  rlen = sizeof(CARD_RID_DESC);  memcpy((char *)v_info->ConfigDesc.CardRamOff,	   (char *)&v_info->ConfigDesc.RIDDesc,sizeof(CARD_RID_DESC));  ridlen = (u16 *)ridp;  if(*ridlen < 4 || *ridlen > 2047 ){    printk(KERN_ERR "RIDLEN in vwrite = %x\n",*ridlen);    return -1;  }  memcpy((char *)v_info->ConfigDesc.VirtualHostAddress,(char *)ridp,*ridlen);  carddesc->valid             = 1;  if(((status = cb20command(v_info,&cmd,&rsp)) & 0xff00) !=0){    printk(KERN_ERR "Write rid Error %d\n",status);    printk(KERN_ERR "Cmd = %x\n",cmd.cmd);  }  mac_enable(v_info,&rsp);  cb20out(v_info,V_EVINTEN,irqstate);  /* If status error return qualifier   */  if((rsp.status & 0x7f00)!=0)    return rsp.rsp0;    return status;}/* In/out  word  * @cb20out */ unsigned short cb20in(struct cb20_info *vp,u16 reg){  unsigned short ret;  ret = inw(vp->iobase+reg);  return ret;}void cb20out(struct cb20_info *vp,u16 reg,u16 val){  outw(val,vp->iobase+reg);}/* @command  */static  u16 cb20command(struct cb20_info *ai, Cmd *pCmd, Resp *pRsp) {  int flags;  int max_tries =600000;  int rc = SUCCESS;  int i,ik=0;  if(ai->flags & NOCARD )    return -NODEV;           /* Ejected */  spin_lock_irqsave(&ai->cmd_lock, flags);  // wait for no busy   for(i=0;i!=600000;i++){    if (cb20in(ai, V_COMMAND) & COMMAND_BUSY) {      mdelay(10);    }   else      break;  }  if(i==600000){#ifdef DEBUG_CMD    printk(KERN_ERR "Was busy too long \n");#endif    rc = ERROR;    goto trynclear;  }  cb20out(ai, V_PARAM0, pCmd->parm0);  cb20out(ai, V_PARAM1, pCmd->parm1);  cb20out(ai, V_PARAM2, pCmd->parm2);  cb20out(ai, V_COMMAND, pCmd->cmd);  /*    * Check for reset command . Takes a while and does    * not return EV_CMD status. Caller must delay ~1s .   * after calling.   */  if(pCmd->cmd == CMD_X500_ResetCard )    goto done;  while ( max_tries-- && (cb20in(ai, V_EVSTAT) & EV_CMD)== 0) {    if ( (ik = cb20in(ai, V_COMMAND)) == pCmd->cmd) {       // didn't notice command, try again      cb20out(ai, V_COMMAND, pCmd->cmd);    }  }   trynclear:  if ( max_tries == -1 ) {    printk( KERN_ERR "CB20: Max tries exceeded when issueing command\n" );    printk( KERN_ERR "CB20: Command was %x\n",pCmd->cmd );        rc = ERROR;#ifdef DEBUG_CMD    printk(KERN_ERR "Hung command reg = %x\n",cb20in(ai,V_COMMAND));#endif    cb20_kick(ai);    if ( !cb20_clear(ai)){#ifdef DEBUG_CMD      printk(KERN_ERR "Command register cleared!\n");#endif      goto done;    }    else{      printk(KERN_ERR "Could not clear command register\n");      goto done;    }  }  // command completed  pRsp->status = cb20in(ai, V_STATUS);  pRsp->rsp0 = cb20in(ai, V_RESP0);  pRsp->rsp1 = cb20in(ai, V_RESP1);  pRsp->rsp2 = cb20in(ai, V_RESP2);    // clear stuck command busy if necessary  if (cb20in(ai, V_COMMAND) & COMMAND_BUSY) {    cb20out(ai, V_EVACK, EV_CLEARCOMMANDBUSY);  }  // acknowledge processing the status/response  cb20out(ai, V_EVACK, EV_CMD); done:  if((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_X500_ResetCard ){    printk(KERN_ERR "cb20command cmd = %x\n",pCmd->cmd);    printk(KERN_ERR "cb20command status = %x\n",pRsp->status);    printk(KERN_ERR "cb20command Rsp0 = %x\n",pRsp->rsp0);    printk(KERN_ERR "cb20command Rsp1 = %x\n",pRsp->rsp1);    printk(KERN_ERR "cb20command Rsp2 = %x\n",pRsp->rsp2);  }  spin_unlock_irqrestore(&ai->cmd_lock, flags);  return rc;}static  void  cb20_kick(struct cb20_info *v_info){#ifdef DEBUG_CMD  printk(KERN_ERR "Cb20 kick!!\n");#endif  cb20out(v_info,V_COMMAND,0x10);  mdelay(20);}/* * Try to clear stuck command busy bit return  * 0 if cleared NZ if not */static  int cb20_clear(struct cb20_info *v_info){  u32 ccmd,maxtries = 10000;  if (cb20in(v_info, V_COMMAND) & COMMAND_BUSY) {    cb20out(v_info, V_EVACK, EV_CMD);  }  else    {#ifdef DEBUG_CMD      printk(KERN_ERR "Busy not set in cb20 clear !!\n");#endif      return 0; /* Busybit not set */    }  while ( maxtries-- &&	((cb20in(v_info, V_EVSTAT)) & EV_CMD)== 0) {    mdelay(10);    if ( (ccmd = cb20in(v_info, V_COMMAND)) & COMMAND_BUSY ) {       cb20out(v_info, V_EVACK, EV_CMD);    }  }  if(maxtries > 0 ){#if DEBUG_CMD    printk(KERN_ERR "Acknowledge command in clear!!\n");#endif    cb20out(v_info, V_EVACK, EV_CMD);    return 0;  }  else    printk(KERN_ERR "Could not clear command busy !\n");  return 1;}/******************************************************************* * @init_cb20_card the descriptors etc start ball rolling.        * ******************************************************************* */static struct net_device *init_cb20_card(struct pci_dev *vencard){  TXFID_HDR txFidHdr = {{0, 0, 0, 0, 0x20, 0, 0, 0}};  struct net_device *vdev;  int      i,status;  struct   cb20_info *v_info;  unsigned char *busaddroff,*vpackoff;  unsigned char *pciaddroff;  Cmd  cmd;  Resp rsp;  if(!vencard){    printk(KERN_ERR "No cb20 found!\n");    return 0;  }      vdev = 0;  vdev = init_etherdev(0,sizeof(struct cb20_info));  if(!vdev){	printk( KERN_INFO "CB20: etherdev alloc FAILED\n");	return 0;

⌨️ 快捷键说明

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