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

📄 ul_wdbase.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_wdbase.c	- common Windows NT KDM and Win2k WDM driver code  (C) Copyright 1996-2004 by Pavel Pisa - project originator        http://cmp.felk.cvut.cz/~pisa  (C) Copyright 1996-2004 PiKRON Ltd.        http://www.pikron.com  (C) Copyright 2002-2004 Petr Smolik    The uLan driver project can be used and distributed   in compliance with any of next licenses   - GPL - GNU Public License     See file COPYING for details.   - LGPL - Lesser GNU Public License   - MPL - Mozilla Public License   - and other licenses added by project originator  Code can be modified and re-distributed under any combination  of the above listed licenses. If contributor does not agree with  some of the licenses, he/she can delete appropriate line.  WARNING: if you delete all lines, you are not allowed to  distribute code or sources in any form. *******************************************************************/// This variable has to be initialized by RtlConvertLongToLargeInteger(0) in DriverEntryLARGE_INTEGER ULD_LARGE_INTEGER_0;//-------------------------------------------------------------------// Memory check#ifdef ENABLE_UL_MEM_CHECKvoid * ul_mem_check_malloc(size_t size){ void *ptr;  ptr=ExAllocatePool(NonPagedPool,size);  if(ptr) InterlockedIncrement(&ul_mem_check_counter);  return ptr;}void ul_mem_check_free(void *ptr){  if(ptr) InterlockedDecrement(&ul_mem_check_counter);  ExFreePool(ptr);}#endif /* ENABLE_UL_MEM_CHECK *///-------------------------------------------------------------------////  Begin FUNCTIONS//NTSTATUSulan_GetRegistryDword(    IN      PWCHAR    RegPath,    IN      PWCHAR    ValueName,    IN OUT  PULONG    Value    )/*++Routine Description:	Obtain a Dword value from the registryArguments:    RegPath  -- supplies absolute registry path    ValueName    - Supplies the Value Name.    Value      - receives the REG_DWORD value.Return Value:    TRUE if successfull, FALSE on fail.--*/{  UNICODE_STRING path;  RTL_QUERY_REGISTRY_TABLE paramTable[2];  //zero'd second table terminates parms  ULONG lDef = *Value;                     // default  NTSTATUS status;  WCHAR wbuf[ MAXIMUM_FILENAME_LENGTH ];  path.Length = 0;  path.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof( WCHAR );  // MAXIMUM_FILENAME_LENGTH defined in wdm.h  path.Buffer = wbuf;  RtlZeroMemory(path.Buffer, path.MaximumLength);  RtlMoveMemory(path.Buffer, RegPath, wcslen( RegPath) * sizeof( WCHAR ));  RtlZeroMemory(paramTable, sizeof(paramTable));  paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;  paramTable[0].Name = ValueName;  paramTable[0].EntryContext = Value;  paramTable[0].DefaultType = REG_DWORD;  paramTable[0].DefaultData = &lDef;  paramTable[0].DefaultLength = sizeof(ULONG);  status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,                                  path.Buffer, paramTable, NULL, NULL);  return status;}//-------------------------------------------------------------------// ScanForPCICard for WinNT KMD// WDM uses different technique to query VENDOR_ID and DEVICE_ID// for example PCI\VEN_1415&DEV_950A&SUBSYS_00001415&REV_00#ifdef UL_WITH_PCI#ifdef FOR_WIN_WDMBOOLEAN FindPciHWID(PWCHAR HWID,		    OUT pci_device_id_t **Ppci_device_id	           ){  PWCHAR pwcH, pwcM;  WCHAR  fldName;  USHORT vendorID=0;  USHORT deviceID=0;  USHORT subvendorID=0;  USHORT subdeviceID=0;  ULONG  val, i, c;  static WCHAR PciHWIDMask[]=L"PCI\\VEN_vvvv&DEV_xxxx&SUBSYS_sssswwww";  pci_device_id_t *device_id;  *Ppci_device_id=NULL;  if(HWID==NULL) return FALSE;  pwcH=HWID;  pwcM=PciHWIDMask;  while(*pwcH&&*pwcM) {    if(*pwcH==*pwcM){      pwcH++; pwcM++;      continue;    }    fldName=*pwcM;    if((fldName!='v')&&(fldName!='x')&&       (fldName!='s')&&(fldName!='w')) break;    val=0;    for(i=4;i--;){      c=*(pwcH++); pwcM++;      if(c<='9') c-='0';      else if(c<='F') c=c-'A'+10;      else if(c<='f') c=c-'a'+10;      if(c>15) {val=0;break;}      val<<=4;      val+=c;    }    switch (fldName) {      case 'v':        vendorID=(USHORT)val;	break;      case 'x':        deviceID=(USHORT)val;	break;      case 'w':        subvendorID=(USHORT)val;	break;      case 's':        subdeviceID=(USHORT)val;	break;    }  }#if DBG  uLan_DbgPrint("uLan: PCI - Ven %04X Dev %04X SubVen %04X SubDev %04X\n",                  vendorID,deviceID,subvendorID,subdeviceID);#endif  for(device_id=ulan_pci_tbl;device_id->vendor;device_id++){    if((device_id->vendor!=PCI_ANY_ID)&&(device_id->vendor!=vendorID)) continue;    if((device_id->device!=PCI_ANY_ID)&&(device_id->device!=deviceID)) continue;    if((device_id->subvendor!=PCI_ANY_ID)&&(device_id->vendor!=subvendorID)) continue;    if((device_id->subdevice!=PCI_ANY_ID)&&(device_id->device!=subdeviceID)) continue;    *Ppci_device_id=device_id;    return TRUE;  }  return FALSE;}#else /* !FOR_WIN_WDM */BOOLEAN ScanForPCICard(IN OUT PULONG PBusNumber,                       IN OUT PPCI_SLOT_NUMBER PSlotNumber,                       IN BOOLEAN FindFirst,		       OUT pci_device_id_t **Ppci_device_id		      ){  ULONG BusNumber=*PBusNumber;  PCI_SLOT_NUMBER SlotNumber=*PSlotNumber;  UCHAR Buffer[2*sizeof(USHORT)];  ULONG Readed=sizeof(Buffer);  pci_device_id_t *device_id;  while(1){    if(FindFirst){      BusNumber=0;      SlotNumber.u.AsULONG=0;      FindFirst=0;    }else{      if(Readed>2){        SlotNumber.u.bits.FunctionNumber=            (SlotNumber.u.bits.FunctionNumber+1)&7;      }else{        SlotNumber.u.bits.FunctionNumber=0;      }      if(!SlotNumber.u.bits.FunctionNumber){        if(!Readed&&!SlotNumber.u.bits.DeviceNumber)            break;        SlotNumber.u.bits.DeviceNumber=            (SlotNumber.u.bits.DeviceNumber+1)&0x1f;        if(!SlotNumber.u.bits.DeviceNumber)            BusNumber++;      }    }    Readed=HalGetBusData(PCIConfiguration,BusNumber,SlotNumber.u.AsULONG,                         Buffer,sizeof(Buffer));    if(Readed==sizeof(Buffer)){      for(device_id=&ulan_pci_tbl[0];device_id->vendor;device_id++){        if((((PPCI_COMMON_CONFIG)Buffer)->VendorID==device_id->vendor)&&           (((PPCI_COMMON_CONFIG)Buffer)->DeviceID==device_id->device)){            *PBusNumber=BusNumber;            *PSlotNumber=SlotNumber;            if(Ppci_device_id)                *Ppci_device_id=device_id;            return TRUE;        }      }    }  }  return FALSE;}                    #endif /* FOR_WIN_WDM */#endif /*UL_WITH_PCI*///-------------------------------------------------------------------// WDM uses different technique to query VENDOR_ID and DEVICE_ID// for example USB\Vid_dead&Pid_1001&REV_0001#ifdef UL_WITH_USBBOOLEAN FindUsbHWID(PWCHAR HWID,		    OUT usb_device_id_t **Pusb_device_id	           ){  PWCHAR pwcH, pwcM;  WCHAR  fldName;  USHORT vendorID=0;  USHORT productID=0;  ULONG  val, i, c;  static WCHAR UsbHWIDMask[]=L"USB\\Vid_vvvv&Pid_pppp";  usb_device_id_t *device_id;  *Pusb_device_id=NULL;  if(HWID==NULL) return FALSE;  pwcH=HWID;  pwcM=UsbHWIDMask;  while(*pwcH&&*pwcM) {    if(*pwcH==*pwcM){      pwcH++; pwcM++;      continue;    }    fldName=*pwcM;    if((fldName!='v')&&(fldName!='p')) break;    val=0;    for(i=4;i--;){      c=*(pwcH++); pwcM++;      if(c<='9') c-='0';      else if(c<='F') c=c-'A'+10;      else if(c<='f') c=c-'a'+10;      if(c>15) {val=0;break;}      val<<=4;      val+=c;    }    switch (fldName) {      case 'v':        vendorID=(USHORT)val;	break;      case 'p':        productID=(USHORT)val;	break;    }  }#if DBG  uLan_DbgPrint("uLan: USB - Ven %04X Dev %04X\n",                  vendorID,productID);#endif  for(device_id=ulan_usb_tbl;device_id->idVendor;device_id++){    if((device_id->idVendor!=vendorID)) continue;    if((device_id->idProduct!=productID)) continue;    *Pusb_device_id=device_id;    return TRUE;  }  return FALSE;}#endif /* UL_WITH_USB *///-------------------------------------------------------------------////  Initialize and free driver///* initialize new driver from given parameters */NTSTATUS ul_drv_init_ext(ul_drv *udrv, int port,	 int irq, int baud, long baudbase, int chip_options, int buffer_size, int my_adr){  int ret;  int test_cnt;  unsigned long probe_irqs;  udrv->flag_IN_ISR=0;  udrv->flag_ASK_ISR=0;  udrv->flag_NACTIV=0;  udrv->flag_CHIPOK=0;  udrv->flag_IN_BOTTOM=0;  udrv->flag_ASK_BOTTOM=0;  udrv->flag_CHECK_FILT=0;  udrv->flag_KWTKILL=0;  if(buffer_size<0x2000) buffer_size=0x2000;  /* init sequencer */  ul_drv_new_init_state(udrv,my_adr);  /* init chip driver */  #ifdef UL_WITH_USB  if((chip_options&~0xff)==UL_USB_HW_PS1){    if((ret=ul_usb_ps1_init(udrv, port, irq, baud, baudbase, chip_options))>=0){      UL_PRINTF("uLan ul_drv_new : usb_ps1\n");    }  } else {  #else  {  #endif /* UL_WITH_USB */  #ifdef UL_WITH_PCI    if((chip_options&~0xff)==0x16954000){      if((ret=u950pci_init(udrv, port, irq, baud, baudbase, chip_options))>=0){        UL_PRINTF("uLan ul_drv_new : 16C954 at 0x%x\n",port);      }    }else  #endif /* UL_WITH_PCI */    {      if((ret=u510_init(udrv, port, irq, baud, baudbase, chip_options))>=0){        UL_PRINTF("uLan ul_drv_new : 82510 found at 0x%x\n",port);      }else if((ret=u450_init(udrv, port, irq, baud, baudbase, chip_options))>=0){        UL_PRINTF("uLan ul_drv_new : 16450 found at 0x%x\n",port);      };    }  }  if(ret>=0)  { /* setups buffers, ports and first part of irq      for sucesfully detected device */    if(ul_drv_new_start(udrv,buffer_size)>=0)      return STATUS_SUCCESS;  }  UL_PRINTF("uLan ul_drv_new : failed to init\n");  return STATUS_INSUFFICIENT_RESOURCES;};/* destroy driver */void ul_drv_done_ext(ul_drv *udrv){  int old_CHIPOK;  if(!udrv) return;  old_CHIPOK=udrv->flag_CHIPOK;  udrv->flag_CHIPOK=0;  if(old_CHIPOK&&udrv->irq){    /* free_irq(udrv->irq,udrv)*/;    /* synchronize_irq(); */  }  DONE_UDRV_WDTIM(udrv);  /* schedule(); */  ul_mem_done(udrv);  if(old_CHIPOK) {     udrv->fnc_cctrl(udrv,UL_CC_PDONE,0);  };};//-------------------------------------------------------------------////  File operations//NTSTATUS ul_drv_open(ul_drv *udrv,ul_opdata *opdata){   opdata->magic=ULOP_MAGIC;  opdata->message=NULL;  opdata->udrv=udrv;  /* init_waitqueue_head(&opdata->wqrec); */  opdata->opprew=NULL;  opdata->opnext=NULL;  opdata->recchain=NULL;  opdata->filtchain=NULL;  opdata->wait_irp=NULL;  { /* add us onto list of clients of udrv */    ul_opdata *opptr;    UL_DRV_LOCK_FINI    UL_DRV_LOCK;    opptr=udrv->operators;    if(opptr) {opptr->opprew=opdata;opdata->opnext=opptr;};    UL_MB();    udrv->operators=opdata;    UL_DRV_UNLOCK;  };  return 0;}NTSTATUS ul_drv_close(ul_drv *udrv,ul_opdata *opdata){  ul_opchain *opmember;  KIRQL OldIrql;  if (opdata->message) ulan_freemsg(opdata);  KeRaiseIrql(DISPATCH_LEVEL,&OldIrql);  {while(InterlockedExchange(&udrv->flag_IN_BOTTOM,1))/* spinlock loop*/;}  {     /* delete us from list of clients of udrv */    ul_drv *udrv=opdata->udrv;    ul_opdata *opptr;    UL_DRV_LOCK_FINI    UL_DRV_LOCK;    if((opptr=opdata->opnext)) opptr->opprew=opdata->opprew;    if((opptr=opdata->opprew)) opptr->opnext=opdata->opnext;    else udrv->operators=opdata->opnext;    UL_DRV_UNLOCK;  };  InterlockedExchange(&udrv->flag_IN_BOTTOM,0);  ulan_bottom_dpc(NULL,udrv,NULL,NULL);  KeLowerIrql(OldIrql);  while((opmember=opdata->recchain))  {    del_from_opchain(&opdata->recchain,opmember);    if(opmember->message) ul_dec_ref_cnt(opmember->message);    FREE(opmember);  };  while((opmember=opdata->filtchain))  {    del_from_opchain(&opdata->filtchain,opmember);    FREE(opmember);  };  return 0;};NTSTATUS ulan_read(ul_drv *udrv,ul_opdata *opdata,				   uchar *buf, ULONG count,				   LARGE_INTEGER pos, PULONG pcount){  int cn;  int len;  if(!opdata->message) return -ENOMSG;  if(opdata->data.pos+count>UL_BLK_HEAD(opdata->data.head_blk).len)    count=UL_BLK_HEAD(opdata->data.head_blk).len-opdata->data.pos;  cn=count;  while(cn>0)  {    if(!ul_di_adjust(&opdata->data))    {      RtlZeroMemory(buf,cn);      cn=0;      break;    };    len=ul_di_atonce(&opdata->data);    if(len>cn) len=cn;    RtlCopyMemory(buf,ul_di_byte(&opdata->data),len);    ul_di_add(&opdata->data,len);    buf+=len;    cn-=len;  };  *pcount=count-cn;  return 0;};NTSTATUS ulan_write(ul_drv *udrv,ul_opdata *opdata,				   const uchar *buf, ULONG count,				   LARGE_INTEGER pos, PULONG pcount){  int cn;  int len;  ul_mem_blk *blk;  if(!opdata->message) return -ENOMSG;

⌨️ 快捷键说明

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