Project

General

Profile

Download (2.54 KB) Statistics
| Branch: | Tag: | Revision:
1
/* OpenPCD USB handler - handle incoming USB requests on OUT pipe
2
 * (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
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
 */
19

    
20
#include <sys/types.h>
21
#include <errno.h>
22
#include <string.h>
23

    
24
#include <openpcd.h>
25

    
26
#include <os/pcd_enumerate.h>
27
#include <os/usb_handler.h>
28
#include <os/req_ctx.h>
29
#include <os/led.h>
30
#include <os/dbgu.h>
31

    
32
#include "../openpcd.h"
33

    
34
static usb_cmd_fn *cmd_hdlrs[16];
35

    
36
int usb_hdlr_register(usb_cmd_fn *hdlr, uint8_t class)
37
{
38
	cmd_hdlrs[class] = hdlr;
39
	return 0;
40
}
41

    
42
void usb_hdlr_unregister(uint8_t class)
43
{
44
	cmd_hdlrs[class] = NULL;
45
}
46

    
47
static int usb_in(struct req_ctx *rctx)
48
{
49
	struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data;
50
	usb_cmd_fn *hdlr;
51
	int ret;
52

    
53
/*	DEBUGP("usb_in(cls=%d) ", OPENPCD_CMD_CLS(poh->cmd));*/
54

    
55
	if (rctx->tot_len < sizeof(*poh))
56
		return -EINVAL;
57
	
58
	hdlr = cmd_hdlrs[OPENPCD_CMD_CLS(poh->cmd)];
59
	if (!hdlr) {
60
		DEBUGPCR("no handler for this class ");
61
		ret = USB_ERR(USB_ERR_CMD_UNKNOWN);
62
	} else
63
		ret = (hdlr)(rctx);
64
	
65
	if (ret & USB_RET_ERR) {
66
		poh->val = ret & 0xff;
67
		poh->flags = OPENPCD_FLAG_ERROR;
68
	}
69
	if (ret & USB_RET_RESPOND) { 
70
		req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING);
71
		udp_refill_ep(2);
72
	}
73

    
74
/*	DEBUGPCR("");*/
75
	return (ret & USB_RET_ERR) ? 1 : 0;
76
}
77

    
78
/* Process all pending request contexts that want to Tx on either
79
 * IN or INTERRUPT endpoint */
80
void usb_out_process(void)
81
{
82
	/* interrupts are likely to be more urgent than bulk */
83
	udp_refill_ep(3);
84
	udp_refill_ep(2);
85
}
86

    
87
/* process incoming USB packets (OUT pipe) that have already been 
88
 * put into request contexts by the UDP IRQ handler */
89
void usb_in_process(void)
90
{
91
	struct req_ctx *rctx;
92

    
93
	while (rctx = req_ctx_find_get(0, RCTX_STATE_UDP_RCV_DONE,
94
				       RCTX_STATE_MAIN_PROCESSING)) {
95
/*		DEBUGPCRF("found used ctx %u: len=%u", 
96
			  req_ctx_num(rctx), rctx->tot_len);*/
97
		usb_in(rctx);
98
	}
99
	udp_unthrottle();
100
}
101

    
(34-34/40)
Add picture from clipboard (Maximum size: 48.8 MB)