annotate packages/io/usb/slave/current/src/usbs.c @ 1777:c16341b1bac6 default tip

* Added execute permissions to files missed in conversion from CVS
author alexs
date Mon, 12 Oct 2009 02:26:09 +0100
parents d2c90368aeef
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
151
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
1 //==========================================================================
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
2 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
3 // usbs.c
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
4 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
5 // Generic USB slave-side support
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
6 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
7 //==========================================================================
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
8 //####ECOSGPLCOPYRIGHTBEGIN####
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
9 // -------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
10 // This file is part of eCos, the Embedded Configurable Operating System.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
12 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
13 // eCos is free software; you can redistribute it and/or modify it under
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
14 // the terms of the GNU General Public License as published by the Free
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
15 // Software Foundation; either version 2 or (at your option) any later version.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
16 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
20 // for more details.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
21 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
22 // You should have received a copy of the GNU General Public License along
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
25 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
26 // As a special exception, if other files instantiate templates or use macros
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
27 // or inline functions from this file, or you compile this file and link it
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
28 // with other works to produce a work based on this file, this file does not
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
29 // by itself cause the resulting work to be covered by the GNU General Public
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
30 // License. However the source code for this file must still be made available
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
31 // in accordance with section (3) of the GNU General Public License.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
32 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
33 // This exception does not invalidate any other reasons why a work based on
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
34 // this file might be covered by the GNU General Public License.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
35 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
210
d2c90368aeef Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents: 208
diff changeset
37 // at http://sources.redhat.com/ecos/ecos-license/
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
38 // -------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 184
diff changeset
39 //####ECOSGPLCOPYRIGHTEND####
151
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
40 //==========================================================================
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
41 //#####DESCRIPTIONBEGIN####
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
42 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
43 // Author(s): bartv
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
44 // Contributors: bartv
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
45 // Date: 2000-10-04
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
46 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
47 //####DESCRIPTIONEND####
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
48 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
49 //==========================================================================
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
50
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
51 #include <pkgconf/system.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
52 #include <cyg/infra/cyg_type.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
53 #include <cyg/infra/cyg_ass.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
54 #include <cyg/infra/cyg_trac.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
55 #include <cyg/infra/diag.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
56 #include <cyg/io/usb/usbs.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
57 #include <cyg/hal/drv_api.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
58
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
59 // ----------------------------------------------------------------------------
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
60 // Devtab entry support. This code can be compiled with no overheads as
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
61 // long as the necessary support package is in place.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
62 #ifdef CYGPKG_IO
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
63 # include <cyg/io/io.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
64 # include <cyg/io/devtab.h>
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
65 // ----------------------------------------------------------------------------
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
66 // read()/write() functions applied to USB endpoints. These just
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
67 // indirect via the usbs_endpoint structures and wait for the
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
68 // callback to happen.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
69
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
70 typedef struct usbs_callback_data {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
71 bool completed;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
72 int result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
73 cyg_drv_mutex_t lock;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
74 cyg_drv_cond_t signal;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
75 } usbs_callback_data;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
76
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
77 static void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
78 usbs_devtab_callback(void* arg, int result)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
79 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
80 usbs_callback_data* callback_data = (usbs_callback_data*) arg;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
81 callback_data->result = result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
82 callback_data->completed = true;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
83 cyg_drv_cond_signal(&(callback_data->signal));
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
84 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
85
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
86 Cyg_ErrNo
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
87 usbs_devtab_cwrite(cyg_io_handle_t handle, const void* buf, cyg_uint32* size)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
88 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
89 usbs_callback_data wait;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
90 cyg_devtab_entry_t* devtab_entry;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
91 usbs_tx_endpoint* endpoint;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
92 int result = ENOERR;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
93
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
94 CYG_REPORT_FUNCTION();
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
95
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
96 wait.completed = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
97 cyg_drv_mutex_init(&wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
98 cyg_drv_cond_init(&wait.signal, &wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
99
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
100 devtab_entry = (cyg_devtab_entry_t*) handle;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
101 CYG_CHECK_DATA_PTR( devtab_entry, "A valid endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
102 endpoint = (usbs_tx_endpoint*) devtab_entry->priv;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
103
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
104 CYG_CHECK_DATA_PTR( endpoint, "The handle must correspond to a USB endpoint");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
105 CYG_CHECK_FUNC_PTR( endpoint->start_tx_fn, "The endpoint must have a start_tx function");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
106
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
107 endpoint->buffer = (unsigned char*) buf;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
108 endpoint->buffer_size = (int) *size;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
109 endpoint->complete_fn = &usbs_devtab_callback;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
110 endpoint->complete_data = (void*) &wait;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
111 (*endpoint->start_tx_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
112
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
113 cyg_drv_mutex_lock(&wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
114 while (!wait.completed) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
115 cyg_drv_cond_wait(&wait.signal);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
116 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
117 cyg_drv_mutex_unlock(&wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
118 if (wait.result < 0) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
119 result = wait.result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
120 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
121 *size = wait.result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
122 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
123
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
124 cyg_drv_cond_destroy(&wait.signal);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
125 cyg_drv_mutex_destroy(&wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
126
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
127 CYG_REPORT_RETURN();
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
128 return result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
129 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
130
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
131 Cyg_ErrNo
165
d63db767121d Merge from eCos master repository on 2001-06-29-06:43:03-BST
jlarmour
parents: 151
diff changeset
132 usbs_devtab_cread(cyg_io_handle_t handle, void* buf, cyg_uint32* size)
151
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
133 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
134 usbs_callback_data wait;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
135 cyg_devtab_entry_t* devtab_entry;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
136 usbs_rx_endpoint* endpoint;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
137 int result = ENOERR;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
138
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
139 CYG_REPORT_FUNCTION();
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
140
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
141 wait.completed = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
142 cyg_drv_mutex_init(&wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
143 cyg_drv_cond_init(&wait.signal, &wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
144
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
145 devtab_entry = (cyg_devtab_entry_t*) handle;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
146 CYG_CHECK_DATA_PTR( devtab_entry, "A valid endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
147 endpoint = (usbs_rx_endpoint*) devtab_entry->priv;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
148
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
149 CYG_CHECK_DATA_PTR( endpoint, "The handle must correspond to a USB endpoint");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
150 CYG_CHECK_FUNC_PTR( endpoint->start_rx_fn, "The endpoint must have a start_rx function");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
151
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
152 endpoint->buffer = (unsigned char*) buf;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
153 endpoint->buffer_size = (int) *size;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
154 endpoint->complete_fn = &usbs_devtab_callback;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
155 endpoint->complete_data = (void*) &wait;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
156 (*endpoint->start_rx_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
157 cyg_drv_mutex_lock(&wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
158 while (!wait.completed) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
159 cyg_drv_cond_wait(&wait.signal);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
160 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
161 cyg_drv_mutex_unlock(&wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
162 if (wait.result < 0) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
163 result = wait.result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
164 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
165 *size = wait.result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
166 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
167
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
168 cyg_drv_cond_destroy(&wait.signal);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
169 cyg_drv_mutex_destroy(&wait.lock);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
170
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
171 CYG_REPORT_RETURN();
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
172 return result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
173 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
174
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
175 // ----------------------------------------------------------------------------
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
176 // More devtab functions, this time related to ioctl() style operations.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
177 Cyg_ErrNo
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
178 usbs_devtab_get_config(cyg_io_handle_t handle, cyg_uint32 code, void* buf, cyg_uint32* size)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
179 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
180 return -EINVAL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
181 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
182
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
183 Cyg_ErrNo
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
184 usbs_devtab_set_config(cyg_io_handle_t handle, cyg_uint32 code, const void* buf, cyg_uint32* size)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
185 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
186 return -EINVAL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
187 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
188
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
189 #endif // CYGPKG_IO
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
190
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
191 // ----------------------------------------------------------------------------
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
192 // USB-specific functions that are useful for applications/packages which
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
193 // do not want to use the devtab interface. These may get called in DSR
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
194 // context.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
195
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
196 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
197 usbs_start_rx(usbs_rx_endpoint* endpoint)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
198 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
199 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
200 CYG_CHECK_FUNC_PTR( endpoint->start_rx_fn, "The USB endpoint must support receive operations");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
201 (*endpoint->start_rx_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
202 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
203
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
204 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
205 usbs_start_rx_buffer(usbs_rx_endpoint* endpoint,
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
206 unsigned char* buf, int size,
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
207 void (*callback_fn)(void *, int), void* callback_arg)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
208 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
209 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
210 CYG_CHECK_FUNC_PTR( endpoint->start_rx_fn, "The USB endpoint must support receive operations");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
211
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
212 endpoint->buffer = buf;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
213 endpoint->buffer_size = size;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
214 endpoint->complete_fn = callback_fn;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
215 endpoint->complete_data = callback_arg;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
216 (*endpoint->start_rx_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
217 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
218
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
219 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
220 usbs_start_tx(usbs_tx_endpoint* endpoint)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
221 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
222 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
223 CYG_CHECK_FUNC_PTR( endpoint->start_tx_fn, "The USB endpoint must support receive operations");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
224 (*endpoint->start_tx_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
225 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
226
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
227 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
228 usbs_start_tx_buffer(usbs_tx_endpoint* endpoint,
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
229 const unsigned char* buf, int size,
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
230 void (*callback_fn)(void*, int), void *callback_arg)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
231 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
232 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
233 CYG_CHECK_FUNC_PTR( endpoint->start_tx_fn, "The USB endpoint must support receive operations");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
234
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
235 endpoint->buffer = buf;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
236 endpoint->buffer_size = size;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
237 endpoint->complete_fn = callback_fn;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
238 endpoint->complete_data = callback_arg;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
239 (*endpoint->start_tx_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
240 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
241
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
242 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
243 usbs_start(usbs_control_endpoint* endpoint)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
244 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
245 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
246 CYG_CHECK_FUNC_PTR( endpoint->start_fn, "The USB endpoint should have a start function");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
247
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
248 (*endpoint->start_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
249 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
250
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
251 cyg_bool
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
252 usbs_rx_endpoint_halted(usbs_rx_endpoint* endpoint)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
253 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
254 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
255 return endpoint->halted;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
256 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
257
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
258 cyg_bool
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
259 usbs_tx_endpoint_halted(usbs_tx_endpoint* endpoint)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
260 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
261 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
262 return endpoint->halted;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
263 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
264
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
265 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
266 usbs_set_rx_endpoint_halted(usbs_rx_endpoint* endpoint, cyg_bool halted)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
267 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
268 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
269 CYG_CHECK_FUNC_PTR( endpoint->set_halted_fn, "The USB endpoint should have a set-halted function");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
270 (*endpoint->set_halted_fn)(endpoint, halted);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
271 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
272
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
273 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
274 usbs_set_tx_endpoint_halted(usbs_tx_endpoint* endpoint, cyg_bool halted)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
275 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
276 CYG_CHECK_DATA_PTR( endpoint, "A valid USB endpoint must be supplied");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
277 CYG_CHECK_FUNC_PTR( endpoint->set_halted_fn, "The USB endpoint should have a set-halted function");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
278 (*endpoint->set_halted_fn)(endpoint, halted);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
279 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
280
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
281 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
282 usbs_start_rx_endpoint_wait(usbs_rx_endpoint* endpoint, void (*callback_fn)(void*, int), void* callback_data)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
283 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
284 endpoint->buffer = (unsigned char*) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
285 endpoint->buffer_size = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
286 endpoint->complete_fn = callback_fn;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
287 endpoint->complete_data = callback_data;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
288 (*endpoint->start_rx_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
289 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
290
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
291 void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
292 usbs_start_tx_endpoint_wait(usbs_tx_endpoint* endpoint, void (*callback_fn)(void*, int), void* callback_data)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
293 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
294 endpoint->buffer = (unsigned char*) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
295 endpoint->buffer_size = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
296 endpoint->complete_fn = callback_fn;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
297 endpoint->complete_data = callback_data;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
298 (*endpoint->start_tx_fn)(endpoint);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
299 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
300
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
301
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
302 // ----------------------------------------------------------------------------
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
303 // Handling of standard control messages. This will be invoked by
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
304 // a USB device driver, usually at DSR level, to process any control
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
305 // messages that cannot be handled by the hardware itself and that
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
306 // have also not been handled by the application-specific handler
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
307 // (if any).
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
308 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
309 // Because this function can run at DSR level performance is important.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
310 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
311 // The various standard control messages are affected as follows:
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
312 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
313 // clear-feature: nothing can be done here about device requests to
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
314 // disable remote-wakeup or about endpoint halt requests. It appears
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
315 // to be legal to clear no features on an interface.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
316 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
317 // get-configuration: if the device is not configured a single byte 0
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
318 // should be returned. Otherwise this code assumes only one configuration
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
319 // is supported and its id can be extracted from the enumeration data.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
320 // For more complicated devices get-configuration has to be handled
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
321 // at a higher-level.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
322 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
323 // get-descriptor: this is the big one. It is used to obtain
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
324 // the enumeration data. An auxiliary refill function is needed.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
325 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
326 // get-interface: this can be used to identify the current variant
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
327 // for a given interface within a configuration. For simple devices
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
328 // there will be only interface, 0. For anything more complicated
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
329 // higher level code will have to take care of the request.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
330 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
331 // get-status. Much the same as clear-feature.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
332 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
333 // set-address. Must be handled at the device driver level.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
334 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
335 // set-configuration: a value of 0 is used to deconfigure the device,
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
336 // which can be handled here. Otherwise this code assumes that only
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
337 // a single configuration is supported and enables that. For anything
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
338 // more complicated higher-level code has to handle this request.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
339 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
340 // set-descriptor: used to update the enumeration data. This is not
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
341 // supported here, although higher-level code can choose to do so.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
342 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
343 // set-feature. See clear-feature and get-status.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
344 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
345 // set-interface. Variant interfaces are not supported by the
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
346 // base code so this request has to be handled at a higher level.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
347 //
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
348 // synch-frame. This is only relevant for isochronous transfers
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
349 // which are not yet supported, and anyway it is not clear what
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
350 // could be done about these requests here.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
351
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
352 // This refill function handles GET_DESCRIPTOR requests for a
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
353 // configuration. For details of the control_buffer usage see
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
354 // the relevant code in the main callback.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
355 static void
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
356 usbs_configuration_descriptor_refill(usbs_control_endpoint* endpoint)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
357 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
358 usb_devreq* req = (usb_devreq*) endpoint->control_buffer;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
359 int length = (req->length_hi << 8) | req->length_lo;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
360 int sent = (req->index_hi << 8) | req->index_lo;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
361 int current_interface = req->type;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
362 int last_interface = req->request;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
363 int current_endpoint = req->value_lo;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
364 int last_endpoint = req->value_hi;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
365 cyg_bool done = false;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
366
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
367 if (current_endpoint == last_endpoint) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
368 // The next transfer should be a single interface - unless we have already finished.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
369 if (current_interface == last_interface) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
370 done = true;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
371 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
372 endpoint->buffer = (unsigned char*) &(endpoint->enumeration_data->interfaces[current_interface]);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
373 if (USB_INTERFACE_DESCRIPTOR_LENGTH >= (length - sent)) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
374 endpoint->buffer_size = length - sent;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
375 done = true;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
376 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
377 endpoint->buffer_size = USB_INTERFACE_DESCRIPTOR_LENGTH;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
378 sent += USB_INTERFACE_DESCRIPTOR_LENGTH;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
379 // Note that an interface with zero endpoints is ok. We'll just move
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
380 // to the next interface in the next call.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
381 last_endpoint = current_endpoint +
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
382 endpoint->enumeration_data->interfaces[current_interface].number_endpoints;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
383 current_interface++;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
384 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
385 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
386 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
387 // The next transfer should be a single endpoint. The
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
388 // endpoints are actually contiguous array elements
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
389 // but may not be packed, so they have to be transferred
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
390 // one at a time.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
391 endpoint->buffer = (unsigned char*) &(endpoint->enumeration_data->endpoints[current_endpoint]);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
392 if ((sent + USB_ENDPOINT_DESCRIPTOR_LENGTH) >= length) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
393 endpoint->buffer_size = length - sent;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
394 done = true;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
395 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
396 endpoint->buffer_size = USB_ENDPOINT_DESCRIPTOR_LENGTH;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
397 current_endpoint ++;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
398 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
399 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
400
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
401 if (done) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
402 endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
403 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
404 req->type = (unsigned char) current_interface;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
405 req->value_lo = (unsigned char) current_endpoint;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
406 req->value_hi = (unsigned char) last_endpoint;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
407 req->index_hi = (unsigned char) (sent >> 8);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
408 req->index_lo = (unsigned char) (sent & 0x00FF);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
409 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
410 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
411
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
412 usbs_control_return
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
413 usbs_handle_standard_control(usbs_control_endpoint* endpoint)
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
414 {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
415 usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
416 usb_devreq* req = (usb_devreq*) endpoint->control_buffer;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
417 int length;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
418 int direction;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
419 int recipient;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
420
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
421 length = (req->length_hi << 8) | req->length_lo;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
422 direction = req->type & USB_DEVREQ_DIRECTION_MASK;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
423 recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
424
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
425 if (USB_DEVREQ_CLEAR_FEATURE == req->request) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
426
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
427 if (USB_DEVREQ_RECIPIENT_INTERFACE == recipient) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
428 // The host should expect no data back, the device must
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
429 // be configured, and there are no defined features to clear.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
430 if ((0 == length) &&
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
431 (USBS_STATE_CONFIGURED == (endpoint->state & USBS_STATE_MASK)) &&
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
432 (0 == req->value_lo)) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
433
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
434 int interface_id = req->index_lo;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
435 CYG_ASSERT( 1 == endpoint->enumeration_data->total_number_interfaces, \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
436 "Higher level code should have handled this request");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
437
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
438 if (interface_id == endpoint->enumeration_data->interfaces[0].interface_id) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
439 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
440 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
441 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
442 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
443
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
444 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
445 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
446 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
447 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
448
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
449 } else if (USB_DEVREQ_GET_CONFIGURATION == req->request) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
450
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
451 // Return a single byte 0 if the device is not currently
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
452 // configured. Otherwise assume a single configuration
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
453 // in the enumeration data and return its id.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
454 if ((1 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
455
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
456 if (USBS_STATE_CONFIGURED == (endpoint->state & USBS_STATE_MASK)) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
457 CYG_ASSERT( 1 == endpoint->enumeration_data->device.number_configurations, \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
458 "Higher level code should have handled this request");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
459 endpoint->control_buffer[0] = endpoint->enumeration_data->configurations[0].configuration_id;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
460 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
461 endpoint->control_buffer[0] = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
462 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
463 endpoint->buffer = endpoint->control_buffer;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
464 endpoint->buffer_size = 1;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
465 endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
466 endpoint->complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, cyg_bool)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
467 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
468
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
469 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
470 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
471 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
472
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
473 } else if (USB_DEVREQ_GET_DESCRIPTOR == req->request) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
474
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
475 // The descriptor type is in value_hi. The descriptor index
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
476 // is in value_lo.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
477 // The hsot must expect at least one byte of data.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
478 if ((0 == length) || (USB_DEVREQ_DIRECTION_IN != direction)) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
479
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
480 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
481
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
482 } else if (USB_DEVREQ_DESCRIPTOR_TYPE_DEVICE == req->value_hi) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
483
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
484 // The device descriptor is easy, it is a single field in the
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
485 // enumeration data.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
486 endpoint->buffer = (unsigned char*) &(endpoint->enumeration_data->device);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
487 endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
488 endpoint->complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, cyg_bool)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
489 if (length < USB_DEVICE_DESCRIPTOR_LENGTH) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
490 endpoint->buffer_size = length;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
491 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
492 endpoint->buffer_size = USB_DEVICE_DESCRIPTOR_LENGTH;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
493 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
494 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
495
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
496 } else if (USB_DEVREQ_DESCRIPTOR_TYPE_CONFIGURATION == req->value_hi) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
497
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
498 // This is where things get messy. We need to supply the
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
499 // specified configuration data, followed by some number of
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
500 // interfaces and endpoints. Plus there are length limits
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
501 // to consider. First check that the specified index is valid.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
502 if (req->value_lo >= endpoint->enumeration_data->device.number_configurations) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
503 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
504 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
505 // No such luck. OK, supplying the initial block is easy.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
506 endpoint->buffer = (unsigned char*) &(endpoint->enumeration_data->configurations[req->value_lo]);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
507 endpoint->complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, cyg_bool)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
508
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
509 // How much data was actually requested. If only the
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
510 // configuration itself is of interest then there is
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
511 // no need to worry about the rest.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
512 if (length <= USB_CONFIGURATION_DESCRIPTOR_LENGTH) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
513 endpoint->buffer_size = length;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
514 endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
515 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
516 int i, j;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
517 int start_interface;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
518 int start_endpoint;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
519 endpoint->buffer_size = USB_CONFIGURATION_DESCRIPTOR_LENGTH;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
520 endpoint->fill_buffer_fn = &usbs_configuration_descriptor_refill;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
521
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
522 // The descriptor refill_fn needs to know what next to transfer.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
523 // The desired interfaces and endpoints will be contiguous so
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
524 // we need to keep track of the following:
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
525 // 1) the current interface index being transferred.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
526 // 2) the last interface that should be transferred.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
527 // 3) the current endpoint index that should be transferred.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
528 // 4) the last endpoint index. This marks interface/endpoint transitions.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
529 // 5) how much has been transferred to date.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
530 // This information can be held in the control_buffer,
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
531 // with the length field being preserved.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
532 start_interface = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
533 start_endpoint = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
534 // For all configurations up to the desired one.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
535 for (i = 0; i < req->value_lo; i++) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
536 int config_interfaces = endpoint->enumeration_data->configurations[i].number_interfaces;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
537
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
538 // For all interfaces in this configuration.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
539 for (j = 0; j < config_interfaces; j++) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
540 // Add the number of endpoints in this interface to the current count.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
541 CYG_ASSERT( (j + start_interface) < endpoint->enumeration_data->total_number_interfaces, \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
542 "Valid interface count in enumeration data");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
543 start_endpoint += endpoint->enumeration_data->interfaces[j + start_interface].number_endpoints;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
544 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
545 // And update the index for the starting interface.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
546 start_interface += config_interfaces;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
547 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
548 CYG_ASSERT( start_interface < endpoint->enumeration_data->total_number_interfaces, \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
549 "Valid interface count in enumeration data");
184
022f1e506033 Merge from eCos master repository on 2001-10-02-17:59:22-BST
jlarmour
parents: 165
diff changeset
550 CYG_ASSERT( ((0 == endpoint->enumeration_data->total_number_endpoints) && (0 == start_endpoint)) || \
022f1e506033 Merge from eCos master repository on 2001-10-02-17:59:22-BST
jlarmour
parents: 165
diff changeset
551 (start_endpoint < endpoint->enumeration_data->total_number_endpoints), \
151
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
552 "Valid endpoint count in enumeration data");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
553
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
554 req->type = (unsigned char) start_interface;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
555 req->request = (unsigned char) (start_interface +
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
556 endpoint->enumeration_data->configurations[req->value_lo].number_interfaces
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
557 );
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
558 req->value_lo = (unsigned char) start_endpoint;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
559 req->value_hi = (unsigned char) start_endpoint;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
560 req->index_lo = USB_CONFIGURATION_DESCRIPTOR_LENGTH;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
561 req->index_hi = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
562 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
563 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
564 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
565
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
566
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
567 } else if (USB_DEVREQ_DESCRIPTOR_TYPE_STRING == req->value_hi) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
568
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
569 // As long as the index is valid, the rest is easy since
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
570 // the strings are just held in a simple array.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
571 // NOTE: if multiple languages have to be supported
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
572 // then things get more difficult.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
573 if (req->value_lo >= endpoint->enumeration_data->total_number_strings) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
574 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
575 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
576 endpoint->buffer = (unsigned char*) endpoint->enumeration_data->strings[req->value_lo];
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
577 endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
578 endpoint->complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, cyg_bool)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
579
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
580 if (length < endpoint->buffer[0]) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
581 endpoint->buffer_size = length;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
582 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
583 endpoint->buffer_size = endpoint->buffer[0];
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
584 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
585 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
586 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
587
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
588 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
589 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
590 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
591
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
592 } else if (USB_DEVREQ_GET_INTERFACE == req->request) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
593
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
594 if ((1 != length) ||
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
595 (USB_DEVREQ_DIRECTION_IN != direction) ||
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
596 (USBS_STATE_CONFIGURED != (endpoint->state & USBS_STATE_MASK))) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
597
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
598 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
599
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
600 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
601 int interface_id;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
602
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
603 CYG_ASSERT( (1 == endpoint->enumeration_data->device.number_configurations) && \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
604 (1 == endpoint->enumeration_data->total_number_interfaces), \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
605 "Higher level code should have handled this request");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
606
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
607 interface_id = (req->index_hi << 8) | req->index_lo;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
608 if (interface_id != endpoint->enumeration_data->interfaces[0].interface_id) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
609 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
610 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
611 endpoint->control_buffer[0] = endpoint->enumeration_data->interfaces[0].alternate_setting;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
612 endpoint->buffer = endpoint->control_buffer;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
613 endpoint->buffer_size = 1;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
614 endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
615 endpoint->complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, cyg_bool)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
616 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
617 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
618 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
619
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
620 } else if (USB_DEVREQ_GET_STATUS == req->request) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
621
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
622 if (USB_DEVREQ_RECIPIENT_INTERFACE == recipient) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
623 // The host should expect two bytes back, the device must
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
624 // be configured, the interface number must be valid.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
625 // The host should expect no data back, the device must
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
626 // be configured, and there are no defined features to clear.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
627 if ((2 == length) &&
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
628 (USB_DEVREQ_DIRECTION_IN == direction) &&
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
629 (USBS_STATE_CONFIGURED == (endpoint->state & USBS_STATE_MASK))) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
630
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
631 int interface_id = req->index_lo;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
632 CYG_ASSERT( 1 == endpoint->enumeration_data->total_number_interfaces, \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
633 "Higher level code should have handled this request");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
634
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
635 if (interface_id == endpoint->enumeration_data->interfaces[0].interface_id) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
636
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
637 // The request is legit, but there are no defined features for an interface...
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
638 endpoint->control_buffer[0] = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
639 endpoint->control_buffer[1] = 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
640 endpoint->buffer = endpoint->control_buffer;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
641 endpoint->buffer_size = 2;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
642 endpoint->fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
643 endpoint->complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, cyg_bool)) 0;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
644 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
645
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
646 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
647 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
648 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
649 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
650 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
651 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
652 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
653
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
654 } else if (USB_DEVREQ_SET_CONFIGURATION == req->request) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
655
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
656 // Changing to configuration 0 means a state change from
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
657 // configured to addressed. Changing to anything else means a
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
658 // state change to configured. Both involve invoking the
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
659 // state change callback. If there are multiple configurations
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
660 // to choose from then this request has to be handled at
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
661 // a higher level.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
662 int old_state = endpoint->state;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
663 if (0 == req->value_lo) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
664 endpoint->state = USBS_STATE_ADDRESSED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
665 if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != endpoint->state_change_fn) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
666 (*endpoint->state_change_fn)(endpoint, endpoint->state_change_data,
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
667 USBS_STATE_CHANGE_DECONFIGURED, old_state);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
668 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
669 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
670
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
671 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
672 CYG_ASSERT(1 == endpoint->enumeration_data->device.number_configurations, \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
673 "Higher level code should have handled this request");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
674 if (req->value_lo == endpoint->enumeration_data->configurations[0].configuration_id) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
675 endpoint->state = USBS_STATE_CONFIGURED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
676 if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != endpoint->state_change_fn) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
677 (*endpoint->state_change_fn)(endpoint, endpoint->state_change_data,
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
678 USBS_STATE_CHANGE_CONFIGURED, old_state);
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
679 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
680 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
681 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
682 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
683 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
684 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
685
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
686 } else if (USB_DEVREQ_SET_FEATURE == req->request) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
687
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
688 if (USB_DEVREQ_RECIPIENT_INTERFACE == recipient) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
689 // The host should expect no data back, the device must
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
690 // be configured, and there are no defined features to clear.
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
691 if ((0 == length) &&
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
692 (USBS_STATE_CONFIGURED == (endpoint->state & USBS_STATE_MASK)) &&
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
693 (0 == req->value_lo)) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
694
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
695 int interface_id = req->index_lo;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
696 CYG_ASSERT( 1 == endpoint->enumeration_data->total_number_interfaces, \
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
697 "Higher level code should have handled this request");
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
698
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
699 if (interface_id == endpoint->enumeration_data->interfaces[0].interface_id) {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
700 result = USBS_CONTROL_RETURN_HANDLED;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
701 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
702 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
703 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
704
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
705 } else {
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
706 result = USBS_CONTROL_RETURN_STALL;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
707 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
708 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
709
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
710 }
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
711
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
712 return result;
25e238959bae Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
diff changeset
713 }