Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

isp116x-hcd: prepare for urb->status

This patch (as931b), adapted from a patch by Olav Kongas, makes a small
set of conservative changes to the isp116x-hcd driver in preparation
for the removal of urb->status.

finish_request() is moved up in the source and is called
as soon as the URB is known to have completed, rather than
after all the active endpoints have been scanned.

The status of a completed URB is kept in a local variable
and copied to urb->status only when the URB is about to be
given back.

-EREMOTEIO error status for control transfers is set after
the status stage rather than when the short packet arrives.

Some unnecessary uses of urb->lock are removed.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Olav Kongas <ok@artecdesign.ee>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>


authored by

Alan Stern and committed by
Greg Kroah-Hartman
1b4cd43b 10e48522

+142 -157
+142 -157
drivers/usb/host/isp116x-hcd.c
··· 228 228 struct urb, urb_list); 229 229 ptd = &ep->ptd; 230 230 len = ep->length; 231 - spin_lock(&urb->lock); 232 231 ep->data = (unsigned char *)urb->transfer_buffer 233 232 + urb->actual_length; 234 233 ··· 263 264 | PTD_EP(ep->epnum); 264 265 ptd->len = PTD_LEN(len) | PTD_DIR(dir); 265 266 ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); 266 - spin_unlock(&urb->lock); 267 267 if (!ep->active) { 268 268 ptd->mps |= PTD_LAST_MSK; 269 269 isp116x->atl_last_dir = dir; 270 270 } 271 271 isp116x->atl_bufshrt = sizeof(struct ptd) + isp116x->atl_buflen; 272 272 isp116x->atl_buflen = isp116x->atl_bufshrt + ALIGN(len, 4); 273 - } 274 - } 275 - 276 - /* 277 - Analyze transfer results, handle partial transfers and errors 278 - */ 279 - static void postproc_atl_queue(struct isp116x *isp116x) 280 - { 281 - struct isp116x_ep *ep; 282 - struct urb *urb; 283 - struct usb_device *udev; 284 - struct ptd *ptd; 285 - int short_not_ok; 286 - u8 cc; 287 - 288 - for (ep = isp116x->atl_active; ep; ep = ep->active) { 289 - BUG_ON(list_empty(&ep->hep->urb_list)); 290 - urb = 291 - container_of(ep->hep->urb_list.next, struct urb, urb_list); 292 - udev = urb->dev; 293 - ptd = &ep->ptd; 294 - cc = PTD_GET_CC(ptd); 295 - short_not_ok = 1; 296 - spin_lock(&urb->lock); 297 - 298 - /* Data underrun is special. For allowed underrun 299 - we clear the error and continue as normal. For 300 - forbidden underrun we finish the DATA stage 301 - immediately while for control transfer, 302 - we do a STATUS stage. */ 303 - if (cc == TD_DATAUNDERRUN) { 304 - if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) { 305 - DBG("Allowed data underrun\n"); 306 - cc = TD_CC_NOERROR; 307 - short_not_ok = 0; 308 - } else { 309 - ep->error_count = 1; 310 - if (usb_pipecontrol(urb->pipe)) 311 - ep->nextpid = USB_PID_ACK; 312 - else 313 - usb_settoggle(udev, ep->epnum, 314 - ep->nextpid == 315 - USB_PID_OUT, 316 - PTD_GET_TOGGLE(ptd)); 317 - urb->actual_length += PTD_GET_COUNT(ptd); 318 - urb->status = cc_to_error[TD_DATAUNDERRUN]; 319 - spin_unlock(&urb->lock); 320 - continue; 321 - } 322 - } 323 - /* Keep underrun error through the STATUS stage */ 324 - if (urb->status == cc_to_error[TD_DATAUNDERRUN]) 325 - cc = TD_DATAUNDERRUN; 326 - 327 - if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED 328 - && (++ep->error_count >= 3 || cc == TD_CC_STALL 329 - || cc == TD_DATAOVERRUN)) { 330 - if (urb->status == -EINPROGRESS) 331 - urb->status = cc_to_error[cc]; 332 - if (ep->nextpid == USB_PID_ACK) 333 - ep->nextpid = 0; 334 - spin_unlock(&urb->lock); 335 - continue; 336 - } 337 - /* According to usb spec, zero-length Int transfer signals 338 - finishing of the urb. Hey, does this apply only 339 - for IN endpoints? */ 340 - if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { 341 - if (urb->status == -EINPROGRESS) 342 - urb->status = 0; 343 - spin_unlock(&urb->lock); 344 - continue; 345 - } 346 - 347 - /* Relax after previously failed, but later succeeded 348 - or correctly NAK'ed retransmission attempt */ 349 - if (ep->error_count 350 - && (cc == TD_CC_NOERROR || cc == TD_NOTACCESSED)) 351 - ep->error_count = 0; 352 - 353 - /* Take into account idiosyncracies of the isp116x chip 354 - regarding toggle bit for failed transfers */ 355 - if (ep->nextpid == USB_PID_OUT) 356 - usb_settoggle(udev, ep->epnum, 1, PTD_GET_TOGGLE(ptd) 357 - ^ (ep->error_count > 0)); 358 - else if (ep->nextpid == USB_PID_IN) 359 - usb_settoggle(udev, ep->epnum, 0, PTD_GET_TOGGLE(ptd) 360 - ^ (ep->error_count > 0)); 361 - 362 - switch (ep->nextpid) { 363 - case USB_PID_IN: 364 - case USB_PID_OUT: 365 - urb->actual_length += PTD_GET_COUNT(ptd); 366 - if (PTD_GET_ACTIVE(ptd) 367 - || (cc != TD_CC_NOERROR && cc < 0x0E)) 368 - break; 369 - if (urb->transfer_buffer_length != urb->actual_length) { 370 - if (short_not_ok) 371 - break; 372 - } else { 373 - if (urb->transfer_flags & URB_ZERO_PACKET 374 - && ep->nextpid == USB_PID_OUT 375 - && !(PTD_GET_COUNT(ptd) % ep->maxpacket)) { 376 - DBG("Zero packet requested\n"); 377 - break; 378 - } 379 - } 380 - /* All data for this URB is transferred, let's finish */ 381 - if (usb_pipecontrol(urb->pipe)) 382 - ep->nextpid = USB_PID_ACK; 383 - else if (urb->status == -EINPROGRESS) 384 - urb->status = 0; 385 - break; 386 - case USB_PID_SETUP: 387 - if (PTD_GET_ACTIVE(ptd) 388 - || (cc != TD_CC_NOERROR && cc < 0x0E)) 389 - break; 390 - if (urb->transfer_buffer_length == urb->actual_length) 391 - ep->nextpid = USB_PID_ACK; 392 - else if (usb_pipeout(urb->pipe)) { 393 - usb_settoggle(udev, 0, 1, 1); 394 - ep->nextpid = USB_PID_OUT; 395 - } else { 396 - usb_settoggle(udev, 0, 0, 1); 397 - ep->nextpid = USB_PID_IN; 398 - } 399 - break; 400 - case USB_PID_ACK: 401 - if (PTD_GET_ACTIVE(ptd) 402 - || (cc != TD_CC_NOERROR && cc < 0x0E)) 403 - break; 404 - if (urb->status == -EINPROGRESS) 405 - urb->status = 0; 406 - ep->nextpid = 0; 407 - break; 408 - default: 409 - BUG(); 410 - } 411 - spin_unlock(&urb->lock); 412 273 } 413 274 } 414 275 ··· 324 465 if (!--isp116x->periodic_count) { 325 466 isp116x->irqenb &= ~HCuPINT_SOF; 326 467 isp116x->irqenb |= HCuPINT_ATL; 468 + } 469 + } 470 + 471 + /* 472 + Analyze transfer results, handle partial transfers and errors 473 + */ 474 + static void postproc_atl_queue(struct isp116x *isp116x) 475 + { 476 + struct isp116x_ep *ep; 477 + struct urb *urb; 478 + struct usb_device *udev; 479 + struct ptd *ptd; 480 + int short_not_ok; 481 + int status; 482 + u8 cc; 483 + 484 + for (ep = isp116x->atl_active; ep; ep = ep->active) { 485 + BUG_ON(list_empty(&ep->hep->urb_list)); 486 + urb = 487 + container_of(ep->hep->urb_list.next, struct urb, urb_list); 488 + udev = urb->dev; 489 + ptd = &ep->ptd; 490 + cc = PTD_GET_CC(ptd); 491 + short_not_ok = 1; 492 + status = -EINPROGRESS; 493 + 494 + /* Data underrun is special. For allowed underrun 495 + we clear the error and continue as normal. For 496 + forbidden underrun we finish the DATA stage 497 + immediately while for control transfer, 498 + we do a STATUS stage. */ 499 + if (cc == TD_DATAUNDERRUN) { 500 + if (!(urb->transfer_flags & URB_SHORT_NOT_OK) || 501 + usb_pipecontrol(urb->pipe)) { 502 + DBG("Allowed or control data underrun\n"); 503 + cc = TD_CC_NOERROR; 504 + short_not_ok = 0; 505 + } else { 506 + ep->error_count = 1; 507 + usb_settoggle(udev, ep->epnum, 508 + ep->nextpid == USB_PID_OUT, 509 + PTD_GET_TOGGLE(ptd)); 510 + urb->actual_length += PTD_GET_COUNT(ptd); 511 + status = cc_to_error[TD_DATAUNDERRUN]; 512 + goto done; 513 + } 514 + } 515 + 516 + if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED 517 + && (++ep->error_count >= 3 || cc == TD_CC_STALL 518 + || cc == TD_DATAOVERRUN)) { 519 + status = cc_to_error[cc]; 520 + if (ep->nextpid == USB_PID_ACK) 521 + ep->nextpid = 0; 522 + goto done; 523 + } 524 + /* According to usb spec, zero-length Int transfer signals 525 + finishing of the urb. Hey, does this apply only 526 + for IN endpoints? */ 527 + if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { 528 + status = 0; 529 + goto done; 530 + } 531 + 532 + /* Relax after previously failed, but later succeeded 533 + or correctly NAK'ed retransmission attempt */ 534 + if (ep->error_count 535 + && (cc == TD_CC_NOERROR || cc == TD_NOTACCESSED)) 536 + ep->error_count = 0; 537 + 538 + /* Take into account idiosyncracies of the isp116x chip 539 + regarding toggle bit for failed transfers */ 540 + if (ep->nextpid == USB_PID_OUT) 541 + usb_settoggle(udev, ep->epnum, 1, PTD_GET_TOGGLE(ptd) 542 + ^ (ep->error_count > 0)); 543 + else if (ep->nextpid == USB_PID_IN) 544 + usb_settoggle(udev, ep->epnum, 0, PTD_GET_TOGGLE(ptd) 545 + ^ (ep->error_count > 0)); 546 + 547 + switch (ep->nextpid) { 548 + case USB_PID_IN: 549 + case USB_PID_OUT: 550 + urb->actual_length += PTD_GET_COUNT(ptd); 551 + if (PTD_GET_ACTIVE(ptd) 552 + || (cc != TD_CC_NOERROR && cc < 0x0E)) 553 + break; 554 + if (urb->transfer_buffer_length != urb->actual_length) { 555 + if (short_not_ok) 556 + break; 557 + } else { 558 + if (urb->transfer_flags & URB_ZERO_PACKET 559 + && ep->nextpid == USB_PID_OUT 560 + && !(PTD_GET_COUNT(ptd) % ep->maxpacket)) { 561 + DBG("Zero packet requested\n"); 562 + break; 563 + } 564 + } 565 + /* All data for this URB is transferred, let's finish */ 566 + if (usb_pipecontrol(urb->pipe)) 567 + ep->nextpid = USB_PID_ACK; 568 + else 569 + status = 0; 570 + break; 571 + case USB_PID_SETUP: 572 + if (PTD_GET_ACTIVE(ptd) 573 + || (cc != TD_CC_NOERROR && cc < 0x0E)) 574 + break; 575 + if (urb->transfer_buffer_length == urb->actual_length) 576 + ep->nextpid = USB_PID_ACK; 577 + else if (usb_pipeout(urb->pipe)) { 578 + usb_settoggle(udev, 0, 1, 1); 579 + ep->nextpid = USB_PID_OUT; 580 + } else { 581 + usb_settoggle(udev, 0, 0, 1); 582 + ep->nextpid = USB_PID_IN; 583 + } 584 + break; 585 + case USB_PID_ACK: 586 + if (PTD_GET_ACTIVE(ptd) 587 + || (cc != TD_CC_NOERROR && cc < 0x0E)) 588 + break; 589 + if ((urb->transfer_flags & URB_SHORT_NOT_OK) && 590 + urb->actual_length < 591 + urb->transfer_buffer_length) 592 + status = -EREMOTEIO; 593 + else 594 + status = 0; 595 + ep->nextpid = 0; 596 + break; 597 + default: 598 + BUG(); 599 + } 600 + 601 + done: 602 + if (status != -EINPROGRESS) { 603 + spin_lock(&urb->lock); 604 + if (urb->status == -EINPROGRESS) 605 + urb->status = status; 606 + spin_unlock(&urb->lock); 607 + } 608 + if (urb->status != -EINPROGRESS) 609 + finish_request(isp116x, ep, urb); 327 610 } 328 611 } 329 612 ··· 571 570 */ 572 571 static void finish_atl_transfers(struct isp116x *isp116x) 573 572 { 574 - struct isp116x_ep *ep; 575 - struct urb *urb; 576 - 577 573 if (!isp116x->atl_active) 578 574 return; 579 575 /* Fifo not ready? */ ··· 580 582 atomic_inc(&isp116x->atl_finishing); 581 583 unpack_fifo(isp116x); 582 584 postproc_atl_queue(isp116x); 583 - for (ep = isp116x->atl_active; ep; ep = ep->active) { 584 - urb = 585 - container_of(ep->hep->urb_list.next, struct urb, urb_list); 586 - /* USB_PID_ACK check here avoids finishing of 587 - control transfers, for which TD_DATAUNDERRUN 588 - occured, while URB_SHORT_NOT_OK was set */ 589 - if (urb && urb->status != -EINPROGRESS 590 - && ep->nextpid != USB_PID_ACK) 591 - finish_request(isp116x, ep, urb); 592 - } 593 585 atomic_dec(&isp116x->atl_finishing); 594 586 } 595 587 ··· 809 821 } 810 822 811 823 /* in case of unlink-during-submit */ 812 - spin_lock(&urb->lock); 813 824 if (urb->status != -EINPROGRESS) { 814 - spin_unlock(&urb->lock); 815 825 finish_request(isp116x, ep, urb); 816 826 ret = 0; 817 827 goto fail; 818 828 } 819 829 urb->hcpriv = hep; 820 - spin_unlock(&urb->lock); 821 830 start_atl_transfers(isp116x); 822 831 823 832 fail: