Skip to content

Commit 9cb777b

Browse files
jfischer-nojhedberg
authored andcommitted
drivers: uhc: rework transfer buffer handling
The current approach is a bit impractical in the upper layer. This patch removes the two fifos that hold the transfer buffers and replaces them with a byte array for the setup packet and a pointer to a data buffer. The data buffer is mandatory for all types of transfers except control without a data stage. The waste of eight unused bytes for non-control transfers should be insignificant, since an additional pointer would be at least half of it, and then there would be the overhead of handling it. This patch also clean up the transfer flags, rename owner to callback as it reflects the upper layer use case, and add an additional member to hold the pointer to the USB device (peripheral on the bus). Signed-off-by: Johann Fischer <[email protected]>
1 parent 960e758 commit 9cb777b

File tree

8 files changed

+262
-350
lines changed

8 files changed

+262
-350
lines changed

drivers/usb/uhc/uhc_common.c

Lines changed: 58 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ void uhc_xfer_return(const struct device *dev,
5050

5151
sys_dlist_remove(&xfer->node);
5252
xfer->queued = 0;
53-
xfer->claimed = 0;
5453
xfer->err = err;
5554

5655
data->event_cb(dev, &drv_evt);
@@ -81,13 +80,25 @@ int uhc_xfer_append(const struct device *dev,
8180
return 0;
8281
}
8382

83+
struct net_buf *uhc_xfer_buf_alloc(const struct device *dev,
84+
const size_t size)
85+
{
86+
return net_buf_alloc_len(&uhc_ep_pool, size, K_NO_WAIT);
87+
}
88+
89+
void uhc_xfer_buf_free(const struct device *dev, struct net_buf *const buf)
90+
{
91+
net_buf_unref(buf);
92+
}
93+
8494
struct uhc_transfer *uhc_xfer_alloc(const struct device *dev,
8595
const uint8_t addr,
8696
const uint8_t ep,
8797
const uint8_t attrib,
8898
const uint16_t mps,
8999
const uint16_t timeout,
90-
void *const owner)
100+
void *const udev,
101+
void *const cb)
91102
{
92103
const struct uhc_api *api = dev->api;
93104
struct uhc_transfer *xfer = NULL;
@@ -98,108 +109,93 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev,
98109
goto xfer_alloc_error;
99110
}
100111

101-
LOG_DBG("Allocate xfer, ep 0x%02x attrib 0x%02x owner %p",
102-
ep, attrib, owner);
112+
LOG_DBG("Allocate xfer, ep 0x%02x attrib 0x%02x cb %p",
113+
ep, attrib, cb);
103114

104115
if (k_mem_slab_alloc(&uhc_xfer_pool, (void **)&xfer, K_NO_WAIT)) {
105116
LOG_ERR("Failed to allocate transfer");
106117
goto xfer_alloc_error;
107118
}
108119

109120
memset(xfer, 0, sizeof(struct uhc_transfer));
110-
k_fifo_init(&xfer->queue);
111-
k_fifo_init(&xfer->done);
112121
xfer->addr = addr;
113122
xfer->ep = ep;
114123
xfer->attrib = attrib;
115124
xfer->mps = mps;
116125
xfer->timeout = timeout;
117-
xfer->owner = owner;
126+
xfer->udev = udev;
127+
xfer->cb = cb;
118128

119129
xfer_alloc_error:
120130
api->unlock(dev);
121131

122132
return xfer;
123133
}
124134

125-
int uhc_xfer_free(const struct device *dev, struct uhc_transfer *const xfer)
135+
struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev,
136+
const uint8_t addr,
137+
const uint8_t ep,
138+
const uint8_t attrib,
139+
const uint16_t mps,
140+
const uint16_t timeout,
141+
void *const udev,
142+
void *const cb,
143+
size_t size)
126144
{
127-
const struct uhc_api *api = dev->api;
145+
struct uhc_transfer *xfer;
128146
struct net_buf *buf;
129-
int ret = 0;
130147

131-
api->lock(dev);
132-
133-
if (xfer->queued || xfer->claimed) {
134-
ret = -EBUSY;
135-
LOG_ERR("Transfer is still claimed");
136-
goto xfer_free_error;
137-
}
138-
139-
while (!k_fifo_is_empty(&xfer->queue)) {
140-
buf = net_buf_get(&xfer->queue, K_NO_WAIT);
141-
uhc_xfer_buf_free(dev, buf);
148+
buf = uhc_xfer_buf_alloc(dev, size);
149+
if (buf == NULL) {
150+
return NULL;
142151
}
143152

144-
while (!k_fifo_is_empty(&xfer->done)) {
145-
buf = net_buf_get(&xfer->done, K_NO_WAIT);
146-
uhc_xfer_buf_free(dev, buf);
153+
xfer = uhc_xfer_alloc(dev, addr, ep, attrib, mps, timeout, udev, cb);
154+
if (xfer == NULL) {
155+
net_buf_unref(buf);
156+
return NULL;
147157
}
148158

149-
k_mem_slab_free(&uhc_xfer_pool, (void *)xfer);
150-
151-
xfer_free_error:
152-
api->unlock(dev);
159+
xfer->buf = buf;
153160

154-
return ret;
161+
return xfer;
155162
}
156163

157-
struct net_buf *uhc_xfer_buf_alloc(const struct device *dev,
158-
struct uhc_transfer *const xfer,
159-
const size_t size)
164+
int uhc_xfer_free(const struct device *dev, struct uhc_transfer *const xfer)
160165
{
161166
const struct uhc_api *api = dev->api;
162-
struct net_buf *buf = NULL;
167+
int ret = 0;
163168

164169
api->lock(dev);
165170

166-
if (!uhc_is_initialized(dev)) {
167-
goto buf_alloc_error;
168-
}
169-
170-
if (xfer->queued || xfer->claimed) {
171-
goto buf_alloc_error;
172-
}
173-
174-
LOG_DBG("Allocate net_buf, ep 0x%02x, size %zd", xfer->ep, size);
175-
buf = net_buf_alloc_len(&uhc_ep_pool, size, K_NO_WAIT);
176-
if (!buf) {
177-
LOG_ERR("Failed to allocate net_buf");
178-
goto buf_alloc_error;
179-
}
180-
181-
if (buf->size < size) {
182-
LOG_ERR("Buffer is smaller than requested");
183-
net_buf_unref(buf);
184-
buf = NULL;
185-
goto buf_alloc_error;
171+
if (xfer->queued) {
172+
ret = -EBUSY;
173+
LOG_ERR("Transfer is still queued");
174+
goto xfer_free_error;
186175
}
187176

188-
k_fifo_put(&xfer->queue, &buf->node);
177+
k_mem_slab_free(&uhc_xfer_pool, (void *)xfer);
189178

190-
buf_alloc_error:
179+
xfer_free_error:
191180
api->unlock(dev);
192181

193-
return buf;
182+
return ret;
194183
}
195184

196-
int uhc_xfer_buf_free(const struct device *dev, struct net_buf *const buf)
185+
int uhc_xfer_buf_add(const struct device *dev,
186+
struct uhc_transfer *const xfer,
187+
struct net_buf *buf)
197188
{
198189
const struct uhc_api *api = dev->api;
199190
int ret = 0;
200191

201192
api->lock(dev);
202-
net_buf_unref(buf);
193+
if (xfer->queued) {
194+
ret = -EBUSY;
195+
} else {
196+
xfer->buf = buf;
197+
}
198+
203199
api->unlock(dev);
204200

205201
return ret;
@@ -217,12 +213,13 @@ int uhc_ep_enqueue(const struct device *dev, struct uhc_transfer *const xfer)
217213
goto ep_enqueue_error;
218214
}
219215

220-
xfer->claimed = 1;
216+
xfer->queued = 1;
221217
ret = api->ep_enqueue(dev, xfer);
222218
if (ret) {
223-
xfer->claimed = 0;
219+
xfer->queued = 0;
224220
}
225221

222+
226223
ep_enqueue_error:
227224
api->unlock(dev);
228225

@@ -242,6 +239,7 @@ int uhc_ep_dequeue(const struct device *dev, struct uhc_transfer *const xfer)
242239
}
243240

244241
ret = api->ep_dequeue(dev, xfer);
242+
xfer->queued = 0;
245243

246244
ep_dequeue_error:
247245
api->unlock(dev);

drivers/usb/uhc/uhc_common.h

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -58,54 +58,6 @@ static inline int uhc_unlock_internal(const struct device *dev)
5858
return k_mutex_unlock(&data->mutex);
5959
}
6060

61-
/**
62-
* @brief Checks if the transfer is queued.
63-
*
64-
* @param[in] xfer Pointer to UHC transfer
65-
*
66-
* @return true if transfer is queued, false otherwise
67-
*/
68-
static inline bool uhc_xfer_is_queued(struct uhc_transfer *xfer)
69-
{
70-
return xfer->queued;
71-
}
72-
73-
/**
74-
* @brief Helper function to set queued flag
75-
*
76-
* This function can be used by the driver to set queued flag
77-
*
78-
* @param[in] xfer Pointer to UHC transfer
79-
*/
80-
static inline void uhc_xfer_queued(struct uhc_transfer *xfer)
81-
{
82-
xfer->queued = true;
83-
}
84-
85-
/**
86-
* @brief Checks if the setup flag is set.
87-
*
88-
* @param[in] xfer Pointer to UHC transfer
89-
*
90-
* @return true if setup flagh is set, false otherwise
91-
*/
92-
static inline bool uhc_xfer_is_setup(struct uhc_transfer *xfer)
93-
{
94-
return xfer->setup;
95-
}
96-
97-
/**
98-
* @brief Helper function to set setup flag
99-
*
100-
* This function can be used by the driver to set setup flag
101-
*
102-
* @param[in] xfer Pointer to UHC transfer
103-
*/
104-
static inline void uhc_xfer_setup(struct uhc_transfer *xfer)
105-
{
106-
xfer->setup = true;
107-
}
108-
10961
/**
11062
* @brief Helper function to return UHC transfer to a higher level.
11163
*
@@ -119,29 +71,6 @@ void uhc_xfer_return(const struct device *dev,
11971
struct uhc_transfer *const xfer,
12072
const int err);
12173

122-
/**
123-
* @brief Helper to move current buffer in the done-FIFO.
124-
*
125-
* Helper to move current buffer (probably completed) in the
126-
* designated done-FIFO.
127-
*
128-
* @param[in] xfer Pointer to UHC transfer
129-
*
130-
* @return 0 on success, all other values should be treated as error.
131-
* @retval -ENOMEM if there is no buffer in the queue
132-
*/
133-
static inline int uhc_xfer_done(struct uhc_transfer *xfer)
134-
{
135-
struct net_buf *buf;
136-
137-
buf = k_fifo_get(&xfer->queue, K_NO_WAIT);
138-
if (buf) {
139-
k_fifo_put(&xfer->done, &buf->node);
140-
}
141-
142-
return buf == NULL ? -ENOMEM : 0;
143-
}
144-
14574
/**
14675
* @brief Helper to get next transfer to process.
14776
*

0 commit comments

Comments
 (0)