Lines Matching +full:top +full:- +full:speed

1 // SPDX-License-Identifier: GPL-2.0+
4 * Copyright (C) 2015-2016 Samsung Electronics
9 * Copyright (C) 2003-2005 Alan Stern
25 static int get_frame_limit(enum usb_device_speed speed) in get_frame_limit() argument
27 switch (speed) { in get_frame_limit()
35 /* Bus speed is 500000 bytes/ms, so use a little less */ in get_frame_limit()
39 return -1; in get_frame_limit()
45 * handle_control_request() - handles all control transfers
52 * Return 0 - if the request was handled
53 * 1 - if the request wasn't handles
67 w_index = le16_to_cpu(setup->wIndex); in handle_control_request()
68 w_value = le16_to_cpu(setup->wValue); in handle_control_request()
69 switch (setup->bRequest) { in handle_control_request()
71 if (setup->bRequestType != DEV_REQUEST) in handle_control_request()
73 udc->address = w_value; in handle_control_request()
78 if (setup->bRequestType == DEV_REQUEST) { in handle_control_request()
84 udc->gadget.b_hnp_enable = 1; in handle_control_request()
87 udc->gadget.a_hnp_support = 1; in handle_control_request()
90 udc->gadget.a_alt_hnp_support = 1; in handle_control_request()
93 ret_val = -EOPNOTSUPP; in handle_control_request()
96 udc->devstatus |= (1 << w_value); in handle_control_request()
99 } else if (setup->bRequestType == EP_REQUEST) { in handle_control_request()
102 if (!ep2 || ep2->ep.name == udc->ep[0].ep.name) { in handle_control_request()
103 ret_val = -EOPNOTSUPP; in handle_control_request()
106 ep2->halted = 1; in handle_control_request()
112 if (setup->bRequestType == DEV_REQUEST) { in handle_control_request()
122 ret_val = -EOPNOTSUPP; in handle_control_request()
125 ret_val = -EOPNOTSUPP; in handle_control_request()
129 udc->devstatus &= ~(1 << w_value); in handle_control_request()
132 } else if (setup->bRequestType == EP_REQUEST) { in handle_control_request()
136 ret_val = -EOPNOTSUPP; in handle_control_request()
139 if (!ep2->wedged) in handle_control_request()
140 ep2->halted = 0; in handle_control_request()
146 if (setup->bRequestType == DEV_INREQUEST in handle_control_request()
147 || setup->bRequestType == INTF_INREQUEST in handle_control_request()
148 || setup->bRequestType == EP_INREQUEST) { in handle_control_request()
155 buf = (char *)urb->transfer_buffer; in handle_control_request()
156 if (urb->transfer_buffer_length > 0) { in handle_control_request()
157 if (setup->bRequestType == EP_INREQUEST) { in handle_control_request()
160 ret_val = -EOPNOTSUPP; in handle_control_request()
163 buf[0] = ep2->halted; in handle_control_request()
164 } else if (setup->bRequestType == in handle_control_request()
166 buf[0] = (u8)udc->devstatus; in handle_control_request()
170 if (urb->transfer_buffer_length > 1) in handle_control_request()
172 urb->actual_length = min_t(u32, 2, in handle_control_request()
173 urb->transfer_buffer_length); in handle_control_request()
188 top: in transfer()
190 list_for_each_entry(req, &ep->req_queue, req_entry) { in transfer()
197 * 1..N packets of ep->ep.maxpacket each ... the last one in transfer()
204 host_len = urb->transfer_buffer_length - urb->actual_length; in transfer()
205 dev_len = req->req.length - req->req.actual; in transfer()
208 to_host = usb_pipein(urb->pipe); in transfer()
213 if (len >= ep->ep.maxpacket) { in transfer()
215 if (len % ep->ep.maxpacket > 0) in transfer()
217 len -= len % ep->ep.maxpacket; in transfer()
222 ubuf_pos = urb->transfer_buffer + urb->actual_length; in transfer()
223 rbuf_pos = req->req.buf + req->req.actual; in transfer()
225 if (urb->pipe & USB_DIR_IN) in transfer()
230 urb->actual_length += len; in transfer()
231 req->req.actual += len; in transfer()
241 * need to emulate such data-in-flight. in transfer()
245 req->req.status = 0; in transfer()
246 urb->status = 0; in transfer()
248 req->req.status = 0; in transfer()
250 urb->status = -EOVERFLOW; in transfer()
252 urb->status = 0; in transfer()
254 urb->status = 0; in transfer()
256 req->req.status = -EOVERFLOW; in transfer()
258 req->req.status = 0; in transfer()
264 if (req->req.length == req->req.actual) { in transfer()
265 if (req->req.zero && to_host) in transfer()
268 req->req.status = 0; in transfer()
270 if (urb->transfer_buffer_length == urb->actual_length) { in transfer()
271 if (urb->transfer_flags & URB_ZERO_PACKET && in transfer()
275 urb->status = 0; in transfer()
279 /* device side completion --> continuable */ in transfer()
280 if (req->req.status != -EINPROGRESS) { in transfer()
282 list_del_init(&req->req_entry); in transfer()
283 spin_unlock(&udc->lock); in transfer()
284 usb_gadget_giveback_request(&ep->ep, &req->req); in transfer()
285 spin_lock(&udc->lock); in transfer()
291 /* host side completion --> terminate */ in transfer()
292 if (urb->status != -EINPROGRESS) in transfer()
297 goto top; in transfer()
305 struct transfer_timer *timer = &udc->tr_timer; in v_timer()
313 spin_lock_irqsave(&udc->lock, flags); in v_timer()
315 total = get_frame_limit(udc->gadget.speed); in v_timer()
316 if (total < 0) { /* unknown speed, or not set yet */ in v_timer()
317 timer->state = VUDC_TR_IDLE; in v_timer()
318 spin_unlock_irqrestore(&udc->lock, flags); in v_timer()
322 if (time_after(jiffies, timer->frame_start + msecs_to_jiffies(1))) { in v_timer()
323 timer->frame_limit = total; in v_timer()
325 timer->frame_start = jiffies; in v_timer()
327 total = timer->frame_limit; in v_timer()
331 udc->ep[0].already_seen = 0; in v_timer()
332 list_for_each_entry(_ep, &udc->gadget.ep_list, ep_list) { in v_timer()
334 ep->already_seen = 0; in v_timer()
338 list_for_each_entry_safe(urb_p, tmp, &udc->urb_queue, urb_entry) { in v_timer()
339 struct urb *urb = urb_p->urb; in v_timer()
341 ep = urb_p->ep; in v_timer()
342 if (urb->unlinked) in v_timer()
344 if (timer->state != VUDC_TR_RUNNING) in v_timer()
348 urb->status = -EPROTO; in v_timer()
353 if (total <= 0 && ep->type == USB_ENDPOINT_XFER_BULK) in v_timer()
356 if (ep->already_seen) in v_timer()
358 ep->already_seen = 1; in v_timer()
359 if (ep == &udc->ep[0] && urb_p->new) { in v_timer()
360 ep->setup_stage = 1; in v_timer()
361 urb_p->new = 0; in v_timer()
363 if (ep->halted && !ep->setup_stage) { in v_timer()
364 urb->status = -EPIPE; in v_timer()
368 if (ep == &udc->ep[0] && ep->setup_stage) { in v_timer()
369 /* TODO - flush any stale requests */ in v_timer()
370 ep->setup_stage = 0; in v_timer()
371 ep->halted = 0; in v_timer()
374 (struct usb_ctrlrequest *) urb->setup_packet, in v_timer()
375 (&urb->status)); in v_timer()
377 spin_unlock(&udc->lock); in v_timer()
378 ret = udc->driver->setup(&udc->gadget, in v_timer()
380 urb->setup_packet); in v_timer()
381 spin_lock(&udc->lock); in v_timer()
388 urb->status = -EPIPE; in v_timer()
389 urb->actual_length = 0; in v_timer()
395 switch (ep->type) { in v_timer()
398 urb->status = -EXDEV; in v_timer()
406 limit += urb->transfer_buffer_length; in v_timer()
410 total -= transfer(udc, urb, ep, limit); in v_timer()
412 if (urb->status == -EINPROGRESS) in v_timer()
417 ep->already_seen = ep->setup_stage = 0; in v_timer()
419 spin_lock(&udc->lock_tx); in v_timer()
420 list_del(&urb_p->urb_entry); in v_timer()
421 if (!urb->unlinked) { in v_timer()
424 v_enqueue_ret_unlink(udc, urb_p->seqnum, in v_timer()
425 urb->unlinked); in v_timer()
428 wake_up(&udc->tx_waitq); in v_timer()
429 spin_unlock(&udc->lock_tx); in v_timer()
434 /* TODO - also wait on empty usb_request queues? */ in v_timer()
435 if (list_empty(&udc->urb_queue)) in v_timer()
436 timer->state = VUDC_TR_IDLE; in v_timer()
438 mod_timer(&timer->timer, in v_timer()
439 timer->frame_start + msecs_to_jiffies(1)); in v_timer()
441 spin_unlock_irqrestore(&udc->lock, flags); in v_timer()
444 /* All timer functions are run with udc->lock held */
448 struct transfer_timer *t = &udc->tr_timer; in v_init_timer()
450 timer_setup(&t->timer, v_timer, 0); in v_init_timer()
451 t->state = VUDC_TR_STOPPED; in v_init_timer()
456 struct transfer_timer *t = &udc->tr_timer; in v_start_timer()
458 dev_dbg(&udc->pdev->dev, "timer start"); in v_start_timer()
459 switch (t->state) { in v_start_timer()
465 t->state = VUDC_TR_IDLE; in v_start_timer()
466 t->frame_start = jiffies; in v_start_timer()
467 t->frame_limit = get_frame_limit(udc->gadget.speed); in v_start_timer()
474 struct transfer_timer *t = &udc->tr_timer; in v_kick_timer()
476 dev_dbg(&udc->pdev->dev, "timer kick"); in v_kick_timer()
477 switch (t->state) { in v_kick_timer()
481 t->state = VUDC_TR_RUNNING; in v_kick_timer()
485 mod_timer(&t->timer, time); in v_kick_timer()
491 struct transfer_timer *t = &udc->tr_timer; in v_stop_timer()
494 dev_dbg(&udc->pdev->dev, "timer stop"); in v_stop_timer()
495 t->state = VUDC_TR_STOPPED; in v_stop_timer()