复杂设备Word文档格式.docx

上传人:b****5 文档编号:17206556 上传时间:2022-11-28 格式:DOCX 页数:12 大小:53.62KB
下载 相关 举报
复杂设备Word文档格式.docx_第1页
第1页 / 共12页
复杂设备Word文档格式.docx_第2页
第2页 / 共12页
复杂设备Word文档格式.docx_第3页
第3页 / 共12页
复杂设备Word文档格式.docx_第4页
第4页 / 共12页
复杂设备Word文档格式.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

复杂设备Word文档格式.docx

《复杂设备Word文档格式.docx》由会员分享,可在线阅读,更多相关《复杂设备Word文档格式.docx(12页珍藏版)》请在冰豆网上搜索。

复杂设备Word文档格式.docx

0x100&

&

pos<

PAGE_SIZE/2;

devfn++)

  {

   structpci_dev*dev=NULL;

   dev=pci_find_slot(bus,devfn);

   if(!

dev)

    continue;

   /*Ok,we'

vefoundadevice,copyitscfgspacetothebuffer*/

   for(i=0;

i<

256;

i+=sizeof(u32),pos+=sizeof(u32))pci_read_config_dword(dev,i,(u32*)(buf+pos));

    pci_release_device(dev);

/*2.0compatibility*/

  }

 }

 *eof=1;

 returnpos;

}

  其中使用的pci_find_slot()函数定义为:

structpci_dev*pci_find_slot(unsignedintbus,

unsignedintdevfn)

 structpci_dev*pptr=kmalloc(sizeof(*pptr),GFP_KERNEL);

 intindex=0;

 unsignedshortvendor;

 intret;

pptr)returnNULL;

 pptr->

index=index;

/*0*/

 ret=pcibios_read_config_word(bus,devfn,PCI_VENDOR_ID,&

vendor);

 if(ret/*==PCIBIOS_DEVICE_NOT_FOUNDorwhatevererror*/

||vendor==0xffff||vendor==0x0000){

  kfree(pptr);

returnNULL;

 printk("

ok(%i,%i%x)\n"

bus,devfn,vendor);

 /*fillotherfields*/

bus=bus;

devfn=devfn;

 pcibios_read_config_word(pptr->

bus,pptr->

devfn,PCI_VENDOR_ID,&

pptr->

devfn,PCI_DEVICE_ID,&

device);

 returnpptr;

  (3)根据设备的配置信息申请I/O空间及IRQ资源;

(4)注册设备。

  USB设备的驱动主要处理probe(探测)、disconnect(断开)函数及usb_device_id(设备信息)数据结构,如:

staticstructusb_device_idsample_id_table[]=

  USB_INTERFACE_INFO(3,1,1),driver_info:

(unsignedlong)"

keyboard"

 },

  USB_INTERFACE_INFO(3,1,2),driver_info:

mouse"

 ,

  0,/*nomorematches*/

};

staticstructusb_driversample_usb_driver=

 name:

"

sample"

probe:

sample_probe,disconnect:

sample_disconnect,id_table:

 sample_id_table,

  当一个USB设备从系统拔掉后,设备驱动程序的disconnect函数会自动被调用,在执行了disconnect函数后,所有为USB设备分配的数据结构,内存空间都会被释放:

staticvoidsample_disconnect(structusb_device*udev,void*clientdata)

 /*theclientdataisthesample_devicewepassedoriginally*/

 structsample_device*sample=clientdata;

 /*removetheURB,removetheinputdevice,freememory*/

 usb_unlink_urb(&

sample->

urb);

 kfree(sample);

 printk(KERN_INFO"

sample:

USB%sdisconnected\n"

sample->

name);

 *hereyoumightMOD_DEC_USE_COUNT,butonlyifyouincrement

 *thecountinsample_probe()below

 return;

  当驱动程序向子系统注册后,插入一个新的USB设备后总是要自动进入probe函数。

驱动程序会为这个新加入系统的设备向内部的数据结构建立一个新的实例。

通常情况下,probe函数执行一些功能来检测新加入的USB设备硬件中的生产厂商和产品定义以及设备所属的类或子类定义是否与驱动程序相符,若相符,再比较接口的数目与本驱动程序支持设备的接口数目是否相符。

一般在probe函数中也会解析USB设备的说明,从而确认新加入的USB设备会使用这个驱动程序:

staticvoid*sample_probe(structusb_device*udev,unsignedintifnum,

conststructusb_device_id*id)

 *Theprobeprocedureisprettystandard.Devicematchinghasalready

 *beenperformedbasedontheid_tablestructure(definedlater)

 structusb_interface*iface;

 structusb_interface_descriptor*interface;

 structusb_endpoint_descriptor*endpoint;

 structsample_device*sample;

usbsample:

probecalledfor%sdevice\n"

(char*)id->

driver_info/*"

or"

*/);

 iface=&

udev->

actconfig->

interface[ifnum];

 interface=&

iface->

altsetting[iface->

act_altsetting];

 if(interface->

bNumEndpoints!

=1)returnNULL;

 endpoint=interface->

endpoint+0;

(endpoint->

bEndpointAddress&

0x80))returnNULL;

 if((endpoint->

bmAttributes&

3)!

=3)returnNULL;

 usb_set_protocol(udev,interface->

bInterfaceNumber,0);

 usb_set_idle(udev,interface->

bInterfaceNumber,0,0);

 /*allocateandzeroanewdatastructureforthenewdevice*/

 sample=kmalloc(sizeof(structsample_device),GFP_KERNEL);

sample)returnNULL;

/*failure*/

 memset(sample,0,sizeof(*sample));

 sample->

name=(char*)id->

driver_info;

 /*filltheURBdatastructureusingtheFILL_INT_URBmacro*/

  intpipe=usb_rcvintpipe(udev,endpoint->

bEndpointAddress);

  intmaxp=usb_maxpacket(udev,pipe,usb_pipeout(pipe));

  if(maxp>

8)maxp=8;

sample->

maxp=maxp;

/*rememberforlater*/

  FILL_INT_URB(&

urb,udev,pipe,sample->

data,maxp,

  sample_irq,sample,endpoint->

bInterval);

 /*registertheURBwithintheUSBsubsystem*/

 if(usb_submit_urb(&

urb)){

  kfree(sample);

  returnNULL;

 /*announceyourself*/

probesuccessfulfor%s(maxpis%i)\n"

sample->

name,sample->

maxp);

 *hereyoumightMOD_INC_USE_COUNT;

ifyoudo,you'

llneedtounplug

 *thedeviceorthedevicesbeforebeingabletounloadthemodule

 /*andreturnthenewstructure*/

 returnsample;

  在网络设备驱动的编写中,我们特别关心的就是数据的收、发及中断。

网络设备驱动程序的层次如下:

  网络设备接收到报文后将其传入上层:

/*

*Receiveapacket:

retrieve,encapsulateandpassovertoupperlevels

*/

voidsnull_rx(structnet_device*dev,intlen,unsignedchar*buf)

 structsk_buff*skb;

 structsnull_priv*priv=(structsnull_priv*)dev->

priv;

 *Thepackethasbeenretrievedfromthetransmission

 *medium.Buildanskbaroundit,soupperlayerscanhandleit

 skb=dev_alloc_skb(len+2);

skb){

  printk("

snullrx:

lowonmem-packetdropped\n"

  priv->

stats.rx_dropped++;

  return;

 skb_reserve(skb,2);

/*alignIPon16Bboundary*/

 memcpy(skb_put(skb,len),buf,len);

 /*Writemetadata,andthenpasstothereceivelevel*/

 skb->

dev=dev;

protocol=eth_type_trans(skb,dev);

ip_summed=CHECKSUM_UNNECESSARY;

/*don'

tcheckit*/

 priv->

stats.rx_packets++;

 #ifndefLINUX_20

stats.rx_bytes+=len;

 #endif

 netif_rx(skb);

  在中断到来时接收报文信息:

voidsnull_interrupt(intirq,void*dev_id,structpt_regs*regs)

 intstatusword;

 structsnull_priv*priv;

 *Asusual,checkthe"

device"

pointerforsharedhandlers.

 *Thenassign"

structdevice*dev"

 structnet_device*dev=(structnet_device*)dev_id;

 /*...andcheckwithhwifit'

sreallyours*/

dev/*paranoid*/)return;

 /*Lockthedevice*/

 priv=(structsnull_priv*)dev->

 spin_lock(&

priv->

lock);

 /*retrievestatusword:

realnetdevicesuseI/Oinstructions*/

 statusword=priv->

status;

 if(statusword&

SNULL_RX_INTR){

  /*sendittosnull_rxforhandling*/

  snull_rx(dev,priv->

rx_packetlen,priv->

rx_packetdata);

SNULL_TX_INTR){

  /*atransmissionisover:

freetheskb*/

stats.tx_packets++;

stats.tx_bytes+=priv->

tx_packetlen;

  dev_kfree_skb(priv->

skb);

 /*Unlockthedeviceandwearedone*/

 spin_unlock(&

  而发送报文则分为两个层次,一个层次是内核调用,一个层次完成真正的硬件上的发送:

*Transmitapacket(calledbythekernel)

intsnull_tx(structsk_buff*skb,structnet_device*dev)

 intlen;

 char*data;

 #ifndefLINUX_24

 if(dev->

tbusy||skb==NULL){

  PDEBUG("

tintfor%p,tbusy%ld,skb%p\n"

dev,dev->

tbusy,skb);

  snull_tx_timeout(dev);

  if(skb==NULL)

   return0;

 #endif

 len=skb->

len<

ETH_ZLEN?

ETH_ZLEN:

skb->

len;

 data=skb->

data;

 dev->

trans_start=jiffies;

/*savethetimestamp*/

 /*Remembertheskb,sowecanfreeitatinterrupttime*/

skb=skb;

 /*actualdeliverofdataisdevice-specific,andnotshownhere*/

 snull_hw_tx(data,len,dev);

 return0;

/*Oursimpledevicecannotfail*/

*Transmitapacket(lowlevelinterface)

voidsnull_hw_tx(char*buf,intlen,structnet_device*dev)

 *Thisfunctiondealswithhwdetails.Thisinterfaceloops

 *backthepackettotheothersnullinterface(ifany).

 *Inotherwords,thisfunctionimplementsthesnullbehaviour,

 *whileallotherproceduresareratherdevice-independent

 structiphdr*ih;

 structnet_device*dest;

 u32*saddr,*daddr;

 /*Iamparanoid.Ain'

tI?

*/

 if(len<

sizeof(structethhdr)+sizeof(structiphdr)){

snull:

Hmm...packettooshort(%ioctets)\n"

len);

 if(0){/*enablethisconditionaltolookatthedata*/

  inti;

lenis%i\n"

KERN_DEBUG"

data:

"

  for(i=14;

i<

i++)

   printk("

%02x"

buf[i]&

0xff);

\n"

 *Ethhdris14bytes,butthekernelarrangesforiphdr

 *tobealigned(i.e.,ethhdrisunaligned)

 ih=(structiphdr*)(buf+sizeof(structethhdr));

 saddr=&

ih->

saddr;

 daddr=&

daddr;

 ((u8*)saddr)[2]^=1;

/*changethethirdoctet(classC)*/

 ((u8*)daddr)[2]^=1;

 ih->

check=0;

/*andrebuildthechecksum(ipneedsit)*/

check=ip_fast_csum((unsignedchar*)ih,ih->

ihl);

 if(dev==snull_devs)

  PDEBUGG("

%08x:

%05i-->

%08x:

%05i\n"

ntohl(ih->

saddr),ntohs(((structtcphdr*)(ih+1))->

source),

ntohl(ih->

daddr),ntohs(((structtcphdr*)(ih+1))->

dest));

 else

%05i<

--%08x:

  ntohl(ih->

daddr),ntoh

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 简洁抽象

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1