m3dev

cortex m3 debug tools -- superceded by mdebug
git clone http://frotz.net/git/m3dev.git
Log | Files | Refs | README | LICENSE

usb-v2.c (15627B)


      1 /* usb.c
      2  *
      3  * Copyright 2011 Brian Swetland <swetland@frotz.net>
      4  * Copyright 2013-2014 Erik Gillikg <konkers@konkers.net>
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 
     19 #include <fw/io.h>
     20 #include <fw/lib.h>
     21 #include <fw/string.h>
     22 #include <fw/types.h>
     23 
     24 #include <arch/cpu.h>
     25 #include <arch/interrupts.h>
     26 #include <arch/hardware.h>
     27 
     28 #include <protocol/usb.h>
     29 
     30 #include "usb-v2.h"
     31 
     32 #undef DEBUG
     33 
     34 #ifdef DEBUG
     35 #define usb_debug(fmt, args...) do { \
     36 		printx(fmt, ##args); \
     37 	} while (0)
     38 
     39 static inline void dump_bytes(void *addr, int len)
     40 {
     41 
     42 	int i;
     43 	for (i = 0; i <len; i++) {
     44 		if (i != 0)
     45 			printx(" ");
     46 		printx("%b", ((u8 *)addr)[i]);
     47 	}
     48 	printx("\n");
     49 }
     50 
     51 #else
     52 #define usb_debug(fmt, args...) do { \
     53 	} while (0)
     54 static inline void dump_bytes(void *addr, int len)
     55 {
     56 }
     57 #endif
     58 
     59 static volatile unsigned msec_counter = 0;
     60 
     61 void usb_handle_irq(void);
     62 
     63 static u8 _dev00[] = {
     64 	18,		/* size */
     65 	DSC_DEVICE,
     66 	0x00, 0x01,	/* version */
     67 	0xFF,		/* class */
     68 	0x00,		/* subclass */
     69 	0x00,		/* protocol */
     70 	0x40,		/* maxpacket0 */
     71 	0xd1, 0x18,	/* VID */
     72 	0x02, 0x65,	/* PID */
     73 	0x00, 0x01,	/* version */
     74 	0x00,		/* manufacturer string */
     75 	0x00,		/* product string */
     76 	0x00,		/* serialno string */
     77 	0x01,		/* configurations */
     78 };
     79 
     80 static u8 _cfg00[] = {
     81 	9,
     82 	DSC_CONFIG,
     83 	0x20, 0x00,	/* total length */
     84 	0x01,		/* ifc count */
     85 	0x01,		/* configuration value */
     86 	0x00,		/* configuration string */
     87 	0x80,		/* attributes */
     88 	50,		/* mA/2 */
     89 
     90 	9,
     91 	DSC_INTERFACE,
     92 	0x00,		/* interface number */
     93 	0x00,		/* alt setting */
     94 	0x02,		/* ept count */
     95 	0xFF,		/* class */
     96 	0x00,		/* subclass */
     97 	0x00,		/* protocol */
     98 	0x00,		/* interface string */
     99 
    100 	7,
    101 	DSC_ENDPOINT,
    102 	0x81,		/* address */
    103 	0x02,		/* bulk */
    104 	0x40, 0x00,	/* max packet size */
    105 	0x00,		/* interval */
    106 
    107 	7,
    108 	DSC_ENDPOINT,
    109 	0x01,		/* address */
    110 	0x02,		/* bulk */
    111 	0x40, 0x00,	/* max packet size */
    112 	0x00,		/* interval */
    113 };
    114 
    115 const static u8 lang_id[] = {
    116 	4,
    117 	DSC_STRING,
    118 	0x09, 0x04
    119 };
    120 
    121 static u16 mfg_string[24] = {
    122 };
    123 
    124 static u16 prod_string[24] = {
    125 };
    126 
    127 static void *usb_sram_highwater = (void *) USB_SRAM;
    128 static u32 *usb_ep_list;
    129 static u8 *usb_setup_buf;
    130 
    131 struct usb_ep {
    132 	u8 addr;
    133 
    134 	u16 in_size;
    135 	u16 in_max_packet;
    136 	i16 in_len;
    137 	u16 in_pos;
    138 
    139 	u16 out_size;
    140 	u16 out_len;
    141 	u16 out_pos;
    142 
    143 	u8 *out_buf;
    144 	u8 *in_buf;
    145 	/* no pingpong buffers supported yet */
    146 };
    147 
    148 static struct usb_ep usb_ep_data[5];
    149 
    150 enum {
    151 	USB_STATE_OFFLINE = 0,
    152 	USB_STATE_ONLINE,
    153 };
    154 
    155 static volatile unsigned usb_frames;
    156 volatile int usb_state;
    157 
    158 void (*usb_ep1_rx_full_cb)(void);
    159 void (*usb_ep1_tx_empty_cb)(void);
    160 void (*usb_ep2_rx_full_cb)(void);
    161 void (*usb_ep2_tx_empty_cb)(void);
    162 void (*usb_online_cb)(int online);
    163 
    164 
    165 static void *usb_sram_alloc(int size, int align)
    166 {
    167 	void *highwater = usb_sram_highwater;
    168 	highwater += (align - ((unsigned)usb_sram_highwater % align)) % align;
    169 	if (highwater + size > (void *)(USB_SRAM + USB_SRAM_SIZE)) {
    170 		printx("can't allocate 0x%x bytes of USB SRAM\n", size);
    171 		return 0;
    172 	}
    173 	usb_sram_highwater = highwater + size;
    174 
    175 	return highwater;
    176 }
    177 
    178 static void usb_setup_ep(struct usb_ep *ep, u8 addr, u16 in_buf_size, u16 in_max_packet, u16 out_buf_size)
    179 {
    180 	ep->addr = addr;
    181 
    182 	ep->in_buf = usb_sram_alloc(in_buf_size, 64);
    183 	ep->in_size = in_buf_size;
    184 	ep->in_len = -1;
    185 	ep->in_max_packet = in_max_packet;
    186 	ep->out_buf = usb_sram_alloc(out_buf_size, 64);
    187 	ep->out_size = out_buf_size;
    188 }
    189 
    190 void usb_init(unsigned vid, unsigned pid, const char *mfg, const char *prod) {
    191 	unsigned n;
    192 
    193 	irq_enable(v_usb_irq);
    194 
    195 	usb_state = USB_STATE_OFFLINE;
    196 
    197 	_dev00[8] = vid;
    198 	_dev00[9] = vid >> 8;
    199 	_dev00[10] = pid;
    200 	_dev00[11] = pid >> 8;
    201 
    202 	if (mfg) {
    203 		int i;
    204 		for (i = 0; mfg[i] != 0 && i < ((sizeof(mfg_string) / 2) - 1); i++) {
    205 			mfg_string[i+1] = mfg[i];
    206 		}
    207 		mfg_string[0] = (DSC_STRING << 8) | ((i * 2) + 2);
    208 
    209 		_dev00[14] = 1;
    210 	}
    211 	if (prod) {
    212 		int i;
    213 		for (i = 0; prod[i] != 0 && i < ((sizeof(prod_string) / 2) - 1); i++) {
    214 			prod_string[i+1] = prod[i];
    215 		}
    216 		prod_string[0] = (DSC_STRING << 8) | ((i * 2) + 2);
    217 
    218 		_dev00[15] = 2;
    219 	}
    220 
    221 	/* SYSCLK to USB REG domain */
    222 	writel(readl(SYS_CLK_CTRL) | SYS_CLK_USB_REG | SYS_CLK_USBSRAM, SYS_CLK_CTRL);
    223 
    224 	writel(0, USB_DEVCMDSTAT);
    225 
    226 	/* power on USB PHY and USB PLL */
    227 	writel(readl(0x40048238) & (~(1 << 10)), 0x40048238);
    228 	writel(readl(0x40048238) & (~(1 << 8)), 0x40048238);
    229 
    230 	/* wait for power */
    231 	for (n = 0; n < 10000; n++) asm("nop");
    232 
    233 	usb_ep_list = usb_sram_alloc(0x50, 256);
    234 	usb_setup_buf = usb_sram_alloc(9, 64);
    235 
    236 	usb_setup_ep(&usb_ep_data[0], 0x0, 64, 64, 64);
    237 	usb_setup_ep(&usb_ep_data[1], 0x1, 128, 64, 64);
    238 
    239 	for (n = 0; n < 4; n++)
    240 		usb_ep_list[n] = 0;
    241 	for (n = 4; n < 20; n++)
    242 		usb_ep_list[n] = USB_EP_LIST_DISABLED;
    243 	for (n = 0; n < 9; n++)
    244 		usb_setup_buf[n] = 0;
    245 
    246 	usb_ep_list[EP_LIST_SETUP] = USB_EP_LIST_BUF_ADDR(usb_setup_buf);
    247 	writel((unsigned)usb_ep_list, USB_EPLISTSTART);
    248 	writel(USB_SRAM, USB_DATABUFSTART);
    249 
    250 
    251 	writel(0, USB_INTROUTING);
    252 	writel(USB_DEVCMDSTAT_DEV_ADDR(0) |
    253 	       USB_DEVCMDSTAT_DEV_EN |
    254 	       USB_DEVCMDSTAT_DCON |
    255 	       USB_DEVCMDSTAT_DSUS,
    256 	       USB_DEVCMDSTAT);
    257 
    258 	writel(USB_INT_DEV_INT |
    259 	       USB_INT_EP0OUT | USB_INT_EP0IN,
    260 	       USB_INTEN);
    261 }
    262 
    263 static void usb_send_in(struct usb_ep *ep)
    264 {
    265 //	unsigned ep_out_cmd = usb_ep_list[ep->addr * 4];
    266 	unsigned ep_cmd = usb_ep_list[ep->addr * 4 + 2];
    267 	ep_cmd = USB_EP_LIST_BUF_ADDR(ep->in_buf + ep->in_pos) |
    268 		USB_EP_LIST_BUF_SIZE(min(ep->in_len, ep->in_max_packet)) |
    269 		USB_EP_LIST_ACTIVE;
    270 
    271 //	if (ep->in_len >= ep->in_max_packet)
    272 //		ep_cmd |= USB_EP_LIST_STALL;
    273 //	ep_out_cmd = clr_set_bits(ep_out_cmd, USB_EP_LIST_ACTIVE, USB_EP_LIST_STALL);
    274 //	usb_ep_list[ep->addr * 4] = ep_out_cmd;
    275 	usb_ep_list[ep->addr * 4 + 2] = ep_cmd;
    276 
    277 	/* clear error code */
    278 	writel(0x0, USB_INFO);
    279 
    280 //	if (len)
    281 //		clr_set_reg(USB_DEVCMDSTAT, USB_DEVCMDSTAT_INTONNAK_CO, USB_DEVCMDSTAT_INTONNAK_CI);
    282 }
    283 
    284 static void usb_send_zlp(struct usb_ep *ep)
    285 {
    286 	ep->in_pos = 0;
    287 	ep->in_len = 0;
    288 	usb_send_in(ep);
    289 }
    290 
    291 static void usb_nak(struct usb_ep *ep)
    292 {
    293 	unsigned ep_out_cmd = usb_ep_list[ep->addr * 4];
    294 	unsigned ep_in_cmd = usb_ep_list[ep->addr * 4 + 2];
    295 
    296 	ep_out_cmd = clr_set_bits(ep_out_cmd, USB_EP_LIST_ACTIVE, USB_EP_LIST_STALL);
    297 	ep_in_cmd = clr_set_bits(ep_in_cmd, USB_EP_LIST_ACTIVE, USB_EP_LIST_STALL);
    298 
    299 	usb_ep_list[ep->addr * 4 + 2] = ep_in_cmd;
    300 	usb_ep_list[ep->addr * 4] = ep_out_cmd;
    301 }
    302 
    303 static int usb_ep_write(struct usb_ep *ep, const void *data, int len)
    304 {
    305 	if (len > ep->in_size)
    306 		return -EFAIL;
    307 
    308 	if (ep->in_len >= 0)
    309 		return -EBUSY;
    310 
    311 	memcpy(ep->in_buf, data, len);
    312 	ep->in_len = len;
    313 	ep->in_pos = 0;
    314 	usb_send_in(ep);
    315 
    316 	return 0;
    317 }
    318 
    319 static void usb_send_desc(const void *desc, int len)
    320 {
    321 	if (usb_ep_data[0].in_size < len) {
    322 		usb_debug("descriptor size (%x) larger than in buffer (%x)\n",
    323 		       len, usb_ep_data[0].in_size);
    324 		usb_nak(&usb_ep_data[0]);
    325 		return;
    326 	}
    327 	usb_ep_write(&usb_ep_data[0], desc, len);
    328 }
    329 
    330 
    331 static void usb_handle_get_desc(struct usb_setup_req *req)
    332 {
    333 	switch (req->wValue) {
    334 	case USB_DESC_VALUE(USB_DESC_DEVICE, 0):
    335 		usb_send_desc(_dev00, min(sizeof(_dev00),req->wLength));
    336 		break;
    337 
    338 	case USB_DESC_VALUE(USB_DESC_CONFIG, 0):
    339 		usb_send_desc(_cfg00, min(sizeof(_cfg00),req->wLength));
    340 		break;
    341 
    342 	case USB_DESC_VALUE(USB_DESC_STRING, 0):
    343 		usb_send_desc(lang_id, min(sizeof(lang_id),req->wLength));
    344 		break;
    345 
    346 	case USB_DESC_VALUE(USB_DESC_STRING, 1):
    347 		usb_send_desc(mfg_string, min(sizeof(mfg_string),req->wLength));
    348 		break;
    349 
    350 	case USB_DESC_VALUE(USB_DESC_STRING, 2):
    351 		usb_send_desc(prod_string, min(sizeof(prod_string),req->wLength));
    352 		break;
    353 
    354 	default:
    355 		usb_debug("unknown desc: %h\n", req->wValue);
    356 
    357 		usb_nak(&usb_ep_data[0]);
    358 		break;
    359 	}
    360 }
    361 
    362 static void usb_config_ep(struct usb_ep *ep)
    363 {
    364 	/* out buf 0 */
    365 //	usb_ep_list[ep->addr * 4] = USB_EP_LIST_TR;
    366 	usb_ep_list[ep->addr * 4] =  USB_EP_LIST_BUF_ADDR(ep->out_buf) |
    367 		USB_EP_LIST_BUF_SIZE(ep->out_size) |
    368 		USB_EP_LIST_ACTIVE | /* USB_EP_LIST_STALL | */ USB_EP_LIST_TR;
    369 
    370 	/* in buf 0 */
    371 	usb_ep_list[ep->addr * 4 + 2] =  USB_EP_LIST_TR; // USB_EP_LIST_STALL;
    372 
    373 	clr_set_reg(USB_INTEN, 0, 0x3 << (ep->addr * 2));
    374 }
    375 
    376 static void usb_handle_set_config(unsigned config)
    377 {
    378         usb_debug("set_config(%d)\n", config);
    379 	if (config != 1) {
    380 		usb_nak(&usb_ep_data[0]);
    381 		return;
    382 	}
    383 	usb_config_ep(&usb_ep_data[1]);
    384 //	clr_set_reg(USB_DEVCMDSTAT, 0, USB_DEVCMDSTAT_INTONNAK_AI);
    385 
    386 	usb_send_zlp(&usb_ep_data[0]);
    387 	usb_state = USB_STATE_ONLINE;
    388 	if (usb_online_cb)
    389 		usb_online_cb(1);
    390         printx("state = %d\n", usb_state);
    391 }
    392 static void usb_handle_setup_req(struct usb_setup_req *req)
    393 {
    394 	switch (req->bRequest) {
    395 	case USB_REQ_GET_DESCRIPTOR:
    396 		usb_handle_get_desc(req);
    397 		break;
    398 	case USB_REQ_SET_ADDRESS:
    399 		clr_set_reg(USB_DEVCMDSTAT, USB_DEVCMDSTAT_DEV_ADDR(~0),
    400 			    USB_DEVCMDSTAT_DEV_ADDR(req->wValue));
    401 		usb_send_zlp(&usb_ep_data[0]);
    402 		break;
    403 	case USB_REQ_GET_CONFIGURATION: {
    404                 u8 config = usb_state == USB_STATE_ONLINE;
    405                 usb_debug("get_config(%d)\n", config);
    406                 usb_ep_write(&usb_ep_data[0], &config, 1);
    407                 break;
    408         }
    409 
    410 	case USB_REQ_SET_CONFIGURATION:
    411 		usb_handle_set_config(req->wValue);
    412 		break;
    413 
    414 	default:
    415 		usb_debug("unknown setup req:\n");
    416 		usb_debug("  bmRequestType: %b\n", req->bmRequestType);
    417 		usb_debug("     dir: %b\n", req->t.dir);
    418 		usb_debug("     type: %b\n", req->t.type);
    419 		usb_debug("     rcpt: %b\n", req->t.rcpt);
    420 		usb_debug("  bRequest:      %b\n", req->bRequest);
    421 		usb_debug("  wValue:        %h\n", req->wValue);
    422 		usb_debug("  wIndex:        %h\n", req->wIndex);
    423 		usb_debug("  wLength:       %h\n", req->wLength);
    424 
    425 		usb_nak(&usb_ep_data[0]);
    426 		break;
    427 	}
    428 }
    429 
    430 void usb_handle_dev_int(void)
    431 {
    432 	unsigned cmdstat = readl(USB_DEVCMDSTAT);
    433 	int n;
    434 
    435 	if (cmdstat & USB_DEVCMDSTAT_DCON_C) {
    436 	}
    437 	if (cmdstat & USB_DEVCMDSTAT_DSUS_C) {
    438 	}
    439 	if (cmdstat & USB_DEVCMDSTAT_DRES_C) {
    440 		for (n = 4; n < 20; n++)
    441 			usb_ep_list[n] = USB_EP_LIST_DISABLED;
    442 	}
    443 	writel(cmdstat, USB_DEVCMDSTAT);
    444 	writel(USB_INT_DEV_INT, USB_INTSTAT);
    445 }
    446 
    447 void usb_handle_ep0out(void)
    448 {
    449 	writel(USB_INT_EP0OUT, USB_INTSTAT);
    450 	unsigned cmdstat = readl(USB_DEVCMDSTAT);
    451 
    452 	if (cmdstat & USB_DEVCMDSTAT_SETUP) {
    453 		struct usb_setup_req *req;
    454 		usb_ep_list[EP_LIST_EP0_OUT] &= ~(USB_EP_LIST_ACTIVE | USB_EP_LIST_STALL);
    455 		usb_ep_list[EP_LIST_EP0_IN] &= ~(USB_EP_LIST_ACTIVE | USB_EP_LIST_STALL);
    456 
    457 		writel(USB_INT_EP0IN, USB_INTSTAT);
    458 		writel(cmdstat, USB_DEVCMDSTAT);
    459 
    460 		req = (struct usb_setup_req *)usb_setup_buf;
    461 		usb_handle_setup_req(req);
    462 	} else {
    463 		usb_ep_list[EP_LIST_EP0_OUT] &= ~(USB_EP_LIST_STALL);
    464 
    465 	}
    466 }
    467 
    468 void usb_handle_ep0in(void)
    469 {
    470 	writel(USB_INT_EP0IN, USB_INTSTAT);
    471 	unsigned ep_in_cmd = usb_ep_list[EP_LIST_EP0_IN];
    472 
    473 	if (usb_ep_data[0].in_len >= 0) {
    474 		unsigned ep_out_cmd = usb_ep_list[EP_LIST_EP0_OUT];
    475 
    476 		ep_out_cmd = USB_EP_LIST_BUF_ADDR(usb_ep_data[0].out_buf) |
    477 			USB_EP_LIST_BUF_SIZE(usb_ep_data[0].out_size) |
    478 			USB_EP_LIST_STALL | USB_EP_LIST_ACTIVE ;
    479 
    480 
    481 		usb_ep_list[EP_LIST_EP0_OUT] = ep_out_cmd;
    482 	}
    483 
    484 	ep_in_cmd = clr_set_bits(ep_in_cmd, USB_EP_LIST_ACTIVE, USB_EP_LIST_STALL);
    485 
    486 	usb_ep_list[EP_LIST_EP0_IN] = ep_in_cmd;
    487 	if (usb_ep_data[0].in_len >= 0) {
    488 		writel(USB_INT_EP0OUT, USB_INTSTAT);
    489 		usb_ep_data[0].in_len = -1;
    490 	}
    491 }
    492 
    493 static void usb_handle_in(struct usb_ep *ep, unsigned int_mask)
    494 {
    495 	int pos = ep->in_pos;
    496 	pos -= ep->in_max_packet;
    497 //	printx("ep%b in %x %b\n", ep->addr, usb_ep_list[ep->addr * 4 + 2],
    498 //	       USB_INFO_ERR_CODE(readl(USB_INFO)));
    499 
    500 	writel(int_mask, USB_INTSTAT);
    501 
    502 	if (pos < 0) {
    503 		ep->in_pos = 0;
    504 		ep->in_len = -1;
    505 		if (ep->addr == 0x01 && usb_ep1_tx_empty_cb)
    506 			usb_ep1_tx_empty_cb();
    507 		if (ep->addr == 0x02 && usb_ep2_tx_empty_cb)
    508 			usb_ep2_tx_empty_cb();
    509 	} else if (pos == 0) {
    510 		ep->in_pos = 0;
    511 		usb_send_zlp(ep);
    512 	} else {
    513 		ep->in_pos = pos;
    514 		usb_send_in(ep);
    515 	}
    516 }
    517 
    518 static void usb_handle_out(struct usb_ep *ep, unsigned int_mask)
    519 {
    520 	unsigned cmd = usb_ep_list[ep->addr * 4];
    521 
    522 //	usb_debug("usb_out ep%b %x\n", ep->addr, usb_ep_list[ep->addr * 4]);
    523 	ep->out_len = ep->out_size - USB_EP_LIST_GET_BUF_SIZE(cmd);
    524 	ep->out_pos = 0;
    525 
    526 	if (usb_ep1_rx_full_cb)
    527 		usb_ep1_rx_full_cb();
    528 
    529 	writel(int_mask, USB_INTSTAT);
    530 }
    531 
    532 static int usb_ep_read(struct usb_ep *ep, void *data, int max)
    533 {
    534 	int len = min(ep->out_len - ep->out_pos, max);
    535 
    536 	if (len == 0)
    537 		return -EBUSY;
    538 
    539 	memcpy(data, ep->out_buf + ep->out_pos, len);
    540 
    541 	/* XXX: not rentrant with the irq handler!*/
    542 	ep->out_pos += len;
    543 
    544 	if (ep->out_pos == ep->out_len) {
    545 		usb_ep_list[ep->addr * 4] =  USB_EP_LIST_BUF_ADDR(ep->out_buf) |
    546 			USB_EP_LIST_BUF_SIZE(ep->out_size) |
    547 			USB_EP_LIST_ACTIVE;// | USB_EP_LIST_STALL;
    548 	}
    549 
    550 	return len;
    551 }
    552 
    553 
    554 void handle_irq_usb_irq(void) {
    555 	unsigned status = readl(USB_INTSTAT);
    556 
    557         status &= readl(USB_INTEN);
    558 
    559 	if (status & USB_INT_FRAME_INT) {
    560 		usb_frames++;
    561 		writel(USB_INT_FRAME_INT, USB_INTEN);
    562 	}
    563 
    564 
    565 	if (status & USB_INT_DEV_INT)
    566 		usb_handle_dev_int();
    567 	if (status & USB_INT_EP0OUT)
    568 		usb_handle_ep0out();
    569 	if (status & USB_INT_EP0IN)
    570 		usb_handle_ep0in();
    571 	if (status & USB_INT_EP1OUT)
    572 		usb_handle_out(&usb_ep_data[1], USB_INT_EP1OUT);
    573 	if (status & USB_INT_EP1IN)
    574 		usb_handle_in(&usb_ep_data[1], USB_INT_EP1IN);
    575 
    576 
    577 }
    578 
    579 void usb_handle_irq(void) {
    580 	handle_irq_usb_irq();
    581 }
    582 
    583 
    584 /* USB API */
    585 int usb_ep1_read(void *data, int max)
    586 {
    587 	return usb_ep_read(&usb_ep_data[1], data, max);
    588 }
    589 
    590 
    591 int usb_ep1_write(void *data, int len)
    592 {
    593 	return usb_ep_write(&usb_ep_data[1], data, len);
    594 }
    595 
    596 int usb_ep2_read(void *data, int max)
    597 {
    598 	return -1; // XXX real error
    599 }
    600 
    601 int usb_ep2_write(void *data, int len)
    602 {
    603 	return -1; // XXX real error
    604 }
    605 
    606 void usb_mask_ep1_rx_full(void)
    607 {
    608 
    609 }
    610 
    611 void usb_unmask_ep1_rx_full(void)
    612 {
    613 
    614 }
    615 
    616 void usb_mask_ep1_tx_empty(void)
    617 {
    618 
    619 }
    620 
    621 void usb_unmask_ep1_tx_empty(void)
    622 {
    623 
    624 }
    625 
    626 void usb_mask_ep2_rx_full(void)
    627 {
    628 
    629 }
    630 
    631 void usb_unmask_ep2_rx_full(void)
    632 {
    633 
    634 }
    635 
    636 void usb_mask_ep2_tx_empty(void)
    637 {
    638 
    639 }
    640 
    641 void usb_unmask_ep2_tx_empty(void)
    642 {
    643 
    644 }
    645 
    646 
    647 int usb_xmit(void *_data, int len) {
    648 	int r, tx, xfer;
    649 	u8 *data;
    650 
    651 	data = _data;
    652 	tx = 0;
    653 
    654 	while (len > 0) {
    655 		xfer = (len > 64) ? 64 : len;
    656 		r = usb_ep1_write(data, xfer);
    657 		if (r < 0) {
    658 			if (r == -EBUSY) {
    659 				usb_handle_irq();
    660 				continue;
    661 			}
    662 			return r;
    663 		}
    664 		tx += xfer;
    665 		len -= xfer;
    666 		data += xfer;
    667 	}
    668 	return tx;
    669 }
    670 
    671 int usb_recv_timeout(void *_data, int count, unsigned timeout) {
    672 	int r, rx;
    673 	u8 *data;
    674 
    675 	data = _data;
    676 	rx = 0;
    677 	usb_frames = 0;
    678 
    679 	/* if offline, wait for us to go online */
    680 	while (usb_state == USB_STATE_OFFLINE)
    681 		usb_handle_irq();
    682 
    683 	while (count > 0) {
    684 		r = usb_ep1_read(data, (count > 64) ? 64 : count);
    685 		if (r >= 0) {
    686 			rx += r;
    687 			data += r;
    688 			count -= r;
    689 			/* terminate on short packet */
    690 			if (r != 64)
    691 				break;
    692 		} else if (r == -EBUSY) {
    693 			if (timeout && (usb_frames > timeout))
    694 				return -ETIMEOUT;
    695 			usb_handle_irq();
    696 		} else {
    697 			return r;
    698 		}
    699 	}
    700 	return rx;
    701 }
    702 
    703 int usb_recv(void *_data, int count) {
    704 	return usb_recv_timeout(_data, count, 0);
    705 }
    706 
    707 int usb_online(void) {
    708 	return usb_state == USB_STATE_ONLINE;
    709 }
    710 
    711 void usb_stop(void) {
    712 	/* disable dev */
    713 	writel(0, USB_DEVCMDSTAT);
    714 
    715 	/* power off USB PHY and USB PLL */
    716 	clr_set_reg(0x40048238, (1 << 10) | (1 << 8), 0);
    717 
    718 	/* turn of SYSCLK to USB REG domain */
    719 	clr_set_reg(SYS_CLK_CTRL, SYS_CLK_USB_REG | SYS_CLK_USBSRAM, 0);
    720 }