1. diff --git a/firmware/export/config/rk27generic.h b/firmware/export/config/rk27generic.h
  2. index 69c3330..cb0e825 100644
  3. --- a/firmware/export/config/rk27generic.h
  4. +++ b/firmware/export/config/rk27generic.h
  5. @@ -54,7 +54,7 @@
  6.  /* define this if you have a flash memory storage */
  7.  #define HAVE_FLASH_STORAGE
  8.  
  9. -#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
  10. +#define CONFIG_STORAGE (STORAGE_SD /*| STORAGE_NAND*/)
  11.  
  12.  #define CONFIG_NAND NAND_RK27XX
  13.  #define HAVE_SW_TONE_CONTROLS
  14. diff --git a/firmware/export/logf.h b/firmware/export/logf.h
  15. index b57ae91..48cfae8 100644
  16. --- a/firmware/export/logf.h
  17. +++ b/firmware/export/logf.h
  18. @@ -29,7 +29,7 @@
  19.  
  20.  #ifndef __PCTOOL__
  21.  
  22. -#define MAX_LOGF_SIZE 16384
  23. +#define MAX_LOGF_SIZE 163840
  24.  
  25.  extern unsigned char logfbuffer[MAX_LOGF_SIZE];
  26.  extern int logfindex;
  27. diff --git a/firmware/export/rk27xx.h b/firmware/export/rk27xx.h
  28. index 3ca2bc0..0a56536 100644
  29. --- a/firmware/export/rk27xx.h
  30. +++ b/firmware/export/rk27xx.h
  31. @@ -8,7 +8,8 @@
  32.  #define FLASH_BANK1 0x11000000
  33.  
  34.  #define USB_NUM_ENDPOINTS 16
  35. -#define USB_DEVBSS_ATTR
  36. +/* cache aligned */
  37. +#define USB_DEVBSS_ATTR        __attribute__((aligned(32)))
  38.  
  39.  /* Timers */
  40.  #define APB0_TIMER             (ARM_BUS0_BASE + 0x00000000)
  41. @@ -731,6 +732,7 @@
  42.  #define RXVOIDINTEN            (1<<5)
  43.  #define RXERRINTEN             (1<<6)
  44.  #define RXACKINTEN             (1<<7)
  45. +#define RXCFINTE               (1<<12)
  46.  /* bits 31:8 reserved for EP0 */
  47.  /* bits 31:14 reserved for others */
  48.  
  49. @@ -753,6 +755,7 @@
  50.  #define TXERRINTEN             (1<<5)
  51.  #define TXACKINTEN             (1<<6)
  52.  #define TXDMADNEN              (1<<7) /* reserved for EP0 */
  53. +#define TXCFINTE               (1<<12)
  54.  /* bits 31:8 reserved */
  55.  
  56.  /* TXnBUF bits */
  57. diff --git a/firmware/target/arm/rk27xx/usb-drv-rk27xx.c b/firmware/target/arm/rk27xx/usb-drv-rk27xx.c
  58. index 810c793..7058612 100644
  59. --- a/firmware/target/arm/rk27xx/usb-drv-rk27xx.c
  60. +++ b/firmware/target/arm/rk27xx/usb-drv-rk27xx.c
  61. @@ -170,48 +170,112 @@ static void ctr_read(void)
  62.      RX0DMACTLO = DMA_START;                          /* start DMA */
  63.  }
  64.  
  65. -static void blk_write(int ep)
  66. +static void blk_write(int ep_num)
  67.  {
  68. -    int ep_num = EP_NUM(ep);
  69. -    int max = usb_drv_port_speed() ? 512 : 64;
  70. -    int xfer_size = (endpoints[ep_num].cnt > max) ? max : endpoints[ep_num].cnt;  
  71.      unsigned int timeout = current_tick + HZ/10;
  72. -    
  73. +    int max = usb_drv_port_speed() ? 512 : 64;
  74. +    int xfer_size = (endpoints[ep_num].cnt > max) ? max : endpoints[ep_num].cnt;
  75. +
  76.      while (BIN_TXBUF(ep_num) & TXFULL) /* TXFULL flag */
  77.      {
  78.          if(TIME_AFTER(current_tick, timeout))
  79.              break;
  80.      }
  81. -    
  82. +
  83.      BIN_TXSTAT(ep_num) = xfer_size;                            /* size */
  84.      BIN_DMAINLMADDR(ep_num) = (uint32_t)endpoints[ep_num].buf; /* buf address */
  85.      BIN_DMAINCTL(ep_num) = DMA_START;                          /* start DMA */
  86.      BIN_TXCON(ep_num) &= ~TXNAK;                               /* clear NAK */
  87. -    
  88. +
  89.      /* Decrement by max packet size is intentional.
  90. -     * This way if we have final packet short one we will get negative len
  91. -     * after transfer, which in turn indicates we *don't* need to send
  92. -     * zero length packet. If the final packet is max sized packet we will
  93. -     * get zero len after transfer which indicates we need to send
  94. -     * zero length packet to signal host end of the transfer.
  95. -     */
  96. +    * This way if we have final packet short one we will get negative len
  97. +    * after transfer, which in turn indicates we *don't* need to send
  98. +    * zero length packet. If the final packet is max sized packet we will
  99. +    * get zero len after transfer which indicates we need to send
  100. +    * zero length packet to signal host end of the transfer.
  101. +    */
  102.      endpoints[ep_num].cnt -= max;
  103.      endpoints[ep_num].buf += xfer_size;
  104.  }
  105.  
  106. -static void blk_read(int ep)
  107. +static void blk_write_int(int ep_num)
  108.  {
  109. -    int ep_num = EP_NUM(ep);
  110. -    int xfer_size = BOUT_RXSTAT(ep_num) & 0xffff;
  111. -    
  112. -    /* clear NAK bit */
  113. -    BOUT_RXCON(ep_num) &= ~RXNAK;
  114. -
  115. -    endpoints[ep_num].cnt -= xfer_size;
  116. -    endpoints[ep_num].buf += xfer_size;
  117. -  
  118. -    BOUT_DMAOUTLMADDR(ep_num) = (uint32_t)endpoints[ep_num].buf;
  119. -    BOUT_DMAOUTCTL(ep_num) = DMA_START;
  120. +    uint32_t txstat = BIN_TXSTAT(ep_num);
  121. +    struct endpoint_t *endp = &endpoints[ep_num];
  122. +
  123. +    if(txstat & TXCFINT)
  124. +    {
  125. +        logf("blk_write:cf(0x%x), %ld", ep_num, current_tick);
  126. +        /* bit cleared by read */
  127. +        usb_drv_stall(ep_num, false, true);
  128. +    }
  129. +
  130. +    if (txstat & TXACK) /* check TxACK flag */
  131. +    {
  132. +        if (endp->cnt > 0)
  133. +        {
  134. +            logf("blk_write:ack(0x%x), %ld", ep_num, current_tick);
  135. +            /* we still have data to send (or ZLP) */
  136. +            blk_write(ep_num);
  137. +        }
  138. +        else
  139. +        {
  140. +            logf("udc_intr: usb_core_transfer_complete(0x%x, USB_DIR_IN, 0, 0x%x), %ld", ep_num, endp->len, current_tick);
  141. +            /* final ack received */
  142. +            usb_core_transfer_complete(ep_num,     /* ep */
  143. +                                        USB_DIR_IN, /* dir */
  144. +                                        0,          /* status */
  145. +                                        endp->len);  /* length */
  146. +
  147. +            /* release semaphore for blocking transfer */
  148. +            if (endp->block)
  149. +            {
  150. +                logf("udc_intr: ep=0x%x, semaphore_release(), %ld", ep_num, current_tick);
  151. +                semaphore_release(&endp->complete);
  152. +            }
  153. +        }
  154. +    }
  155. +}
  156. +
  157. +static void blk_read_int(int ep_num)
  158. +{
  159. +    uint32_t rxstat = BOUT_RXSTAT(ep_num);
  160. +    int xfer_size = rxstat & 0xffff;
  161. +    int max = usb_drv_port_speed() ? 512 : 64;
  162. +    struct endpoint_t *endp = &endpoints[ep_num];
  163. +
  164. +    if(rxstat & RXCFINT)
  165. +    {
  166. +        logf("blk_read:cf(0x%x), %ld", ep_num, current_tick);
  167. +        /* bit cleared by read */
  168. +        usb_drv_stall(ep_num, false, false);
  169. +    }
  170. +
  171. +    if((rxstat & RXACK) && endp->cnt > 0)
  172. +    {
  173. +        logf("blk_read:ack(0x%x,0x%x), %ld", ep_num, xfer_size, current_tick);
  174. +        /* clear NAK bit */
  175. +        BOUT_RXCON(ep_num) &= ~RXNAK;
  176. +
  177. +        endp->cnt -= xfer_size;
  178. +        endp->buf += xfer_size;
  179. +
  180. +        /* if the transfer was short or if the total count is zero, transfer is complete */
  181. +        if (endp->cnt == 0 || xfer_size < max)
  182. +        {
  183. +            logf("udc_intr: usb_core_transfer_complete(0x%x, USB_DIR_OUT, 0, 0x%x), %ld", ep_num, endp->len, current_tick);
  184. +            usb_core_transfer_complete(ep_num,      /* ep */
  185. +                                        USB_DIR_OUT, /* dir */
  186. +                                        0,           /* status */
  187. +                                        endp->len - endp->cnt);    /* length */
  188. +            endp->cnt = 0;
  189. +        }
  190. +        else
  191. +        {
  192. +            BOUT_DMAOUTLMADDR(ep_num) = (uint32_t)endp->buf;
  193. +            BOUT_DMAOUTCTL(ep_num) = DMA_START;
  194. +        }
  195. +    }
  196.  }
  197.  
  198.  static void int_write(int ep)
  199. @@ -387,17 +451,20 @@ void INT_UDC(void)
  200.  
  201.      if (intsrc & CONN_INTR) /* usb connect */
  202.      {
  203. -//        if (DEV_INFO & VBUS_STS)
  204. -//        {
  205. +        if (DEV_INFO & VBUS_STS)
  206. +        {
  207.              udc_phy_reset();
  208.              udelay(10000);
  209.              udc_soft_connect();
  210.              udc_conn = 1;
  211.              usb_status_event(USB_INSERTED);
  212.  
  213. -//        }
  214. -//        else
  215. -//            udc_conn = 0;
  216. +        }
  217. +        else
  218. +        {
  219. +            udc_conn = 0;
  220. +            usb_status_event(USB_EXTRACTED);
  221. +        }
  222.      }
  223.  
  224.      /* TODO this needs rework */
  225. @@ -414,60 +481,10 @@ void INT_UDC(void)
  226.                  {
  227.                      case USB_ENDPOINT_XFER_BULK:
  228.                          if (ep->dir == DIR_OUT)
  229. -                        {
  230.                              /* bulk out */
  231. -                            rxstat = BOUT_RXSTAT(ep_num);
  232. -            
  233. -                            /* TODO handle errors */
  234. -                            if (rxstat & RXACK) /* RxACK */
  235. -                            {
  236. -                                if (ep->cnt > 0)
  237. -                                {
  238. -                                    logf("udc_intr: blk_read(0x%x), %ld", ep_num, current_tick);
  239. -                                    blk_read(ep_num);
  240. -                                }
  241. -                                else
  242. -                                {
  243. -                                    logf("udc_intr: usb_core_transfer_complete(0x%x, USB_DIR_OUT, 0, 0x%x), %ld", ep_num, ep->len, current_tick);
  244. -                                    usb_core_transfer_complete(ep_num,      /* ep */
  245. -                                                               USB_DIR_OUT, /* dir */
  246. -                                                               0,           /* status */
  247. -                                                               ep->len);    /* length */
  248. -                                }
  249. -                            }
  250. -                        }
  251. +                            blk_read_int(ep_num);
  252.                          else
  253. -                        {
  254. -                            /* bulk in */
  255. -                            txstat = BIN_TXSTAT(ep_num);
  256. -            
  257. -                            /* TODO handle errors */
  258. -                            if (txstat & TXACK) /* check TxACK flag */
  259. -                            {
  260. -                                if (ep->cnt >= 0)
  261. -                                {
  262. -                                    logf("udc_intr: blk_write(0x%x), %ld", ep_num, current_tick);
  263. -                                    /* we still have data to send (or ZLP) */
  264. -                                    blk_write(ep_num);
  265. -                                }
  266. -                                else
  267. -                                {
  268. -                                    logf("udc_intr: usb_core_transfer_complete(0x%x, USB_DIR_IN, 0, 0x%x), %ld", ep_num, ep->len, current_tick);
  269. -                                    /* final ack received */
  270. -                                    usb_core_transfer_complete(ep_num,     /* ep */
  271. -                                                               USB_DIR_IN, /* dir */
  272. -                                                               0,          /* status */
  273. -                                                               ep->len);  /* length */
  274. -                
  275. -                                    /* release semaphore for blocking transfer */
  276. -                                    if (ep->block)
  277. -                                    {
  278. -                                        logf("udc_intr: ep=0x%x, semaphore_release(), %ld", ep_num, current_tick);
  279. -                                        semaphore_release(&ep->complete);
  280. -                                    }
  281. -                                }
  282. -                            }
  283. -                        }
  284. +                            blk_write_int(ep_num);
  285.                          break;
  286.  
  287.                      case USB_ENDPOINT_XFER_INT:
  288. @@ -534,15 +551,15 @@ int usb_drv_request_endpoint(int type, int dir)
  289.  
  290.              if (ep_num%3 == 0) /* IIN 3, 6, 9, 12, 15 */
  291.              {
  292. -                IIN_TXCON(ep_num) = (ep_num<<8)|TXEPEN|TXNAK; /* ep_num, enable, NAK */
  293. +                IIN_TXCON(ep_num) = (ep_num<<8)|TXEPEN|TXNAK|TXACKINTEN|TXCFINTE;
  294.              }
  295.              else if (ep_num%3 == 1) /* BOUT 1, 4, 7, 10, 13 */
  296.              {
  297. -                BOUT_RXCON(ep_num) = (ep_num<<8)|RXEPEN|RXNAK; /* ep_num, NAK, enable */
  298. +                BOUT_RXCON(ep_num) = (ep_num<<8)|RXEPEN|RXNAK|RXACKINTEN|RXCFINTE;
  299.              }
  300.              else if (ep_num%3 == 2) /* BIN 2, 5, 8, 11, 14 */
  301.              {
  302. -                BIN_TXCON(ep_num) = (ep_num<<8)|TXEPEN|TXNAK; /* ep_num, enable, NAK */
  303. +                BIN_TXCON(ep_num) = (ep_num<<8)|TXEPEN|TXNAK|TXACKINTEN|TXCFINTE;
  304.              }
  305.  
  306.              /* enable interrupt from this endpoint */
  307. @@ -586,6 +603,12 @@ static int _usb_drv_send(int endpoint, void *ptr, int length, bool block)
  308.      struct endpoint_t *ep;
  309.      int ep_num = EP_NUM(endpoint);
  310.  
  311. +    /* for send transfers, make sure the data is committed
  312. +     * for recv, I don't know how to simply discard the cache so commit and
  313. +     * pray that no-one will read it in between */
  314. +    //commit_discard_dcache_range(ptr, length);
  315. +    commit_discard_idcache();
  316. +
  317.      logf("_usb_drv_send: endpt=0x%x, len=0x%x, block=%d", endpoint, length, block);    
  318.      if (ep_num == 0)
  319.          ep = &ctrlep[DIR_IN];
  320. @@ -602,7 +625,7 @@ static int _usb_drv_send(int endpoint, void *ptr, int length, bool block)
  321.      
  322.      switch (ep->type)
  323.      {
  324. -        case USB_ENDPOINT_XFER_CONTROL:                    
  325. +        case USB_ENDPOINT_XFER_CONTROL:
  326.              ctr_write();
  327.              break;
  328.          
  329. @@ -724,6 +747,7 @@ bool usb_drv_stalled(int endpoint, bool in)
  330.  void usb_drv_stall(int endpoint, bool stall, bool in)
  331.  {
  332.      int ep_num = EP_NUM(endpoint);
  333. +    logf("usb_drv: %sstall EP%d %s", stall ? "": "un", ep_num, in ? "IN" : "OUT");
  334.  
  335.      switch (endpoints[ep_num].type)
  336.      {
  337. diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
  338. index 8dc5969..0703036 100644
  339. --- a/firmware/usbstack/usb_core.c
  340. +++ b/firmware/usbstack/usb_core.c
  341. @@ -686,6 +686,16 @@ static void usb_core_do_set_config(uint8_t config)
  342.      #endif
  343.  }
  344.  
  345. +static void usb_core_do_clear_feature(int recip, int recip_nr, int feature)
  346. +{
  347. +    logf("usb_core: CLEAR FEATURE (%d,%d,%d)", recip, recip_nr, feature);
  348. +    if(recip == USB_RECIP_ENDPOINT)
  349. +    {
  350. +        if(feature == USB_ENDPOINT_HALT)
  351. +            usb_drv_stall(EP_NUM(recip_nr), false, EP_DIR(recip_nr));
  352. +    }
  353. +}
  354. +
  355.  static void request_handler_device(struct usb_ctrlrequest* req)
  356.  {
  357.      switch(req->bRequest) {
  358. @@ -808,12 +818,11 @@ static void request_handler_endpoint_standard(struct usb_ctrlrequest* req)
  359.  {
  360.      switch (req->bRequest) {
  361.          case USB_REQ_CLEAR_FEATURE:
  362. -            if(req->wValue == USB_ENDPOINT_HALT)
  363. -                usb_drv_stall(EP_NUM(req->wIndex), false, EP_DIR(req->wIndex));
  364. -            
  365. +            usb_core_do_clear_feature(USB_RECIP_ENDPOINT, req->wIndex, req->wValue);
  366.              usb_drv_send(EP_CONTROL, NULL, 0);
  367.              break;
  368.          case USB_REQ_SET_FEATURE:
  369. +            logf("usb_core: SET FEATURE (%d)", req->wValue);
  370.              if(req->wValue == USB_ENDPOINT_HALT)
  371.                 usb_drv_stall(EP_NUM(req->wIndex), true, EP_DIR(req->wIndex));
  372.              
  373. diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
  374. index dbcf4a2..d2b2a5e 100644
  375. --- a/firmware/usbstack/usb_storage.c
  376. +++ b/firmware/usbstack/usb_storage.c
  377. @@ -753,6 +753,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
  378.      unsigned int block_size_mult = 1;
  379.  
  380.      if(letoh32(cbw->signature) != CBW_SIGNATURE) {
  381. +        logf("ums: bad cbw signature (%x)", cbw->signature);
  382.          usb_drv_stall(ep_in, true,true);
  383.          usb_drv_stall(ep_out, true,false);
  384.          return;
  385. @@ -1151,6 +1152,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
  386.  
  387.          default:
  388.              logf("scsi unknown cmd %x",cbw->command_block[0x0]);
  389. +            usb_drv_stall(ep_in, true,true);
  390.              send_csw(UMS_STATUS_FAIL);
  391.              cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
  392.              cur_sense_data.asc=ASC_INVALID_COMMAND;