?? usersu.c
字號(hào):
} PRINT("}"); } blocks[blockId] = (void*) db; ritorno = 0; } } db = (struct DoubleBuffT*) blocks[blockId]; if (log) {PRINT("db(%p)",db);} /* However allocate urb separate from data. usb_buffer_alloc seem to be more complicated, * so we use to separe kmalloc() of mdata from data one's.*/ if (ritorno==0) { int size, allp; char *bf; struct urb *urb, *curb;/* dma_addr_t dma;*/ struct urbDataT* places; urb = NULL; bf = NULL; curb = NULL; places = NULL; size = ISOC_BYTESxP; allp = ISOC_NUMBOfP; urb = kzalloc(ISOC_URBSPRE*getUrbSize(allp), KMALLOC_FLAG); ritorno = -ENOMEM; if (urb) { if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)==USB_DIR_IN) places = db->istream.places; else places = db->ostream.places; for (l=0; l<ISOC_URBSPRE; l++) { curb = getUrbAddr(urb,l,allp); usb_init_urb(curb); places[l].urb=curb; } if (log) { PRINT("places=0x%p urb={",places); for (l=0; l<ISOC_URBSPRE; l++) { PRINT("%p ",curb); } PRINT("}"); } bf = kzalloc(ISOC_URBSPRE*size*allp,KMALLOC_FLAG)/*usb_buffer_alloc(dev,ISOC_URBSPRE*size*allp,KMALLOC_FLAG,&dma)*/; if (bf) { for (l=0; l<ISOC_URBSPRE; l++) { curb = getUrbAddr(urb,l,allp); curb->transfer_buffer = bf + getUrbSize(allp)*l;/* curb->transfer_dma = dma; if (dma != (~(dma_addr_t) 0)) curb->transfer_dma += getUrbSize(allp)*l;*/ /* alloc_urb, if !capable for dma transfer, ret dma=-1.*/ } if (log) { PRINT("buff={"); for (l=0; l<ISOC_URBSPRE; l++) { PRINT("%p ",curb->transfer_buffer); } PRINT("}"); } ritorno = 0; } } if (ritorno == 0) { int k; if (log) {PRINT("urb: filling.");} for (l=0; l<ISOC_URBSPRE; l++) { curb = getUrbAddr(urb,l,allp); if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)==USB_DIR_IN) { curb->pipe = usb_rcvisocpipe(dev,endpoint->bEndpointAddress); curb->context=(void*) &(db->istream); } else { curb->pipe = usb_sndisocpipe(dev,endpoint->bEndpointAddress); curb->context=(void*) &(db->ostream); } curb->interval = endpoint->bInterval; curb->transfer_buffer_length=allp*size; curb->number_of_packets=allp; curb->complete=DoubleBuff_complete; curb->dev=dev; curb->transfer_flags=URB_ISO_ASAP; for (k=0; k<allp; k++) { curb->iso_frame_desc[k].offset=k*size; curb->iso_frame_desc[k].length=size; curb->iso_frame_desc[k].actual_length=0; curb->iso_frame_desc[k].status=0; }#if 0 /* * Here we only setup 'static' data for urb. * read()'ll be only actor that'll start urb. */ /* * Start only input urb. If start output, we have error -22 = -EINVAL, * so probe'll stop with error. */ if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)==USB_DIR_IN) { nurb_submitted++; ritorno=usb_submit_urb(curb, GFP_KERNEL); PRINT("submit_urb...%d,",ritorno); }#endif } /* for (l=0, l<3, l++) */ } } return ritorno;}void release_nowork(struct kref *kref) {}static int DoubleBuff_disco(int blockId, struct usb_endpoint_descriptor* endpoint) { int ritorno; stop_submit=1; ritorno = 0; if (ritorno==0) { int size, allp; char *bf; struct urb* urb; struct DoubleBuffT* db; int l; urb = NULL; bf = NULL; db = NULL; size = ISOC_BYTESxP; allp = ISOC_NUMBOfP; db = (struct DoubleBuffT*) blocks[blockId]; if (log) {PRINT("db=blocks[%d]=0x%p",blockId,blocks[blockId]);} if (db) { char buf[300]; struct urbDataT* ud; ud = NULL; if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)==USB_DIR_IN) { ud = &(db->istream.places[0]); buf[0]='i'; } else { ud = &(db->ostream.places[0]); buf[0]='u'; } if (log) { PRINT("CLEAR ALL %s PLACE %p!",buf[0]=='i'?"INPUT":"OUTPUT",ud); dumpUrbD(ud,buf,280); buf[280]='\x0'; PRINT("%s",buf); } urb = ud->urb; ud->urb = NULL; } if (urb) bf = urb->transfer_buffer; if (bf) { if (log) {PRINT("CLEAR BUFF!");} kfree(bf);/* usb_buffer_free(dev, ISOC_URBSPRE*size*allp, bf, urb->transfer_dma);*/ } if (urb) { if (log) {PRINT("CLEAR URB!");} for (l=0; l<ISOC_URBSPRE; l++) kref_put(&(urb[l].kref), release_nowork); kfree(urb); } if (((db->istream.places)[0]).urb == NULL && ((db->ostream.places)[0]).urb == NULL) { if (log) {PRINT("CLEAR MAIN STRUCT!");} kfree(db); usbdo_deleteFile(endpoint->bmAttributes); blocks[blockId] = NULL; } } { int l; for (l=10; l<19; l++) if (blocks[l]) break; if (l==20) { PRINT("set_interface()"); ritorno = usb_set_interface(dev,1,0); } } return ritorno;}#if 0 /* To use with struct.pl.*/struct list_head { struct list_head *next; struct list_head *prev;};struct timer_list { struct list_head list; int expires; int data; void *function;};struct spinlock_t { int lock;};struct dma_addr_t { int dma_addr;};struct iso_packet_descriptor { int offset; int length; int actual_length; int status;};struct urb { spinlock_t lock; void* hcipriv; struct list_head urb_list; struct urb* urb_next; struct usb_device* dev; int pipe; int status; int transfer_flags; void *transfer_buffer; dma_addr_t transfer_dma; int transfer_buffer_length; int actual_length; int bandwidth; char *setup_packet; dma_addr_t setup_dma; int start_frame; int numer_of_packets; int interval; int error_count; int timeout; void* context; void* complete; struct iso_packet_descriptor iso_frame_desc[0];};#endif#if 0struct usu_deviceT { struct urb* intr_urb; struct urb* isoc_urb; struct urb* isoc_usc_urb; struct dataQ_T isoc_usc_dataQ; struct dataQ_T isoc_usc_mdataQ; char isoc_data[3*50000]; struct usb_device *dev; struct timer_list tempo; struct dataQ_T isocQ_ing; struct dataQ_T isocQ_usc; struct dataQ_T bulkQ_ing; struct dataQ_T intrQ_ing; struct semaphore bulkSem; struct semaphore intrSem; struct proc_dir_entry* isobf; struct proc_dir_entry* isocf; struct proc_dir_entry* procf; struct proc_dir_entry* procd;/* struct circBuff intrBuffer;*/ struct endP_T isoc_usc_ep; int intIsStopped; int nOfZero; spinlock_t dataav_lock;} usu_device;#endif/* About 600 char.*/int USBDo_dumpUrb(struct urb *urb,char* buf,int len) { int l=0; Snprintf("urb:%p",urb); if (urb) { Snprintf("dev:%p",urb->dev); Snprintf("pipe:%08X",urb->pipe); Snprintf("stat:%d",urb->status); Snprintf("transf_flag:%08X",urb->transfer_flags); Snprintf("transf_buff:%p",urb->transfer_buffer); Snprintf("transf_dma:%08x",urb->transfer_dma); Snprintf("transf_blen:%d",urb->transfer_buffer_length); Snprintf("actual_len:%d",urb->actual_length); Snprintf("setup_pack:%p",urb->setup_packet); Snprintf("start_fram:%p",(void*)urb->start_frame); Snprintf("numOf_pack:%d",urb->number_of_packets); Snprintf("interval:%d",urb->interval); Snprintf("erro_cnt:%d",urb->error_count); Snprintf("context:%p",urb->context); Snprintf("complete:%p",urb->complete); if (urb->number_of_packets<1000 && urb->number_of_packets>0) { int k,trx_min,trx_max,err_min,err_max; trx_min=trx_max=0; /* !correct but adjusted in a little.*/ err_min=err_max=0; for (k=0;k<urb->number_of_packets;k++) { int act_len=urb->iso_frame_desc[k].actual_length; int err_cur=urb->iso_frame_desc[k].status; if (k) { if (act_len>trx_max) trx_max=act_len; if (act_len<trx_min) trx_min=act_len; if (err_cur>err_max) err_max=err_cur; if (err_cur<err_min) err_min=err_cur; } else {trx_min=act_len;trx_max=act_len; err_min=err_max=err_cur;} } Snprintf("iso:actual_len(min,max)=(%d,%d) status(min,max)=(%d,%d)",trx_min,trx_max,err_min,err_max); } } return l;}/* Send bytes syncronously to usb subsystem. * ogf = {'\1:5'} * ocf = ... * data, len contain remaining bytes, * dest = {'i', 'b'}, mean interrupt, bulk. */int USBDo_send(/*unsigned char ocf, unsigned char ogf, */struct usb_device* dv, char dest, unsigned char* data, int len) { int ritorno=0; int ret_len=0; if (dev) { if (log) PRINT("USBDo_send(dest=%c,len=%d)...",dest,len); if (dest=='i') { ritorno = usb_control_msg(dv, usb_sndctrlpipe(dev, 0), 0,USB_TYPE_CLASS,0,0, data, len, 0/* wait undef, no kill_urb() called. USB_COMMAND_TIMEOUT*/); ret_len=ritorno; } else if (dest=='b') { ritorno=usb_bulk_msg(dv, usb_sndbulkpipe(dev, 2), data, len, &ret_len, 0/*5000*/); } else { PRINT("USBDo_send(): unrecognized dest %x\n",dest); } if (log) PRINT("Ok(ret %d, len %d).", ritorno,ret_len); } else PRINT("Device4USBDo !yet recognized. No send were done.\n"); if (ritorno>=0) ritorno=ret_len; return ritorno;}/* * <0 mean !found, * >=0 mean found, one can use result as index interface[]. */static unsigned int usb_if_to_ifnum(struct usb_interface *intf) { int ritorno=-1; int i; struct usb_device *dev=interface_to_usbdev(intf); for (i=0; (i<dev->actconfig->desc.bNumInterfaces) && (ritorno==-1); i++) { if (dev->actconfig->interface[i]==intf) ritorno=i; } return ritorno;}enum IntfWorkT {PROBE, DISCONNECT}; int USBDo_IntfWork(struct usb_interface *intf, enum IntfWorkT work) { int ritorno,l; char* tmp=NULL; ritorno=0; { /* Just print header.*/ switch (work) { case PROBE: tmp="probe"; break; case DISCONNECT: tmp="disco"; break; default: tmp="unkno"; break; } if (dev==NULL) { dev=usb_get_dev(interface_to_usbdev(intf)); PRINT("\nUSBDo_%s. (%x,%x)", tmp,dev->descriptor.idVendor, dev->descriptor.idProduct); } PRINT("\nUSBDo_%s: (dev=0x%p, interface=%d curAltSet=%d numAltSet=%d)",tmp,dev,usb_if_to_ifnum(intf),intf->cur_altsetting->desc.bAlternateSetting,intf->num_altsetting); } /* 1) For each endpoint provided by device.*/ for (l=0; (l<intf->cur_altsetting->desc.bNumEndpoints) && (ritorno==0) ; l++) { struct usb_endpoint_descriptor *endpoint; endpoint=&(intf->cur_altsetting->endpoint[l].desc); PRINT("\n\t(EndPAddr,bmAttr,ifNum,currAltSet,numAltSet)=(0x%x,%d,%d,%d).", endpoint->bEndpointAddress, endpoint->bmAttributes, usb_if_to_ifnum(intf), intf->num_altsetting); /* 2) Endpoint specific code: start with searching if endpoint will to be managed.*/ { int k; int managed; managed = 0; for (k=0; k<sizeof(topol)/sizeof(struct LinkT); k++) {/* PRINT("Comparing (%x vs %x).",endpoint->bmAttributes,topol[k].blockId[0]);*/ if (topol[k].blockId[0] == endpoint->bEndpointAddress) { int blockId = topol[k].blockId[1]; PRINT("\n\tEndpoint managed."); managed++; /* 3) determine type and create object.*/ switch (work) { case PROBE: if (blockId>=0 && blockId<10) ritorno = BuffRead_probe(blockId,endpoint); if (blockId>=10 && blockId<20) ritorno = DoubleBuff_probe(blockId,endpoint); break; case DISCONNECT: if (blockId>=0 && blockId<10) ritorno = BuffRead_disco(blockId,endpoint); if (blockId>=10 && blockId<20) ritorno = DoubleBuff_disco(blockId,endpoint); break; } PRINT("ret (%d)%s",ritorno,ritorno?"ERR":"Ok"); } /* if (endpoint==managed).*/ } /* for each endpoint_managed.*/ if (!managed) PRINT("\n\tSkipped(!managed)."); } /* Endpoint specific code.*/ } /* for each endpoint exposed by device.*/ PRINT("\n/USBDo_%s=%d",tmp,ritorno); return ritorno;}int USBDo_probe(struct usb_interface *intf, const struct usb_device_id *id_table) { return USBDo_IntfWork(intf, PROBE);}void USBDo_deregister(struct usb_interface *intf) { USBDo_IntfWork(intf, DISCONNECT);}/* Without this kernel never call .probe.*/MODULE_DEVICE_TABLE (usb, idta);static struct usb_driver USBDo = { .owner = THIS_MODULE, .name = "USBDo", .probe = USBDo_probe, .disconnect = USBDo_deregister, /*.driver_list = {0, 0}, * without this module is loaded but !linked with device. */ .id_table = idta,};/* static struct usb_driver USBDo = { "name", &USBDo_probe, &USBDo_disconnect,NULL,NULL,0,NULL,NULL,NULL }; *//* * ========================== * === Module load/unload === * ========================== */int a(void) { int ritorno=-ENOMEM; PRINT("\n === Cerco di inserire USBDo!... === "); ritorno=usb_register(&USBDo); PRINT("%s.",ritorno?"Err!":"Ok"); PRINT("ret (%d)", ritorno); return ritorno;}void b(void) { PRINT("\nDeregistro USBDo!..."); usb_deregister(&USBDo);/* USBDo_deregister(); without interface, we do not know what delete. NULL can be delete all. * Is >simple to remeber all intf during probe. Perhaps usb layer have a list for such object. * * First deregister, then wait urb to complete. If invert operation urb never complete.*/ PRINT("Ok"); { int k;#if 0 int blocksAllocated=0; for (k=0; k<sizeof(blocks)/sizeof(blocks[0]); k++) if (blocks[k]) blocksAllocated++; if (blocksAllocated==0) { PRINT("Removing /proc/USBDo"); remove_proc_entry("USBDo",NULL); usbdo_fs = NULL; }#endif PRINT("Waiting for %d urb to complete...",nurb_submitted); k=100; while (nurb_submitted>0 && k--) mdelay(10); PRINT("Ok"); if (nurb_submitted) PRINT(" %d URB REMAIN SUBMITTED.",nurb_submitted); }}module_init(a);module_exit(b);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -