Hi,

Finally I solved some problems running WiFi on DaVinci. Some tips
could help run other USB devices.
Tips:
1. Add delay 1 ms in probe function before FW loading.
2. Work on full usb speed, not high. You may use USB 1.1 hub or lower
MGC_M_POWER_HSENAB in MGC_O_HDRC_POWER.
3. Pay attention and fix bulk/interrupt URB types.
4. compile kernel with wireless support or configure driver with
configuration file (for example zd1211.conf, essid=....)
6. restart URB on timeout.

Please see attached patch for ZD1211LnxDrv_2_15_0_0 driver. The
patched driver works on FS, and have problems on HS.

--
Constantine Shulyupin
Embedded Linux Consultant
http://linuxdriver.co.il/
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/Makefile ZD1211LnxDrv_2_15_0_0.davinci/Makefile
*** ZD1211LnxDrv_2_15_0_0/Makefile	2006-07-07 10:42:52.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/Makefile	2007-02-07 13:28:15.000000000 +0200
***************
*** 4,17 ****
  #
  #
  
! CC=gcc
! CPP=g++
! LD=ld
  rM=rm -f -r
  
  # if the kernel is 2.6.x, trun on this
  KERN_26=y
! KERNEL_SOURCE=/usr/src/linux-2.6.9
  
  # if the kernel is 2.4.x, trun on this
  #KERN_24=y
--- 4,17 ----
  #
  #
  
! #CC=gcc
! #CPP=g++
! #LD=ld
  rM=rm -f -r
  
  # if the kernel is 2.6.x, trun on this
  KERN_26=y
! #KERNEL_SOURCE=/usr/src/linux-2.6.9
  
  # if the kernel is 2.4.x, trun on this
  #KERN_24=y
*************** DEFINES=-D__KERNEL__ -DMODULE=1
*** 24,30 ****
  KERNRELEASE := $(shell uname -r;)
  MODPATH := /lib/modules/$(KERNRELEASE)
  
! 
  
  ifeq ($(KERN_26), y)
  
--- 24,30 ----
  KERNRELEASE := $(shell uname -r;)
  MODPATH := /lib/modules/$(KERNRELEASE)
  
! ZD1211REV_B=1
  
  ifeq ($(KERN_26), y)
  
*************** ifdef CONFIG_SMP
*** 47,53 ****
  EXTRA_CFLAGS += -D__SMP__ -DSMP
  endif
  
! KDIR := /lib/modules/$(shell uname -r)/build
  PWD := $(shell pwd)
  
  WLAN_SRC=$(PWD)
--- 47,54 ----
  EXTRA_CFLAGS += -D__SMP__ -DSMP
  endif
  
! #KDIR := /lib/modules/$(shell uname -r)/build
! KDIR=$(KERNEL_SOURCE)
  PWD := $(shell pwd)
  
  WLAN_SRC=$(PWD)
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zd1205.c ZD1211LnxDrv_2_15_0_0.davinci/src/zd1205.c
*** ZD1211LnxDrv_2_15_0_0/src/zd1205.c	2006-07-12 15:48:49.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zd1205.c	2007-02-05 15:16:59.000000000 +0200
*************** void zdcb_rx_ind(U8 *pData, U32 length, 
*** 9726,9731 ****
--- 9726,9732 ----
  
              case STA_ASSOCIATED:
              case STA_REASSOCIATED:
+ 		printk("Associated\n");
                  macp->bAssoc = 1;
                  mTmRetryConnect=0;
                  iLED_ON(macp, macp->LinkLEDn);
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zd1211.c ZD1211LnxDrv_2_15_0_0.davinci/src/zd1211.c
*** ZD1211LnxDrv_2_15_0_0/src/zd1211.c	2006-07-11 11:43:55.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zd1211.c	2007-02-05 17:30:37.000000000 +0200
*************** out:
*** 457,462 ****
--- 457,477 ----
  }
  #endif
  
+ static void zd_fill_int_urb(struct zd1205_private *macp);
+ static void zd_fill_int_urb(struct zd1205_private *macp)
+ {
+ #if 1
+ 	usb_fill_int_urb(macp->intr_urb, macp->usb,
+ 		usb_rcvintpipe(macp->usb, EP_INT_IN),
+ 		macp->IntEPBuffer, MAX_EPINT_BUFFER,
+ 		zd1211_intr_cb, macp, macp->in_interval);
+ #else  //fake it
+ 	usb_fill_bulk_urb(macp->intr_urb, macp->usb,
+ 		usb_rcvbulkpipe(macp->usb, EP_INT_IN),
+ 		macp->IntEPBuffer, MAX_EPINT_BUFFER,
+ 		zd1211_intr_cb, macp);
+ #endif
+ }
  
  // return 0: success
  int zd1211_USB_PACKAGE_READ_REGISTER(u16 *Address, u16 *pValue, u16 RegCount, u8 bAddUSBCSRAddress)
*************** int zd1211_USB_PACKAGE_READ_REGISTER(u16
*** 468,474 ****
  	u16 bufSize;
  	int ii;
  	//int memflags = GFP_KERNEL;
! 
  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  	if (in_interrupt()){
  #else
--- 483,489 ----
  	u16 bufSize;
  	int ii;
  	//int memflags = GFP_KERNEL;
! 	//mdelay(100);
  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  	if (in_interrupt()){
  #else
*************** int zd1211_USB_PACKAGE_READ_REGISTER(u16
*** 476,488 ****
  	if (in_atomic()){
  #endif
  		printk(KERN_ERR "********zd1211_USB_PACKAGE_READ_REGISTER in_interrupt*********\n");
! 		return 0;
  	}
  	down(&macp->reg_sem); 
  	
  	if ((RegCount == 0) || (!macp->bUSBDeveiceAttached) || (!test_bit(ZD1211_RUNNING, &macp->flags))){
  		up(&macp->reg_sem);
! 		return 0;
  	}
  
     	pRegBuffer = kmalloc(size, GFP_KERNEL);
--- 491,503 ----
  	if (in_atomic()){
  #endif
  		printk(KERN_ERR "********zd1211_USB_PACKAGE_READ_REGISTER in_interrupt*********\n");
! 		return -1;
  	}
  	down(&macp->reg_sem); 
  	
  	if ((RegCount == 0) || (!macp->bUSBDeveiceAttached) || (!test_bit(ZD1211_RUNNING, &macp->flags))){
  		up(&macp->reg_sem);
! 		return -1;
  	}
  
     	pRegBuffer = kmalloc(size, GFP_KERNEL);
*************** int zd1211_USB_PACKAGE_READ_REGISTER(u16
*** 575,580 ****
--- 590,610 ----
  	if (test_bit(ZD1211_REQ_COMP, &macp->flags))
  		macp->regRspCompCnt++;
  	else{
+ 		{ 
+ 			int res;
+ 			printk("%s: warning, restarting INT EP\n",__FUNCTION__);
+ 			//dump_urb(macp->intr_urb);
+ 			//usb_kill_urb(macp->intr_urb);
+ 			usb_free_urb(macp->intr_urb);
+ 			macp->intr_urb = USB_ALLOC_URB(0, GFP_KERNEL);
+ 			zd_fill_int_urb(macp);
+ 			if ((res = SUBMIT_URB(macp->intr_urb, GFP_KERNEL))){
+ 				printk(KERN_ERR "zd1211: failed intr_urb\n");
+ 				zd1211_DumpErrorCode(macp, res);
+ 				return -1;
+ 			}
+ 			macp->bUSBDeveiceAttached=1;
+ 		}
  		memset(macp->IntEPBuffer, 0x0, MAX_EPINT_BUFFER);
  		macp->regUnCompCnt++;
  		ret = -1;
*************** u32 zd1211_readl(u32 Address, u8 bAddUSB
*** 624,637 ****
  
  	while (bRet != 0){
  		bRet = zd1211_USB_PACKAGE_READ_REGISTER(ReadAddr, ReadData, 2, false);
  		count++;
  		
  		if (count > 5){
  			printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious");
! 			break;
  		}
  	}
!     
  	value = (((u32) ReadData[1]) << 16) + ReadData[0];
  	return value;
  }
--- 654,668 ----
  
  	while (bRet != 0){
  		bRet = zd1211_USB_PACKAGE_READ_REGISTER(ReadAddr, ReadData, 2, false);
+ 		if (!bRet) break; // OK
  		count++;
  		
  		if (count > 5){
  			printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious");
! 			return 0;
  		}
  	}
! 	if (count) printk("%s retry OK\n",__FUNCTION__);
  	value = (((u32) ReadData[1]) << 16) + ReadData[0];
  	return value;
  }
*************** int zd1211_USB_PACKAGE_WRITE_REGISTER(u1
*** 645,650 ****
--- 676,682 ----
  	u16 size = sizeof(USB_WRITE_REG);
  	u16 bufSize;
  	int i;
+ 	//mdelay(100);
  
  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
  	if (in_interrupt()){
*************** u8 zd1211_InitSetup(struct net_device *d
*** 1827,1833 ****
  	macp->in_interval = 10;
  #endif
  
! #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))        
  	usb_fill_int_urb(macp->intr_urb, macp->usb,
  		usb_rcvintpipe(macp->usb, EP_INT_IN),
  		macp->IntEPBuffer, MAX_EPINT_BUFFER,
--- 1859,1865 ----
  	macp->in_interval = 10;
  #endif
  
! /*#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))        
  	usb_fill_int_urb(macp->intr_urb, macp->usb,
  		usb_rcvintpipe(macp->usb, EP_INT_IN),
  		macp->IntEPBuffer, MAX_EPINT_BUFFER,
*************** u8 zd1211_InitSetup(struct net_device *d
*** 1837,1843 ****
  		usb_rcvbulkpipe(macp->usb, EP_INT_IN),
  		macp->IntEPBuffer, MAX_EPINT_BUFFER,
  		zd1211_intr_cb, macp);
! #endif
  
  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))             
  	macp->intr_urb->transfer_flags |= URB_ASYNC_UNLINK;
--- 1869,1876 ----
  		usb_rcvbulkpipe(macp->usb, EP_INT_IN),
  		macp->IntEPBuffer, MAX_EPINT_BUFFER,
  		zd1211_intr_cb, macp);
! #endif*/
! 	zd_fill_int_urb(macp);
  
  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))             
  	macp->intr_urb->transfer_flags |= URB_ASYNC_UNLINK;
*************** void zd1211_intr_cb(struct urb *urb, str
*** 2357,2363 ****
  		zd1211_DumpErrorCode(macp, urb->status);
  
  		if (urb->status == -ENODEV){ //device was removed
! 			FPRINT("Device was removed!!!");
  			macp->bUSBDeveiceAttached = 0;
  
              wake_up(&macp->regSet_wait);
--- 2390,2396 ----
  		zd1211_DumpErrorCode(macp, urb->status);
  
  		if (urb->status == -ENODEV){ //device was removed
! 			printk("Device was removed!!!\n");
  			macp->bUSBDeveiceAttached = 0;
  
              wake_up(&macp->regSet_wait);
*************** void zd1211_intr_cb(struct urb *urb, str
*** 2375,2381 ****
              case -EPROTO:
          #endif
                  macp->bUSBDeveiceAttached = 0;
!                 FPRINT("Device was down!!!");
          #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
                  spin_unlock(&macp->intr_lock);
                  return;
--- 2408,2414 ----
              case -EPROTO:
          #endif
                  macp->bUSBDeveiceAttached = 0;
!                 printk("Device was down!!!");
          #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
                  spin_unlock(&macp->intr_lock);
                  return;
*************** void zd1211_intr_cb(struct urb *urb, str
*** 2464,2473 ****
      //memset(macp->IntEPBuffer, 0x0, MAX_EPINT_BUFFER);
  
      //use bulk instead of interrupt in
!     usb_fill_bulk_urb(macp->intr_urb, macp->usb,
  		  usb_rcvbulkpipe(macp->usb, EP_INT_IN),
  		  macp->IntEPBuffer, MAX_EPINT_BUFFER,
!           zd1211_intr_cb, macp);
  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) 
      macp->intr_urb->transfer_flags |= URB_ASYNC_UNLINK;
  #endif
--- 2497,2507 ----
      //memset(macp->IntEPBuffer, 0x0, MAX_EPINT_BUFFER);
  
      //use bulk instead of interrupt in
!     /*usb_fill_bulk_urb(macp->intr_urb, macp->usb,
  		  usb_rcvbulkpipe(macp->usb, EP_INT_IN),
  		  macp->IntEPBuffer, MAX_EPINT_BUFFER,
!           zd1211_intr_cb, macp); */
!     zd_fill_int_urb(macp);
  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) 
      macp->intr_urb->transfer_flags |= URB_ASYNC_UNLINK;
  #endif
*************** int zd1211_LoadUSBSpecCode(struct zd1205
*** 3106,3113 ****
  	while (uImgLength > 0) {
          int translen = (uImgLength > 4096) ? 4096 : uImgLength;
  
!         ZD1211DEBUG(0, "translen = %x\n", translen);
!         ZD1211DEBUG(0, "uCodeOfst = %x\n", uCodeOfst);
  
                                                                                                                                                                                       
  		result = usb_control_msg(macp->usb, usb_sndctrlpipe(macp->usb, 0),
--- 3140,3147 ----
  	while (uImgLength > 0) {
          int translen = (uImgLength > 4096) ? 4096 : uImgLength;
  
!         ZD1211DEBUG(1, "translen = %x\n", translen);
!         ZD1211DEBUG(1, "uCodeOfst = %x\n", uCodeOfst);
  
                                                                                                                                                                                       
  		result = usb_control_msg(macp->usb, usb_sndctrlpipe(macp->usb, 0),
*************** int zd1211_LoadUSBSpecCode(struct zd1205
*** 3116,3127 ****
  					image, translen, HZ);
  
          ZD1211DEBUG(0, "result = %x\n", result);
!         if(result != translen)
          {
              printk("##### Warning! ####\n");
              printk("usb_control_msg doesn't send all data out\n");
              printk("You need to decrease the message amount in each send\n");
!         }
  
  
  		if (result < 0) {
--- 3150,3161 ----
  					image, translen, HZ);
  
          ZD1211DEBUG(0, "result = %x\n", result);
!         /*if(result != translen)
          {
              printk("##### Warning! ####\n");
              printk("usb_control_msg doesn't send all data out\n");
              printk("You need to decrease the message amount in each send\n");
!         }*/
  
  
  		if (result < 0) {
*************** int zd1211_LoadUSBSpecCode(struct zd1205
*** 3130,3135 ****
--- 3164,3170 ----
  		}
  
  
+ 		translen = result & ~1;
  		uImgLength -= translen;
  		image += translen;
  
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zdhw.c ZD1211LnxDrv_2_15_0_0.davinci/src/zdhw.c
*** ZD1211LnxDrv_2_15_0_0/src/zdhw.c	2006-07-07 10:42:52.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zdhw.c	2007-02-05 15:58:35.000000000 +0200
*************** void HW_SwitchChannel(zd_80211Obj_t *pOb
*** 3243,3249 ****
  	switch(pObj->rfMode)
  	{
  		default:
! 			printk("Invalid RF module parameter:%lu", pObj->rfMode);
  
  			break;
  /*			
--- 3243,3249 ----
  	switch(pObj->rfMode)
  	{
  		default:
! 			printk("Invalid RF module parameter:%lu\n", pObj->rfMode);
  
  			break;
  /*			
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zdsynch.c ZD1211LnxDrv_2_15_0_0.davinci/src/zdsynch.c
*** ZD1211LnxDrv_2_15_0_0/src/zdsynch.c	2006-07-07 10:42:52.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zdsynch.c	2007-02-05 15:18:19.000000000 +0200
*************** BOOLEAN ProbeRsp_Beacon(Signal_t *signal
*** 294,299 ****
--- 294,300 ----
  		if (!getElem(rdu, EID_SSID, &pCurrBssInfo->ssid,1)){
   			goto release;
  		}    
+ 		printk("%s: ssid=%s\n",__FUNCTION__,&(pCurrBssInfo->ssid.buf[2]));
  	
  		if (!getElem(rdu, EID_SUPRATES, &pCurrBssInfo->supRates,1)){
  			goto release;	
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zdusb.c ZD1211LnxDrv_2_15_0_0.davinci/src/zdusb.c
*** ZD1211LnxDrv_2_15_0_0/src/zdusb.c	2006-07-07 10:42:52.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zdusb.c	2007-02-07 13:27:34.000000000 +0200
*************** static int zd1211_probe(struct usb_inter
*** 132,138 ****
  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  	usb_get_dev(dev);
  #endif    
! 
  	vendor_id = zd_le16_to_cpu(dev->descriptor.idVendor);
  	product_id = zd_le16_to_cpu(dev->descriptor.idProduct);
  
--- 132,138 ----
  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  	usb_get_dev(dev);
  #endif    
! 	mdelay(1); // workaround loading FW bug
  	vendor_id = zd_le16_to_cpu(dev->descriptor.idVendor);
  	product_id = zd_le16_to_cpu(dev->descriptor.idProduct);
  
_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to