Initial commit
[kk_librfid.git] / firmware / src / os / .svn / text-base / pcd_enumerate.c.svn-base
blobab000c7b1f8a584bd7717f0477067e2ee4c91843
1 /* AT91SAM7 USB interface code for OpenPCD 
2  * (C) 2006 by Harald Welte <laforge@gnumonks.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by 
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * based on existing AT91SAM7 UDP CDC ACM example code, licensed as followed:
19  *----------------------------------------------------------------------------
20  *      ATMEL Microcontroller Software Support  -  ROUSSET  -
21  *----------------------------------------------------------------------------
22  * The software is delivered "AS IS" without warranty or condition of any
23  * kind, either express, implied or statutory. This includes without
24  * limitation any warranty or condition with respect to merchantability or
25  * fitness for any particular purpose, or against the infringements of
26  * intellectual property rights of others.
27  *----------------------------------------------------------------------------
28  */
30 #include <errno.h>
31 #include <usb_ch9.h>
32 #include <sys/types.h>
33 #include <asm/atomic.h>
34 #include <lib_AT91SAM7.h>
35 #include <openpcd.h>
37 #include <usb_strings_app.h>
39 #include <os/pcd_enumerate.h>
40 #include <os/req_ctx.h>
41 #include <dfu/dfu.h>
42 #include "../openpcd.h"
43 #include <os/dbgu.h>
45 #include "../config.h"
47 //#define DEBUG_UDP_IRQ
48 //#define DEBUG_UDP_IRQ_IN
49 //#define DEBUG_UDP_IRQ_OUT
50 #define DEBUG_UDP_EP0
52 #ifdef DEBUG_UDP_IRQ
53 #define DEBUGI(x, args ...)     DEBUGP(x, ## args)
54 #else
55 #define DEBUGI(x, args ...)     do { } while (0)
56 #endif
58 #ifdef DEBUG_UDP_IRQ_IN
59 #define DEBUGII(x, args ...)    DEBUGP(x, ## args)
60 #else
61 #define DEBUGII(x, args ...)    do { } while (0)
62 #endif
64 #ifdef DEBUG_UDP_IRQ_OUT
65 #define DEBUGIO(x, args ...)    DEBUGP(x, ## args)
66 #else
67 #define DEBUGIO(x, args ...)    do { } while (0)
68 #endif
70 #ifdef DEBUG_UDP_EP0
71 #define DEBUGE(x, args ...)     DEBUGP(x, ## args)
72 #else
73 #define DEBUGE(x, args ...)     do { } while (0)
74 #endif
76 #define CONFIG_DFU
78 #ifdef CONFIG_DFU
79 static const struct dfuapi *dfu = DFU_API_LOCATION;
80 #define udp_init                dfu->udp_init
81 //#define udp_ep0_send_data     dfu->ep0_send_data
82 #define udp_ep0_send_zlp        dfu->ep0_send_zlp
83 #define udp_ep0_send_stall      dfu->ep0_send_stall
84 #else
85 #error non-DFU builds currently not supported (yet) again
86 #endif
88 #ifdef CONFIG_USB_HID
89 #include "usb_descriptors_hid.h"
90 #else
91 #include "usb_descriptors_openpcd.h"
92 #endif
94 static struct udp_pcd upcd;
96 struct epstate {
97         u_int32_t state_busy;
98         u_int32_t state_pending;
101 static const struct epstate epstate[] = {
102         [0] =   { .state_busy = RCTX_STATE_INVALID },
103         [1] =   { .state_busy = RCTX_STATE_INVALID },
104         [2] =   { .state_busy = RCTX_STATE_UDP_EP2_BUSY,
105                   .state_pending = RCTX_STATE_UDP_EP2_PENDING },
106         [3] =   { .state_busy = RCTX_STATE_UDP_EP3_BUSY,
107                   .state_pending = RCTX_STATE_UDP_EP3_PENDING },
110 /* Send Data through the control endpoint */
111 static void udp_ep0_send_data(const char *pData, u_int32_t length)
113         AT91PS_UDP pUdp = AT91C_BASE_UDP;
114         u_int32_t cpt = 0;
115         AT91_REG csr;
117         DEBUGE("send_data: %u bytes ", length);
119         do {
120                 cpt = MIN(length, 8);
121                 length -= cpt;
123                 DEBUGE("fifo_fill ");
124                 while (cpt--)
125                         pUdp->UDP_FDR[0] = *pData++;
127                 if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
128                         DEBUGE("wait_txcomp_clear ");
129                         pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
130                         while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) ;
131                 }
133                 DEBUGE("set_txpktrdy ");
134                 pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
135                 DEBUGE("wait_txcomp ");
136                 do {
137                         csr = pUdp->UDP_CSR[0];
139                         /* Data IN stage has been stopped by a status OUT */
140                         if (csr & AT91C_UDP_RX_DATA_BK0) {
141                                 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
142                                 DEBUGE("stopped by status out ");
143                                 return;
144                         }
145                 } while (!(csr & AT91C_UDP_TXCOMP));
147         } while (length);
149         DEBUGE("clear_txcomp ");
150         if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
151                 pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
152                 while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) ;
153         }
154         DEBUGE("done ");
157 static void reset_ep(unsigned int ep)
159         AT91PS_UDP pUDP = upcd.pUdp;
160         struct req_ctx *rctx;
162         //pUDP->UDP_CSR[ep] = AT91C_UDP_EPEDS;
164         atomic_set(&upcd.ep[ep].pkts_in_transit, 0);
166         /* free all currently transmitting contexts */
167         while ((rctx = req_ctx_find_get(0, epstate[ep].state_busy,
168                                        RCTX_STATE_FREE))) {}
169         /* free all currently pending contexts */
170         while ((rctx = req_ctx_find_get(0, epstate[ep].state_pending,
171                                        RCTX_STATE_FREE))) {}
173         pUDP->UDP_RSTEP |= (1 << ep);
174         pUDP->UDP_RSTEP &= ~(1 << ep);
176         upcd.ep[ep].incomplete.rctx = NULL;
179 static void udp_ep0_handler(void);
181 void udp_unthrottle(void)
183         AT91PS_UDP pUDP = upcd.pUdp;
184         pUDP->UDP_IER = AT91C_UDP_EPINT1;
187 static int __udp_refill_ep(int ep)
189         u_int16_t i;
190         AT91PS_UDP pUDP = upcd.pUdp;
191         struct req_ctx *rctx;
192         unsigned int start, end;
194         /* If we're not configured by the host yet, there is no point
195          * in trying to send data to it... */
196         if (!upcd.cur_config) {
197                 return -ENXIO;
198         }
199         
200         /* If there are already two packets in transit, the DPR of
201          * the SAM7 UDC doesn't have space for more data */
202         if (atomic_read(&upcd.ep[ep].pkts_in_transit) == 2) {
203                 return -EBUSY;
204         }
206         /* If we have an incompletely-transmitted req_ctx (>EP size),
207          * we need to transmit the rest and finish the transaction */
208         if (upcd.ep[ep].incomplete.rctx) {
209                 rctx = upcd.ep[ep].incomplete.rctx;
210                 start = upcd.ep[ep].incomplete.bytes_sent;
211         } else {
212                 /* get pending rctx and start transmitting from zero */
213                 rctx = req_ctx_find_get(0, epstate[ep].state_pending, 
214                                         epstate[ep].state_busy);
215                 if (!rctx)
216                         return 0;
217                 start = 0;
219                 upcd.ep[ep].incomplete.bytes_sent = 0;
220         }
222         if (rctx->tot_len - start <= AT91C_EP_IN_SIZE)
223                 end = rctx->tot_len;
224         else
225                 end = start + AT91C_EP_IN_SIZE;
227         /* fill FIFO/DPR */
228         DEBUGII("RCTX_tx(ep=%u,ctx=%u):%u ", ep, req_ctx_num(rctx),
229                 end - start);
230         for (i = start; i < end; i++) 
231                 pUDP->UDP_FDR[ep] = rctx->data[i];
233         if (atomic_inc_return(&upcd.ep[ep].pkts_in_transit) == 1) {
234                 /* not been transmitting before, start transmit */
235                 pUDP->UDP_CSR[ep] |= AT91C_UDP_TXPKTRDY;
236         }
238         if ((end - start < AT91C_EP_OUT_SIZE) ||
239             (((end - start) == 0) && end && (rctx->tot_len % AT91C_EP_OUT_SIZE) == 0)) {
240                 /* CASE 1: return context to pool, if
241                  * - packet transfer < AT91C_EP_OUT_SIZE
242                  * - after ZLP of transfer == AT91C_EP_OUT_SIZE
243                  * - after ZLP of transfer % AT91C_EP_OUT_SIZE == 0
244                  * - after last packet of transfer % AT91C_EP_OUT_SIZE != 0
245                  */
246                 DEBUGII("RCTX(ep=%u,ctx=%u)_tx_done ", ep, req_ctx_num(rctx));
247                 upcd.ep[ep].incomplete.rctx = NULL;
248                 req_ctx_put(rctx);
249         } else {
250                 /* CASE 2: mark transfer as incomplete, if
251                  * - after data of transfer == AT91C_EP_OUT_SIZE
252                  * - after data of transfer > AT91C_EP_OUT_SIZE
253                  * - after last packet of transfer % AT91C_EP_OUT_SIZE == 0
254                  */
255                 upcd.ep[ep].incomplete.rctx = rctx;
256                 upcd.ep[ep].incomplete.bytes_sent += end - start;
257                 DEBUGII("RCTX(ep=%u)_tx_cont ", ep);
258         }
260         return 1;
263 int udp_refill_ep(int ep)
265         unsigned long flags;
266         int ret;
268         local_irq_save(flags);
269         ret = __udp_refill_ep(ep);
270         local_irq_restore(flags);
272         return ret;
275 static void udp_irq(void)
277         u_int32_t csr;
278         AT91PS_UDP pUDP = upcd.pUdp;
279         AT91_REG isr = pUDP->UDP_ISR;
281         DEBUGI("udp_irq(imr=0x%04x, isr=0x%04x, state=%d): ", 
282                 pUDP->UDP_IMR, isr, upcd.state);
284         if (isr & AT91C_UDP_ENDBUSRES) {
285                 DEBUGI("ENDBUSRES ");
286                 pUDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
287                 pUDP->UDP_IER = AT91C_UDP_EPINT0;
288                 /* reset all endpoints */
289                 pUDP->UDP_RSTEP = (unsigned int)-1;
290                 pUDP->UDP_RSTEP = 0;
291                 /* Enable the function */
292                 pUDP->UDP_FADDR = AT91C_UDP_FEN;
293                 /* Configure endpoint 0 */
294                 pUDP->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
295                 upcd.cur_config = 0;
296                 upcd.state = USB_STATE_DEFAULT;
298                 reset_ep(1);
299                 reset_ep(2);
300                 reset_ep(3);
301                 
302 #ifdef CONFIG_DFU
303                 if (*dfu->dfu_state == DFU_STATE_appDETACH) {
304                         DEBUGI("DFU_SWITCH ");
305                         /* now we need to switch to DFU mode */
306                         dfu->dfu_switch();
307                         goto out;
308                 }
309 #endif
310         }
312         if (isr & AT91C_UDP_EPINT0) {
313                 DEBUGI("EP0INT(Control) ");
314                 udp_ep0_handler();
315         }
316         if (isr & AT91C_UDP_EPINT1) {
317                 u_int32_t cur_rcv_bank = upcd.cur_rcv_bank;
318                 u_int16_t i, pkt_size;
319                 struct req_ctx *rctx;
321                 csr = pUDP->UDP_CSR[1];
322                 pkt_size = csr >> 16;
324                 DEBUGI("EP1INT(Out, CSR=0x%08x) ", csr);
325                 if (cur_rcv_bank == AT91C_UDP_RX_DATA_BK1)
326                         DEBUGIO("cur_bank=1 ");
327                 else if (cur_rcv_bank == AT91C_UDP_RX_DATA_BK0)
328                         DEBUGIO("cur_bank=0 ");
329                 else
330                         DEBUGIO("cur_bank INVALID ");
332                 if (csr & AT91C_UDP_RX_DATA_BK1)
333                         DEBUGIO("BANK1 ");
334                 if (csr & AT91C_UDP_RX_DATA_BK0)
335                         DEBUGIO("BANK0 ");
337                 if (!(csr & cur_rcv_bank))
338                         goto cont_ep2;
340                 if (upcd.ep[1].incomplete.rctx) {
341                         DEBUGIO("continue_incompl_RCTX ");
342                         rctx = upcd.ep[1].incomplete.rctx;
343                 } else {
344                         /* allocate new req_ctx  */
345                         DEBUGIO("alloc_new_RCTX ");
346                 
347                         /* whether to get a big or a small req_ctx */
348                         if (pkt_size >= AT91C_EP_IN_SIZE)
349                                 rctx = req_ctx_find_get(1, RCTX_STATE_FREE,
350                                                  RCTX_STATE_UDP_RCV_BUSY);
351                         else 
352                                 rctx = req_ctx_find_get(0, RCTX_STATE_FREE,
353                                                  RCTX_STATE_UDP_RCV_BUSY);
355                         if (!rctx) {
356                                 /* disable interrupts for now */
357                                 pUDP->UDP_IDR = AT91C_UDP_EPINT1;
358                                 DEBUGP("NO_RCTX_AVAIL! ");
359                                 goto cont_ep2;
360                         }
361                         rctx->tot_len = 0;
362                 }
363                 DEBUGIO("RCTX=%u ", req_ctx_num(rctx));
365                 if (rctx->size - rctx->tot_len < pkt_size) {
366                         DEBUGIO("RCTX too small, truncating !!!\n");
367                         pkt_size = rctx->size - rctx->tot_len;
368                 }
370                 for (i = 0; i < pkt_size; i++)
371                         rctx->data[rctx->tot_len++] = pUDP->UDP_FDR[1];
373                 pUDP->UDP_CSR[1] &= ~cur_rcv_bank;
375                 /* toggle current receive bank */
376                 if (cur_rcv_bank == AT91C_UDP_RX_DATA_BK0)
377                         cur_rcv_bank = AT91C_UDP_RX_DATA_BK1;
378                 else
379                         cur_rcv_bank = AT91C_UDP_RX_DATA_BK0;
380                 upcd.cur_rcv_bank = cur_rcv_bank;
382                 DEBUGIO("rctxdump(%s) ", hexdump(rctx->data, rctx->tot_len));
384                 /* if this is the last packet in transfer, hand rctx up the
385                  * stack */
386                 if (pkt_size < AT91C_EP_IN_SIZE) {
387                         DEBUGIO("RCTX_rx_done ");
388                         req_ctx_set_state(rctx, RCTX_STATE_UDP_RCV_DONE);
389                         upcd.ep[1].incomplete.rctx = NULL;
390                 } else {
391                         DEBUGIO("RCTX_rx_cont ");
392                         upcd.ep[1].incomplete.rctx = rctx;
393                 }
394         }
395 cont_ep2:
396         if (isr & AT91C_UDP_EPINT2) {
397                 csr = pUDP->UDP_CSR[2];
398                 DEBUGI("EP2INT(In, CSR=0x%08x) ", csr);
399                 if (csr & AT91C_UDP_TXCOMP) {
400                         DEBUGII("ACK_TX_COMP ");
401                         /* acknowledge TX completion */
402                         pUDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
403                         while (pUDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) ;
405                         /* if we already have another packet in DPR, send it */
406                         if (atomic_dec_return(&upcd.ep[2].pkts_in_transit) == 1)
407                                 pUDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
409                         __udp_refill_ep(2);
410                 }
411         }
412         if (isr & AT91C_UDP_EPINT3) {
413                 csr = pUDP->UDP_CSR[3];
414                 DEBUGII("EP3INT(Interrupt, CSR=0x%08x) ", csr);
415                 /* Transmit has completed, re-fill from pending rcts for EP3 */
416                 if (csr & AT91C_UDP_TXCOMP) {
417                         pUDP->UDP_CSR[3] &= ~AT91C_UDP_TXCOMP;
418                         while (pUDP->UDP_CSR[3] & AT91C_UDP_TXCOMP) ;
420                         /* if we already have another packet in DPR, send it */
421                         if (atomic_dec_return(&upcd.ep[3].pkts_in_transit) == 1)
422                                 pUDP->UDP_CSR[3] |= AT91C_UDP_TXPKTRDY;
424                         __udp_refill_ep(3);
425                 }
426         }
427         if (isr & AT91C_UDP_RXSUSP) {
428                 pUDP->UDP_ICR = AT91C_UDP_RXSUSP;
429                 DEBUGI("RXSUSP ");
430 #ifdef CONFIG_USB_SUSPEND
431                 upcd.state = USB_STATE_SUSPENDED;
432                 /* FIXME: implement suspend/resume correctly. This
433                  * involves saving the pre-suspend state, and calling back
434                  * into the main application program to ask it to power down
435                  * all peripherals, switching to slow clock, ... */
436 #endif
437         }
438         if (isr & AT91C_UDP_RXRSM) {
439                 pUDP->UDP_ICR = AT91C_UDP_RXRSM;
440                 DEBUGI("RXRSM ");
441 #ifdef CONFIG_USB_SUSPEND
442                 if (upcd.state == USB_STATE_SUSPENDED)
443                         upcd.state = USB_STATE_CONFIGURED;
444                 /* FIXME: implement suspend/resume */
445 #endif
446         }
447         if (isr & AT91C_UDP_EXTRSM) {
448                 pUDP->UDP_ICR = AT91C_UDP_EXTRSM;
449                 DEBUGI("EXTRSM ");
450                 /* FIXME: implement suspend/resume */
451         }
452         if (isr & AT91C_UDP_SOFINT) {
453                 pUDP->UDP_ICR = AT91C_UDP_SOFINT;
454                 DEBUGI("SOFINT ");
455         }
456         if (isr & AT91C_UDP_WAKEUP) {
457                 pUDP->UDP_ICR = AT91C_UDP_WAKEUP;
458                 DEBUGI("WAKEUP ");
459         }
460 out:
461         DEBUGI("END\r\n");
462         AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_UDP);
465 void udp_pullup_on(void)
467 #ifdef PCD
468         AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
469 #endif
470         AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUPv4);
473 void udp_pullup_off(void)
475 #ifdef PCD
476         AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
477 #endif
478         AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUPv4);
481 /* Open USB Device Port  */
482 void udp_open(void)
484         DEBUGPCRF("entering");
485         udp_init();
486         upcd.pUdp = AT91C_BASE_UDP;
487         upcd.cur_config = 0;
488         upcd.cur_rcv_bank = AT91C_UDP_RX_DATA_BK0;
489         /* This should start with USB_STATE_NOTATTACHED, but we're a pure
490          * bus powered device and thus start with powered */
491         upcd.state = USB_STATE_POWERED;
493         AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_UDP,
494                               OPENPCD_IRQ_PRIO_UDP,
495                               AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &udp_irq);
496         AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_UDP);
498         /* End-of-Bus-Reset is always enabled */
500         /* Set the Pull up resistor */
501         udp_pullup_on();
504 void udp_reset(void)
506         volatile int i;
508         udp_pullup_off();
509         for (i = 0; i < 0xffff; i++)
510                 ;
511         udp_pullup_on();
514 /* Handle requests on the USB Control Endpoint */
515 static void udp_ep0_handler(void)
517         AT91PS_UDP pUDP = upcd.pUdp;
518         u_int8_t bmRequestType, bRequest;
519         u_int16_t wValue, wIndex, wLength, wStatus;
520         u_int32_t csr = pUDP->UDP_CSR[0];
522         DEBUGE("CSR=0x%04x ", csr);
524         if (csr & AT91C_UDP_STALLSENT) {
525                 DEBUGE("ACK_STALLSENT ");
526                 pUDP->UDP_CSR[0] = ~AT91C_UDP_STALLSENT;
527         }
529         if (csr & AT91C_UDP_RX_DATA_BK0) {
530                 DEBUGE("ACK_BANK0 ");
531                 pUDP->UDP_CSR[0] &= ~AT91C_UDP_RX_DATA_BK0;
532         }
534         if (!(csr & AT91C_UDP_RXSETUP)) {
535                 DEBUGE("no setup packet ");
536                 return;
537         }
539         DEBUGE("len=%d ", csr >> 16);
540         if (csr >> 16  == 0) {
541                 DEBUGE("empty packet ");
542                 return;
543         }
545         bmRequestType = pUDP->UDP_FDR[0];
546         bRequest = pUDP->UDP_FDR[0];
547         wValue = (pUDP->UDP_FDR[0] & 0xFF);
548         wValue |= (pUDP->UDP_FDR[0] << 8);
549         wIndex = (pUDP->UDP_FDR[0] & 0xFF);
550         wIndex |= (pUDP->UDP_FDR[0] << 8);
551         wLength = (pUDP->UDP_FDR[0] & 0xFF);
552         wLength |= (pUDP->UDP_FDR[0] << 8);
554         DEBUGE("bmRequestType=0x%2x ", bmRequestType);
556         if (bmRequestType & 0x80) {
557                 DEBUGE("DATA_IN=1 ");
558                 pUDP->UDP_CSR[0] |= AT91C_UDP_DIR;
559                 while (!(pUDP->UDP_CSR[0] & AT91C_UDP_DIR)) ;
560         }
561         pUDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
562         while ((pUDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)) ;
564         DEBUGE("dfu_state = %u ", *dfu->dfu_state);
565         /* Handle supported standard device request Cf Table 9-3 in USB
566          * speciication Rev 1.1 */
567         switch ((bRequest << 8) | bmRequestType) {
568                 u_int8_t desc_type, desc_index;
569         case STD_GET_DESCRIPTOR:
570                 DEBUGE("GET_DESCRIPTOR(wValue=0x%04x, wIndex=0x%04x) ",
571                         wValue, wIndex);
572                 desc_type = wValue >> 8;
573                 desc_index = wValue & 0xff;
574                 switch (desc_type) {
575                 case USB_DT_DEVICE:
576                         /* Return Device Descriptor */
577 #ifdef CONFIG_DFU
578                         if (*dfu->dfu_state != DFU_STATE_appIDLE)
579                                 udp_ep0_send_data((const char *) 
580                                                   dfu->dfu_dev_descriptor,
581                                                   MIN(dfu->dfu_dev_descriptor->bLength,
582                                                       wLength));
583                         else
584 #endif
585                         udp_ep0_send_data((const char *) &dev_descriptor,
586                                            MIN(sizeof(dev_descriptor), wLength));
587                         break;
588                 case USB_DT_CONFIG:
589                         /* Return Configuration Descriptor */
590 #ifdef CONFIG_DFU
591                         if (*dfu->dfu_state != DFU_STATE_appIDLE)
592                                 udp_ep0_send_data((const char *)
593                                                   dfu->dfu_cfg_descriptor,
594                                                   MIN(dfu->dfu_cfg_descriptor->ucfg.wTotalLength,
595                                                       wLength));
596                         else
597 #endif
598                         udp_ep0_send_data((const char *) &cfg_descriptor,
599                                            MIN(sizeof(cfg_descriptor), wLength));
600                         break;
601                 case USB_DT_STRING:
602 #ifdef CONFIG_USB_STRING
603                         /* Return String descriptor */
604                         if (desc_index > ARRAY_SIZE(usb_strings))
605                                 goto out_stall;
606                         DEBUGE("bLength=%u, wLength=%u\n", 
607                                 usb_strings[desc_index]->bLength, wLength);
608                         udp_ep0_send_data((const char *) usb_strings[desc_index],
609                                           MIN(usb_strings[desc_index]->bLength, 
610                                               wLength));
611 #else
612                         goto out_stall;
613 #endif
614                         break;
615                 case USB_DT_CS_DEVICE:
616                         /* Return Function descriptor */
617                         udp_ep0_send_data((const char *) &dfu->dfu_cfg_descriptor->func_dfu,
618                                           MIN(sizeof(dfu->dfu_cfg_descriptor->func_dfu), wLength));
619                         break;
620                 case USB_DT_INTERFACE:
621                         /* Return Interface descriptor */
622                         if (desc_index > cfg_descriptor.ucfg.bNumInterfaces)
623                                 goto out_stall;
624                         switch (desc_index) {
625                         case 0:
626                                 udp_ep0_send_data((const char *)
627                                                 &cfg_descriptor.uif,
628                                                 MIN(sizeof(cfg_descriptor.uif),
629                                                       wLength));
630                                 break;
631         #ifdef CONFIG_DFU
632                         case 1:
633                                 udp_ep0_send_data((const char *)
634                                                 &cfg_descriptor.uif_dfu[0],
635                                                 MIN(sizeof(cfg_descriptor.uif_dfu[0]),
636                                                     wLength));
637                                 break;
638                         case 2:
639                                 udp_ep0_send_data((const char *)
640                                                 &cfg_descriptor.uif_dfu[1],
641                                                 MIN(sizeof(cfg_descriptor.uif_dfu[1]),
642                                                     wLength));
643                                 break;
644         #endif
645                         default:
646                                 goto out_stall;
647                                 break;
648                         }
649                         break;
650                 default:
651                         goto out_stall;
652                         break;
653                 }
654                 break;
655         case STD_SET_ADDRESS:
656                 DEBUGE("SET_ADDRESS ");
657                 if (wValue > 127)
658                         goto out_stall;
659                 
660                 switch (upcd.state) {
661                 case USB_STATE_DEFAULT:
662                         udp_ep0_send_zlp();
663                         if (wValue == 0) {
664                                 /* do nothing */
665                         } else {
666                                 pUDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);
667                                 pUDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
668                                 upcd.state = USB_STATE_ADDRESS;
669                         }
670                         break;
671                 case USB_STATE_ADDRESS:
672                         udp_ep0_send_zlp();
673                         if (wValue == 0) {
674                                 upcd.state = USB_STATE_DEFAULT;
675                         } else {
676                                 pUDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);
677                         }
678                         break;
679                 default:
680                         goto out_stall;
681                         break;
682                 }
683                 break;
684         case STD_SET_CONFIGURATION:
685                 DEBUGE("SET_CONFIG ");
686                 if (upcd.state != USB_STATE_ADDRESS &&
687                     upcd.state != USB_STATE_CONFIGURED) {
688                         goto out_stall;
689                 }
690                 if ((wValue & 0xff) == 0) {
691                         DEBUGE("VALUE==0 ");
692                         upcd.state = USB_STATE_ADDRESS;
693                         pUDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
694                         pUDP->UDP_CSR[1] = 0;
695                         pUDP->UDP_CSR[2] = 0;
696                         pUDP->UDP_CSR[3] = 0;
697                 } else if ((wValue & 0xff) <=
698                                         dev_descriptor.bNumConfigurations) {
699                         DEBUGE("VALUE!=0 ");
700                         upcd.state = USB_STATE_CONFIGURED;
701                         pUDP->UDP_GLBSTATE = AT91C_UDP_CONFG;
702                         pUDP->UDP_CSR[1] = AT91C_UDP_EPEDS |
703                                            AT91C_UDP_EPTYPE_BULK_OUT;
704                         pUDP->UDP_CSR[2] = AT91C_UDP_EPEDS |
705                                            AT91C_UDP_EPTYPE_BULK_IN;
706                         pUDP->UDP_CSR[3] = AT91C_UDP_EPEDS |
707                                            AT91C_UDP_EPTYPE_INT_IN;
708                 } else {
709                         /* invalid configuration */
710                         goto out_stall;
711                         break;
712                 }
713                 upcd.cur_config = wValue;
714                 udp_ep0_send_zlp();
715                 pUDP->UDP_IER = (AT91C_UDP_EPINT0 | AT91C_UDP_EPINT1 |
716                                  AT91C_UDP_EPINT2 | AT91C_UDP_EPINT3);
717                 break;
718         case STD_GET_CONFIGURATION:
719                 DEBUGE("GET_CONFIG ");
720                 switch (upcd.state) {
721                 case USB_STATE_ADDRESS:
722                 case USB_STATE_CONFIGURED:
723                         udp_ep0_send_data((char *)&(upcd.cur_config),
724                                            sizeof(upcd.cur_config));
725                         break;
726                 default:
727                         goto out_stall;
728                         break;
729                 }
730                 break;
731         case STD_GET_INTERFACE:
732                 DEBUGE("GET_INTERFACE ");
733                 if (upcd.state != USB_STATE_CONFIGURED)
734                         goto out_stall;
735                 udp_ep0_send_data((char *)&(upcd.cur_altsett),
736                                   sizeof(upcd.cur_altsett));
737                 break;
738         case STD_GET_STATUS_ZERO:
739                 DEBUGE("GET_STATUS_ZERO ");
740                 wStatus = 0;
741                 udp_ep0_send_data((char *)&wStatus, sizeof(wStatus));
742                 break;
743         case STD_GET_STATUS_INTERFACE:
744                 DEBUGE("GET_STATUS_INTERFACE ");
745                 if (upcd.state == USB_STATE_DEFAULT ||
746                     (upcd.state == USB_STATE_ADDRESS && wIndex != 0))
747                         goto out_stall;
748                 wStatus = 0;
749                 udp_ep0_send_data((char *)&wStatus, sizeof(wStatus));
750                 break;
751         case STD_GET_STATUS_ENDPOINT:
752                 DEBUGE("GET_STATUS_ENDPOINT(EPidx=%u) ", wIndex&0x0f);
753                 if (upcd.state == USB_STATE_DEFAULT ||
754                     (upcd.state == USB_STATE_ADDRESS && wIndex != 0))
755                         goto out_stall;
756                 wStatus = 0;
757                 wIndex &= 0x0F;
758                 if ((pUDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {
759                         wStatus =
760                             (pUDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
761                         udp_ep0_send_data((char *)&wStatus,
762                                            sizeof(wStatus));
763                 } else if ((pUDP->UDP_GLBSTATE & AT91C_UDP_FADDEN)
764                            && (wIndex == 0)) {
765                         wStatus =
766                             (pUDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
767                         udp_ep0_send_data((char *)&wStatus,
768                                            sizeof(wStatus));
769                 } else
770                         goto out_stall;
771                 break;
772         case STD_SET_FEATURE_ZERO:
773                 DEBUGE("SET_FEATURE_ZERO ");
774                 if (upcd.state == USB_STATE_ADDRESS &&
775                     (wIndex & 0xff) != 0)
776                         goto out_stall;
777                 /* FIXME: implement this */
778                 goto out_stall;
779                 break;
780         case STD_SET_FEATURE_INTERFACE:
781                 DEBUGE("SET_FEATURE_INTERFACE ");
782                 if (upcd.state == USB_STATE_ADDRESS &&
783                     (wIndex & 0xff) != 0)
784                         goto out_stall;
785                 udp_ep0_send_zlp();
786                 break;
787         case STD_SET_FEATURE_ENDPOINT:
788                 DEBUGE("SET_FEATURE_ENDPOINT ");
789                 if (upcd.state == USB_STATE_ADDRESS &&
790                     (wIndex & 0xff) != 0)
791                         goto out_stall;
792                 if (wValue != USB_ENDPOINT_HALT)
793                         goto out_stall;
794                 udp_ep0_send_zlp();
795                 wIndex &= 0x0F;
796                 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
797                         pUDP->UDP_CSR[wIndex] = 0;
798                         udp_ep0_send_zlp();
799                 } else
800                         goto out_stall;
801                 break;
802         case STD_CLEAR_FEATURE_ZERO:
803                 DEBUGE("CLEAR_FEATURE_ZERO ");
804                 goto out_stall;
805                 break;
806         case STD_CLEAR_FEATURE_INTERFACE:
807                 DEBUGP("CLEAR_FEATURE_INTERFACE ");
808                 udp_ep0_send_zlp();
809                 break;
810         case STD_CLEAR_FEATURE_ENDPOINT:
811                 DEBUGE("CLEAR_FEATURE_ENDPOINT(EPidx=%u) ", wIndex & 0x0f);
812                 if (wValue != USB_ENDPOINT_HALT)
813                         goto out_stall;
814                 wIndex &= 0x0F;
815                 if ((wValue == 0) && wIndex && (wIndex <= 3)) {
816                         reset_ep(wIndex);
817                         udp_ep0_send_zlp();
818                 } else
819                         goto out_stall;
820                 break;
821         case STD_SET_INTERFACE:
822                 DEBUGE("SET INTERFACE ");
823                 if (upcd.state != USB_STATE_CONFIGURED)
824                         goto out_stall;
825                 if (wIndex > cfg_descriptor.ucfg.bNumInterfaces)
826                         goto out_stall;
827                 upcd.cur_interface = wIndex;
828                 upcd.cur_altsett = wValue;
829                 /* USB spec mandates that if we only support one altsetting in
830                  * the given interface, we shall respond with STALL in the
831                  * status stage */
832                 udp_ep0_send_stall();
833                 break;
834         default:
835                 DEBUGE("DEFAULT(req=0x%02x, type=0x%02x) ", 
836                         bRequest, bmRequestType);
837 #ifdef CONFIG_DFU
838                 if ((bmRequestType & 0x3f) == USB_TYPE_DFU) {
839                         dfu->dfu_ep0_handler(bmRequestType, bRequest, wValue,
840                                              wLength);
841                 } else
842 #endif
843                 goto out_stall;
844                 break;
845         }
846         return;
847 out_stall:
848         DEBUGE("STALL!! ");
849         udp_ep0_send_stall();