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