aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/isp116x-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/isp116x-hcd.c')
-rw-r--r--drivers/usb/host/isp116x-hcd.c214
1 files changed, 96 insertions, 118 deletions
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 46873f2534b..c27417f5b9d 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -228,7 +228,6 @@ static void preproc_atl_queue(struct isp116x *isp116x)
228 struct urb, urb_list); 228 struct urb, urb_list);
229 ptd = &ep->ptd; 229 ptd = &ep->ptd;
230 len = ep->length; 230 len = ep->length;
231 spin_lock(&urb->lock);
232 ep->data = (unsigned char *)urb->transfer_buffer 231 ep->data = (unsigned char *)urb->transfer_buffer
233 + urb->actual_length; 232 + urb->actual_length;
234 233
@@ -264,7 +263,6 @@ static void preproc_atl_queue(struct isp116x *isp116x)
264 | PTD_EP(ep->epnum); 263 | PTD_EP(ep->epnum);
265 ptd->len = PTD_LEN(len) | PTD_DIR(dir); 264 ptd->len = PTD_LEN(len) | PTD_DIR(dir);
266 ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); 265 ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe));
267 spin_unlock(&urb->lock);
268 if (!ep->active) { 266 if (!ep->active) {
269 ptd->mps |= PTD_LAST_MSK; 267 ptd->mps |= PTD_LAST_MSK;
270 isp116x->atl_last_dir = dir; 268 isp116x->atl_last_dir = dir;
@@ -275,6 +273,61 @@ static void preproc_atl_queue(struct isp116x *isp116x)
275} 273}
276 274
277/* 275/*
276 Take done or failed requests out of schedule. Give back
277 processed urbs.
278*/
279static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep,
280 struct urb *urb, int status)
281__releases(isp116x->lock) __acquires(isp116x->lock)
282{
283 unsigned i;
284
285 ep->error_count = 0;
286
287 if (usb_pipecontrol(urb->pipe))
288 ep->nextpid = USB_PID_SETUP;
289
290 urb_dbg(urb, "Finish");
291
292 usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb);
293 spin_unlock(&isp116x->lock);
294 usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status);
295 spin_lock(&isp116x->lock);
296
297 /* take idle endpoints out of the schedule */
298 if (!list_empty(&ep->hep->urb_list))
299 return;
300
301 /* async deschedule */
302 if (!list_empty(&ep->schedule)) {
303 list_del_init(&ep->schedule);
304 return;
305 }
306
307 /* periodic deschedule */
308 DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch);
309 for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) {
310 struct isp116x_ep *temp;
311 struct isp116x_ep **prev = &isp116x->periodic[i];
312
313 while (*prev && ((temp = *prev) != ep))
314 prev = &temp->next;
315 if (*prev)
316 *prev = ep->next;
317 isp116x->load[i] -= ep->load;
318 }
319 ep->branch = PERIODIC_SIZE;
320 isp116x_to_hcd(isp116x)->self.bandwidth_allocated -=
321 ep->load / ep->period;
322
323 /* switch irq type? */
324 if (!--isp116x->periodic_count) {
325 isp116x->irqenb &= ~HCuPINT_SOF;
326 isp116x->irqenb |= HCuPINT_ATL;
327 }
328}
329
330/*
278 Analyze transfer results, handle partial transfers and errors 331 Analyze transfer results, handle partial transfers and errors
279*/ 332*/
280static void postproc_atl_queue(struct isp116x *isp116x) 333static void postproc_atl_queue(struct isp116x *isp116x)
@@ -284,6 +337,7 @@ static void postproc_atl_queue(struct isp116x *isp116x)
284 struct usb_device *udev; 337 struct usb_device *udev;
285 struct ptd *ptd; 338 struct ptd *ptd;
286 int short_not_ok; 339 int short_not_ok;
340 int status;
287 u8 cc; 341 u8 cc;
288 342
289 for (ep = isp116x->atl_active; ep; ep = ep->active) { 343 for (ep = isp116x->atl_active; ep; ep = ep->active) {
@@ -294,7 +348,7 @@ static void postproc_atl_queue(struct isp116x *isp116x)
294 ptd = &ep->ptd; 348 ptd = &ep->ptd;
295 cc = PTD_GET_CC(ptd); 349 cc = PTD_GET_CC(ptd);
296 short_not_ok = 1; 350 short_not_ok = 1;
297 spin_lock(&urb->lock); 351 status = -EINPROGRESS;
298 352
299 /* Data underrun is special. For allowed underrun 353 /* Data underrun is special. For allowed underrun
300 we clear the error and continue as normal. For 354 we clear the error and continue as normal. For
@@ -302,47 +356,36 @@ static void postproc_atl_queue(struct isp116x *isp116x)
302 immediately while for control transfer, 356 immediately while for control transfer,
303 we do a STATUS stage. */ 357 we do a STATUS stage. */
304 if (cc == TD_DATAUNDERRUN) { 358 if (cc == TD_DATAUNDERRUN) {
305 if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) { 359 if (!(urb->transfer_flags & URB_SHORT_NOT_OK) ||
306 DBG("Allowed data underrun\n"); 360 usb_pipecontrol(urb->pipe)) {
361 DBG("Allowed or control data underrun\n");
307 cc = TD_CC_NOERROR; 362 cc = TD_CC_NOERROR;
308 short_not_ok = 0; 363 short_not_ok = 0;
309 } else { 364 } else {
310 ep->error_count = 1; 365 ep->error_count = 1;
311 if (usb_pipecontrol(urb->pipe)) 366 usb_settoggle(udev, ep->epnum,
312 ep->nextpid = USB_PID_ACK; 367 ep->nextpid == USB_PID_OUT,
313 else 368 PTD_GET_TOGGLE(ptd));
314 usb_settoggle(udev, ep->epnum,
315 ep->nextpid ==
316 USB_PID_OUT,
317 PTD_GET_TOGGLE(ptd));
318 urb->actual_length += PTD_GET_COUNT(ptd); 369 urb->actual_length += PTD_GET_COUNT(ptd);
319 urb->status = cc_to_error[TD_DATAUNDERRUN]; 370 status = cc_to_error[TD_DATAUNDERRUN];
320 spin_unlock(&urb->lock); 371 goto done;
321 continue;
322 } 372 }
323 } 373 }
324 /* Keep underrun error through the STATUS stage */
325 if (urb->status == cc_to_error[TD_DATAUNDERRUN])
326 cc = TD_DATAUNDERRUN;
327 374
328 if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED 375 if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED
329 && (++ep->error_count >= 3 || cc == TD_CC_STALL 376 && (++ep->error_count >= 3 || cc == TD_CC_STALL
330 || cc == TD_DATAOVERRUN)) { 377 || cc == TD_DATAOVERRUN)) {
331 if (urb->status == -EINPROGRESS) 378 status = cc_to_error[cc];
332 urb->status = cc_to_error[cc];
333 if (ep->nextpid == USB_PID_ACK) 379 if (ep->nextpid == USB_PID_ACK)
334 ep->nextpid = 0; 380 ep->nextpid = 0;
335 spin_unlock(&urb->lock); 381 goto done;
336 continue;
337 } 382 }
338 /* According to usb spec, zero-length Int transfer signals 383 /* According to usb spec, zero-length Int transfer signals
339 finishing of the urb. Hey, does this apply only 384 finishing of the urb. Hey, does this apply only
340 for IN endpoints? */ 385 for IN endpoints? */
341 if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { 386 if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) {
342 if (urb->status == -EINPROGRESS) 387 status = 0;
343 urb->status = 0; 388 goto done;
344 spin_unlock(&urb->lock);
345 continue;
346 } 389 }
347 390
348 /* Relax after previously failed, but later succeeded 391 /* Relax after previously failed, but later succeeded
@@ -381,8 +424,8 @@ static void postproc_atl_queue(struct isp116x *isp116x)
381 /* All data for this URB is transferred, let's finish */ 424 /* All data for this URB is transferred, let's finish */
382 if (usb_pipecontrol(urb->pipe)) 425 if (usb_pipecontrol(urb->pipe))
383 ep->nextpid = USB_PID_ACK; 426 ep->nextpid = USB_PID_ACK;
384 else if (urb->status == -EINPROGRESS) 427 else
385 urb->status = 0; 428 status = 0;
386 break; 429 break;
387 case USB_PID_SETUP: 430 case USB_PID_SETUP:
388 if (PTD_GET_ACTIVE(ptd) 431 if (PTD_GET_ACTIVE(ptd)
@@ -402,69 +445,16 @@ static void postproc_atl_queue(struct isp116x *isp116x)
402 if (PTD_GET_ACTIVE(ptd) 445 if (PTD_GET_ACTIVE(ptd)
403 || (cc != TD_CC_NOERROR && cc < 0x0E)) 446 || (cc != TD_CC_NOERROR && cc < 0x0E))
404 break; 447 break;
405 if (urb->status == -EINPROGRESS) 448 status = 0;
406 urb->status = 0;
407 ep->nextpid = 0; 449 ep->nextpid = 0;
408 break; 450 break;
409 default: 451 default:
410 BUG(); 452 BUG();
411 } 453 }
412 spin_unlock(&urb->lock);
413 }
414}
415 454
416/* 455 done:
417 Take done or failed requests out of schedule. Give back 456 if (status != -EINPROGRESS || urb->unlinked)
418 processed urbs. 457 finish_request(isp116x, ep, urb, status);
419*/
420static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep,
421 struct urb *urb)
422__releases(isp116x->lock) __acquires(isp116x->lock)
423{
424 unsigned i;
425
426 urb->hcpriv = NULL;
427 ep->error_count = 0;
428
429 if (usb_pipecontrol(urb->pipe))
430 ep->nextpid = USB_PID_SETUP;
431
432 urb_dbg(urb, "Finish");
433
434 spin_unlock(&isp116x->lock);
435 usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb);
436 spin_lock(&isp116x->lock);
437
438 /* take idle endpoints out of the schedule */
439 if (!list_empty(&ep->hep->urb_list))
440 return;
441
442 /* async deschedule */
443 if (!list_empty(&ep->schedule)) {
444 list_del_init(&ep->schedule);
445 return;
446 }
447
448 /* periodic deschedule */
449 DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch);
450 for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) {
451 struct isp116x_ep *temp;
452 struct isp116x_ep **prev = &isp116x->periodic[i];
453
454 while (*prev && ((temp = *prev) != ep))
455 prev = &temp->next;
456 if (*prev)
457 *prev = ep->next;
458 isp116x->load[i] -= ep->load;
459 }
460 ep->branch = PERIODIC_SIZE;
461 isp116x_to_hcd(isp116x)->self.bandwidth_allocated -=
462 ep->load / ep->period;
463
464 /* switch irq type? */
465 if (!--isp116x->periodic_count) {
466 isp116x->irqenb &= ~HCuPINT_SOF;
467 isp116x->irqenb |= HCuPINT_ATL;
468 } 458 }
469} 459}
470 460
@@ -570,9 +560,6 @@ static void start_atl_transfers(struct isp116x *isp116x)
570*/ 560*/
571static void finish_atl_transfers(struct isp116x *isp116x) 561static void finish_atl_transfers(struct isp116x *isp116x)
572{ 562{
573 struct isp116x_ep *ep;
574 struct urb *urb;
575
576 if (!isp116x->atl_active) 563 if (!isp116x->atl_active)
577 return; 564 return;
578 /* Fifo not ready? */ 565 /* Fifo not ready? */
@@ -582,16 +569,6 @@ static void finish_atl_transfers(struct isp116x *isp116x)
582 atomic_inc(&isp116x->atl_finishing); 569 atomic_inc(&isp116x->atl_finishing);
583 unpack_fifo(isp116x); 570 unpack_fifo(isp116x);
584 postproc_atl_queue(isp116x); 571 postproc_atl_queue(isp116x);
585 for (ep = isp116x->atl_active; ep; ep = ep->active) {
586 urb =
587 container_of(ep->hep->urb_list.next, struct urb, urb_list);
588 /* USB_PID_ACK check here avoids finishing of
589 control transfers, for which TD_DATAUNDERRUN
590 occured, while URB_SHORT_NOT_OK was set */
591 if (urb && urb->status != -EINPROGRESS
592 && ep->nextpid != USB_PID_ACK)
593 finish_request(isp116x, ep, urb);
594 }
595 atomic_dec(&isp116x->atl_finishing); 572 atomic_dec(&isp116x->atl_finishing);
596} 573}
597 574
@@ -685,7 +662,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load)
685/*-----------------------------------------------------------------*/ 662/*-----------------------------------------------------------------*/
686 663
687static int isp116x_urb_enqueue(struct usb_hcd *hcd, 664static int isp116x_urb_enqueue(struct usb_hcd *hcd,
688 struct usb_host_endpoint *hep, struct urb *urb, 665 struct urb *urb,
689 gfp_t mem_flags) 666 gfp_t mem_flags)
690{ 667{
691 struct isp116x *isp116x = hcd_to_isp116x(hcd); 668 struct isp116x *isp116x = hcd_to_isp116x(hcd);
@@ -694,6 +671,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
694 int is_out = !usb_pipein(pipe); 671 int is_out = !usb_pipein(pipe);
695 int type = usb_pipetype(pipe); 672 int type = usb_pipetype(pipe);
696 int epnum = usb_pipeendpoint(pipe); 673 int epnum = usb_pipeendpoint(pipe);
674 struct usb_host_endpoint *hep = urb->ep;
697 struct isp116x_ep *ep = NULL; 675 struct isp116x_ep *ep = NULL;
698 unsigned long flags; 676 unsigned long flags;
699 int i; 677 int i;
@@ -717,7 +695,12 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
717 if (!HC_IS_RUNNING(hcd->state)) { 695 if (!HC_IS_RUNNING(hcd->state)) {
718 kfree(ep); 696 kfree(ep);
719 ret = -ENODEV; 697 ret = -ENODEV;
720 goto fail; 698 goto fail_not_linked;
699 }
700 ret = usb_hcd_link_urb_to_ep(hcd, urb);
701 if (ret) {
702 kfree(ep);
703 goto fail_not_linked;
721 } 704 }
722 705
723 if (hep->hcpriv) 706 if (hep->hcpriv)
@@ -820,19 +803,13 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
820 } 803 }
821 } 804 }
822 805
823 /* in case of unlink-during-submit */
824 spin_lock(&urb->lock);
825 if (urb->status != -EINPROGRESS) {
826 spin_unlock(&urb->lock);
827 finish_request(isp116x, ep, urb);
828 ret = 0;
829 goto fail;
830 }
831 urb->hcpriv = hep; 806 urb->hcpriv = hep;
832 spin_unlock(&urb->lock);
833 start_atl_transfers(isp116x); 807 start_atl_transfers(isp116x);
834 808
835 fail: 809 fail:
810 if (ret)
811 usb_hcd_unlink_urb_from_ep(hcd, urb);
812 fail_not_linked:
836 spin_unlock_irqrestore(&isp116x->lock, flags); 813 spin_unlock_irqrestore(&isp116x->lock, flags);
837 return ret; 814 return ret;
838} 815}
@@ -840,20 +817,21 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
840/* 817/*
841 Dequeue URBs. 818 Dequeue URBs.
842*/ 819*/
843static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) 820static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
821 int status)
844{ 822{
845 struct isp116x *isp116x = hcd_to_isp116x(hcd); 823 struct isp116x *isp116x = hcd_to_isp116x(hcd);
846 struct usb_host_endpoint *hep; 824 struct usb_host_endpoint *hep;
847 struct isp116x_ep *ep, *ep_act; 825 struct isp116x_ep *ep, *ep_act;
848 unsigned long flags; 826 unsigned long flags;
827 int rc;
849 828
850 spin_lock_irqsave(&isp116x->lock, flags); 829 spin_lock_irqsave(&isp116x->lock, flags);
830 rc = usb_hcd_check_unlink_urb(hcd, urb, status);
831 if (rc)
832 goto done;
833
851 hep = urb->hcpriv; 834 hep = urb->hcpriv;
852 /* URB already unlinked (or never linked)? */
853 if (!hep) {
854 spin_unlock_irqrestore(&isp116x->lock, flags);
855 return 0;
856 }
857 ep = hep->hcpriv; 835 ep = hep->hcpriv;
858 WARN_ON(hep != ep->hep); 836 WARN_ON(hep != ep->hep);
859 837
@@ -870,10 +848,10 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
870 } 848 }
871 849
872 if (urb) 850 if (urb)
873 finish_request(isp116x, ep, urb); 851 finish_request(isp116x, ep, urb, status);
874 852 done:
875 spin_unlock_irqrestore(&isp116x->lock, flags); 853 spin_unlock_irqrestore(&isp116x->lock, flags);
876 return 0; 854 return rc;
877} 855}
878 856
879static void isp116x_endpoint_disable(struct usb_hcd *hcd, 857static void isp116x_endpoint_disable(struct usb_hcd *hcd,