Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1240)

Side by Side Diff: device/usb/usb_device_handle_usbfs.cc

Issue 2843613002: Fix crash when closing a device from a USB transfer timeout (Closed)
Patch Set: Address mcasas@ nits Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/usb/usb_device_handle_usbfs.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/usb/usb_device_handle_usbfs.h" 5 #include "device/usb/usb_device_handle_usbfs.h"
6 6
7 #if defined(OS_ANDROID) && __ANDROID_API__ < 21 7 #if defined(OS_ANDROID) && __ANDROID_API__ < 21
8 #include <linux/usb_ch9.h> 8 #include <linux/usb_ch9.h>
9 #else 9 #else
10 #include <linux/usb/ch9.h> 10 #include <linux/usb/ch9.h>
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 DCHECK(fd.is_valid()); 416 DCHECK(fd.is_valid());
417 DCHECK(blocking_task_runner_); 417 DCHECK(blocking_task_runner_);
418 418
419 helper_.reset(new FileThreadHelper(std::move(fd), this, task_runner_)); 419 helper_.reset(new FileThreadHelper(std::move(fd), this, task_runner_));
420 blocking_task_runner_->PostTask( 420 blocking_task_runner_->PostTask(
421 FROM_HERE, 421 FROM_HERE,
422 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get()))); 422 base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get())));
423 } 423 }
424 424
425 scoped_refptr<UsbDevice> UsbDeviceHandleUsbfs::GetDevice() const { 425 scoped_refptr<UsbDevice> UsbDeviceHandleUsbfs::GetDevice() const {
426 DCHECK(sequence_checker_.CalledOnValidSequence());
426 return device_; 427 return device_;
427 } 428 }
428 429
429 void UsbDeviceHandleUsbfs::Close() { 430 void UsbDeviceHandleUsbfs::Close() {
431 DCHECK(sequence_checker_.CalledOnValidSequence());
430 if (!device_) 432 if (!device_)
431 return; // Already closed. 433 return; // Already closed.
432 434
435 // Cancelling transfers may run or destroy callbacks holding the last
436 // reference to this object so hold a reference for the rest of this method.
437 scoped_refptr<UsbDeviceHandleUsbfs> self(this);
438 for (const auto& transfer : transfers_)
439 CancelTransfer(transfer.get(), UsbTransferStatus::CANCELLED);
440
433 // On the |task_runner_| thread check |device_| to see if the handle is 441 // On the |task_runner_| thread check |device_| to see if the handle is
434 // closed. On the |blocking_task_runner_| thread check |fd_.is_valid()| to 442 // closed. On the |blocking_task_runner_| thread check |fd_.is_valid()| to
435 // see if the handle is closed. 443 // see if the handle is closed.
436 device_->HandleClosed(this); 444 device_->HandleClosed(this);
437 device_ = nullptr; 445 device_ = nullptr;
438 446
439 for (const auto& transfer : transfers_)
440 CancelTransfer(transfer.get(), UsbTransferStatus::CANCELLED);
441
442 // Releases |helper_|. 447 // Releases |helper_|.
443 blocking_task_runner_->PostTask( 448 blocking_task_runner_->PostTask(
444 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::CloseBlocking, this)); 449 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::CloseBlocking, this));
445 } 450 }
446 451
447 void UsbDeviceHandleUsbfs::SetConfiguration(int configuration_value, 452 void UsbDeviceHandleUsbfs::SetConfiguration(int configuration_value,
448 const ResultCallback& callback) { 453 const ResultCallback& callback) {
454 DCHECK(sequence_checker_.CalledOnValidSequence());
449 if (!device_) { 455 if (!device_) {
450 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); 456 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
451 return; 457 return;
452 } 458 }
453 459
454 // USBDEVFS_SETCONFIGURATION synchronously issues a SET_CONFIGURATION request 460 // USBDEVFS_SETCONFIGURATION synchronously issues a SET_CONFIGURATION request
455 // to the device so it must be performed on a thread where it is okay to 461 // to the device so it must be performed on a thread where it is okay to
456 // block. 462 // block.
457 blocking_task_runner_->PostTask( 463 blocking_task_runner_->PostTask(
458 FROM_HERE, 464 FROM_HERE,
459 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetConfiguration, 465 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetConfiguration,
460 base::Unretained(helper_.get()), configuration_value, 466 base::Unretained(helper_.get()), configuration_value,
461 callback)); 467 callback));
462 } 468 }
463 469
464 void UsbDeviceHandleUsbfs::ClaimInterface(int interface_number, 470 void UsbDeviceHandleUsbfs::ClaimInterface(int interface_number,
465 const ResultCallback& callback) { 471 const ResultCallback& callback) {
472 DCHECK(sequence_checker_.CalledOnValidSequence());
466 if (!device_) { 473 if (!device_) {
467 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); 474 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
468 return; 475 return;
469 } 476 }
470 477
471 if (base::ContainsKey(interfaces_, interface_number)) { 478 if (base::ContainsKey(interfaces_, interface_number)) {
472 USB_LOG(DEBUG) << "Interface " << interface_number << " already claimed."; 479 USB_LOG(DEBUG) << "Interface " << interface_number << " already claimed.";
473 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); 480 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
474 return; 481 return;
475 } 482 }
476 483
477 // It appears safe to assume that this ioctl will not block. 484 // It appears safe to assume that this ioctl will not block.
478 int rc = HANDLE_EINTR(ioctl(fd_, USBDEVFS_CLAIMINTERFACE, &interface_number)); 485 int rc = HANDLE_EINTR(ioctl(fd_, USBDEVFS_CLAIMINTERFACE, &interface_number));
479 if (rc) { 486 if (rc) {
480 USB_PLOG(DEBUG) << "Failed to claim interface " << interface_number; 487 USB_PLOG(DEBUG) << "Failed to claim interface " << interface_number;
481 } else { 488 } else {
482 interfaces_[interface_number].alternate_setting = 0; 489 interfaces_[interface_number].alternate_setting = 0;
483 RefreshEndpointInfo(); 490 RefreshEndpointInfo();
484 } 491 }
485 task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0)); 492 task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0));
486 } 493 }
487 494
488 void UsbDeviceHandleUsbfs::ReleaseInterface(int interface_number, 495 void UsbDeviceHandleUsbfs::ReleaseInterface(int interface_number,
489 const ResultCallback& callback) { 496 const ResultCallback& callback) {
497 DCHECK(sequence_checker_.CalledOnValidSequence());
490 if (!device_) { 498 if (!device_) {
491 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); 499 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
492 return; 500 return;
493 } 501 }
494 502
495 // USBDEVFS_RELEASEINTERFACE may issue a SET_INTERFACE request to the 503 // USBDEVFS_RELEASEINTERFACE may issue a SET_INTERFACE request to the
496 // device to restore alternate setting 0 so it must be performed on a thread 504 // device to restore alternate setting 0 so it must be performed on a thread
497 // where it is okay to block. 505 // where it is okay to block.
498 blocking_task_runner_->PostTask( 506 blocking_task_runner_->PostTask(
499 FROM_HERE, 507 FROM_HERE,
500 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ReleaseInterface, 508 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ReleaseInterface,
501 base::Unretained(helper_.get()), interface_number, callback)); 509 base::Unretained(helper_.get()), interface_number, callback));
502 } 510 }
503 511
504 void UsbDeviceHandleUsbfs::SetInterfaceAlternateSetting( 512 void UsbDeviceHandleUsbfs::SetInterfaceAlternateSetting(
505 int interface_number, 513 int interface_number,
506 int alternate_setting, 514 int alternate_setting,
507 const ResultCallback& callback) { 515 const ResultCallback& callback) {
516 DCHECK(sequence_checker_.CalledOnValidSequence());
508 if (!device_) { 517 if (!device_) {
509 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); 518 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
510 return; 519 return;
511 } 520 }
512 521
513 // USBDEVFS_SETINTERFACE is synchronous because it issues a SET_INTERFACE 522 // USBDEVFS_SETINTERFACE is synchronous because it issues a SET_INTERFACE
514 // request to the device so it must be performed on a thread where it is okay 523 // request to the device so it must be performed on a thread where it is okay
515 // to block. 524 // to block.
516 blocking_task_runner_->PostTask( 525 blocking_task_runner_->PostTask(
517 FROM_HERE, 526 FROM_HERE,
518 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetInterface, 527 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetInterface,
519 base::Unretained(helper_.get()), interface_number, 528 base::Unretained(helper_.get()), interface_number,
520 alternate_setting, callback)); 529 alternate_setting, callback));
521 } 530 }
522 531
523 void UsbDeviceHandleUsbfs::ResetDevice(const ResultCallback& callback) { 532 void UsbDeviceHandleUsbfs::ResetDevice(const ResultCallback& callback) {
533 DCHECK(sequence_checker_.CalledOnValidSequence());
524 if (!device_) { 534 if (!device_) {
525 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); 535 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
526 return; 536 return;
527 } 537 }
528 538
529 // USBDEVFS_RESET is synchronous because it waits for the port to be reset 539 // USBDEVFS_RESET is synchronous because it waits for the port to be reset
530 // and the device re-enumerated so it must be performed on a thread where it 540 // and the device re-enumerated so it must be performed on a thread where it
531 // is okay to block. 541 // is okay to block.
532 blocking_task_runner_->PostTask( 542 blocking_task_runner_->PostTask(
533 FROM_HERE, 543 FROM_HERE,
534 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ResetDevice, 544 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ResetDevice,
535 base::Unretained(helper_.get()), callback)); 545 base::Unretained(helper_.get()), callback));
536 } 546 }
537 547
538 void UsbDeviceHandleUsbfs::ClearHalt(uint8_t endpoint_address, 548 void UsbDeviceHandleUsbfs::ClearHalt(uint8_t endpoint_address,
539 const ResultCallback& callback) { 549 const ResultCallback& callback) {
550 DCHECK(sequence_checker_.CalledOnValidSequence());
540 if (!device_) { 551 if (!device_) {
541 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); 552 task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
542 return; 553 return;
543 } 554 }
544 555
545 // USBDEVFS_CLEAR_HALT is synchronous because it issues a CLEAR_FEATURE 556 // USBDEVFS_CLEAR_HALT is synchronous because it issues a CLEAR_FEATURE
546 // request to the device so it must be performed on a thread where it is okay 557 // request to the device so it must be performed on a thread where it is okay
547 // to block. 558 // to block.
548 blocking_task_runner_->PostTask( 559 blocking_task_runner_->PostTask(
549 FROM_HERE, 560 FROM_HERE,
550 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ClearHalt, 561 base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ClearHalt,
551 base::Unretained(helper_.get()), endpoint_address, callback)); 562 base::Unretained(helper_.get()), endpoint_address, callback));
552 } 563 }
553 564
554 void UsbDeviceHandleUsbfs::ControlTransfer( 565 void UsbDeviceHandleUsbfs::ControlTransfer(
555 UsbTransferDirection direction, 566 UsbTransferDirection direction,
556 UsbControlTransferType request_type, 567 UsbControlTransferType request_type,
557 UsbControlTransferRecipient recipient, 568 UsbControlTransferRecipient recipient,
558 uint8_t request, 569 uint8_t request,
559 uint16_t value, 570 uint16_t value,
560 uint16_t index, 571 uint16_t index,
561 scoped_refptr<net::IOBuffer> buffer, 572 scoped_refptr<net::IOBuffer> buffer,
562 size_t length, 573 size_t length,
563 unsigned int timeout, 574 unsigned int timeout,
564 const TransferCallback& callback) { 575 const TransferCallback& callback) {
576 DCHECK(sequence_checker_.CalledOnValidSequence());
565 if (!device_) { 577 if (!device_) {
566 task_runner_->PostTask( 578 task_runner_->PostTask(
567 FROM_HERE, 579 FROM_HERE,
568 base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); 580 base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0));
569 return; 581 return;
570 } 582 }
571 583
572 std::unique_ptr<Transfer> transfer(new (0) 584 std::unique_ptr<Transfer> transfer(new (0)
573 Transfer(buffer, callback, nullptr)); 585 Transfer(buffer, callback, nullptr));
574 transfer->control_transfer_buffer = 586 transfer->control_transfer_buffer =
(...skipping 16 matching lines...) Expand all
591 SetUpTimeoutCallback(transfer.get(), timeout); 603 SetUpTimeoutCallback(transfer.get(), timeout);
592 transfers_.push_back(std::move(transfer)); 604 transfers_.push_back(std::move(transfer));
593 } 605 }
594 } 606 }
595 607
596 void UsbDeviceHandleUsbfs::IsochronousTransferIn( 608 void UsbDeviceHandleUsbfs::IsochronousTransferIn(
597 uint8_t endpoint_number, 609 uint8_t endpoint_number,
598 const std::vector<uint32_t>& packet_lengths, 610 const std::vector<uint32_t>& packet_lengths,
599 unsigned int timeout, 611 unsigned int timeout,
600 const IsochronousTransferCallback& callback) { 612 const IsochronousTransferCallback& callback) {
613 DCHECK(sequence_checker_.CalledOnValidSequence());
601 uint8_t endpoint_address = USB_DIR_IN | endpoint_number; 614 uint8_t endpoint_address = USB_DIR_IN | endpoint_number;
602 size_t total_length = 615 size_t total_length =
603 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); 616 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u);
604 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(total_length)); 617 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(total_length));
605 IsochronousTransferInternal(endpoint_address, buffer, total_length, 618 IsochronousTransferInternal(endpoint_address, buffer, total_length,
606 packet_lengths, timeout, callback); 619 packet_lengths, timeout, callback);
607 } 620 }
608 621
609 void UsbDeviceHandleUsbfs::IsochronousTransferOut( 622 void UsbDeviceHandleUsbfs::IsochronousTransferOut(
610 uint8_t endpoint_number, 623 uint8_t endpoint_number,
611 scoped_refptr<net::IOBuffer> buffer, 624 scoped_refptr<net::IOBuffer> buffer,
612 const std::vector<uint32_t>& packet_lengths, 625 const std::vector<uint32_t>& packet_lengths,
613 unsigned int timeout, 626 unsigned int timeout,
614 const IsochronousTransferCallback& callback) { 627 const IsochronousTransferCallback& callback) {
628 DCHECK(sequence_checker_.CalledOnValidSequence());
615 uint8_t endpoint_address = USB_DIR_OUT | endpoint_number; 629 uint8_t endpoint_address = USB_DIR_OUT | endpoint_number;
616 size_t total_length = 630 size_t total_length =
617 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u); 631 std::accumulate(packet_lengths.begin(), packet_lengths.end(), 0u);
618 IsochronousTransferInternal(endpoint_address, buffer, total_length, 632 IsochronousTransferInternal(endpoint_address, buffer, total_length,
619 packet_lengths, timeout, callback); 633 packet_lengths, timeout, callback);
620 } 634 }
621 635
622 void UsbDeviceHandleUsbfs::GenericTransfer(UsbTransferDirection direction, 636 void UsbDeviceHandleUsbfs::GenericTransfer(UsbTransferDirection direction,
623 uint8_t endpoint_number, 637 uint8_t endpoint_number,
624 scoped_refptr<net::IOBuffer> buffer, 638 scoped_refptr<net::IOBuffer> buffer,
625 size_t length, 639 size_t length,
626 unsigned int timeout, 640 unsigned int timeout,
627 const TransferCallback& callback) { 641 const TransferCallback& callback) {
628 if (task_runner_->BelongsToCurrentThread()) { 642 if (task_runner_->BelongsToCurrentThread()) {
629 GenericTransferInternal(direction, endpoint_number, buffer, length, timeout, 643 GenericTransferInternal(direction, endpoint_number, buffer, length, timeout,
630 callback, task_runner_); 644 callback, task_runner_);
631 } else { 645 } else {
632 task_runner_->PostTask( 646 task_runner_->PostTask(
633 FROM_HERE, 647 FROM_HERE,
634 base::Bind(&UsbDeviceHandleUsbfs::GenericTransferInternal, this, 648 base::Bind(&UsbDeviceHandleUsbfs::GenericTransferInternal, this,
635 direction, endpoint_number, buffer, length, timeout, 649 direction, endpoint_number, buffer, length, timeout,
636 callback, base::ThreadTaskRunnerHandle::Get())); 650 callback, base::ThreadTaskRunnerHandle::Get()));
637 } 651 }
638 } 652 }
639 653
640 const UsbInterfaceDescriptor* UsbDeviceHandleUsbfs::FindInterfaceByEndpoint( 654 const UsbInterfaceDescriptor* UsbDeviceHandleUsbfs::FindInterfaceByEndpoint(
641 uint8_t endpoint_address) { 655 uint8_t endpoint_address) {
656 DCHECK(sequence_checker_.CalledOnValidSequence());
642 auto it = endpoints_.find(endpoint_address); 657 auto it = endpoints_.find(endpoint_address);
643 if (it != endpoints_.end()) 658 if (it != endpoints_.end())
644 return it->second.interface; 659 return it->second.interface;
645 return nullptr; 660 return nullptr;
646 } 661 }
647 662
648 UsbDeviceHandleUsbfs::~UsbDeviceHandleUsbfs() { 663 UsbDeviceHandleUsbfs::~UsbDeviceHandleUsbfs() {
649 DCHECK(!device_) << "Handle must be closed before it is destroyed."; 664 DCHECK(!device_) << "Handle must be closed before it is destroyed.";
650 } 665 }
651 666
652 void UsbDeviceHandleUsbfs::ReleaseFileDescriptor() { 667 void UsbDeviceHandleUsbfs::ReleaseFileDescriptor() {
653 // Calls to this method must be posted to |blocking_task_runner_|. 668 // Calls to this method must be posted to |blocking_task_runner_|.
654 helper_->ReleaseFileDescriptor(); 669 helper_->ReleaseFileDescriptor();
655 helper_.reset(); 670 helper_.reset();
656 } 671 }
657 672
658 void UsbDeviceHandleUsbfs::CloseBlocking() { 673 void UsbDeviceHandleUsbfs::CloseBlocking() {
659 // Calls to this method must be posted to |blocking_task_runner_|. 674 // Calls to this method must be posted to |blocking_task_runner_|.
660 helper_.reset(); 675 helper_.reset();
661 } 676 }
662 677
663 void UsbDeviceHandleUsbfs::SetConfigurationComplete( 678 void UsbDeviceHandleUsbfs::SetConfigurationComplete(
664 int configuration_value, 679 int configuration_value,
665 bool success, 680 bool success,
666 const ResultCallback& callback) { 681 const ResultCallback& callback) {
682 DCHECK(sequence_checker_.CalledOnValidSequence());
667 if (success && device_) { 683 if (success && device_) {
668 device_->ActiveConfigurationChanged(configuration_value); 684 device_->ActiveConfigurationChanged(configuration_value);
669 // TODO(reillyg): If all interfaces are unclaimed before a new configuration 685 // TODO(reillyg): If all interfaces are unclaimed before a new configuration
670 // is set then this will do nothing. Investigate. 686 // is set then this will do nothing. Investigate.
671 RefreshEndpointInfo(); 687 RefreshEndpointInfo();
672 } 688 }
673 callback.Run(success); 689 callback.Run(success);
674 } 690 }
675 691
676 void UsbDeviceHandleUsbfs::ReleaseInterfaceComplete( 692 void UsbDeviceHandleUsbfs::ReleaseInterfaceComplete(
677 int interface_number, 693 int interface_number,
678 const ResultCallback& callback) { 694 const ResultCallback& callback) {
695 DCHECK(sequence_checker_.CalledOnValidSequence());
679 auto it = interfaces_.find(interface_number); 696 auto it = interfaces_.find(interface_number);
680 DCHECK(it != interfaces_.end()); 697 DCHECK(it != interfaces_.end());
681 interfaces_.erase(it); 698 interfaces_.erase(it);
682 RefreshEndpointInfo(); 699 RefreshEndpointInfo();
683 callback.Run(true); 700 callback.Run(true);
684 } 701 }
685 702
686 void UsbDeviceHandleUsbfs::IsochronousTransferInternal( 703 void UsbDeviceHandleUsbfs::IsochronousTransferInternal(
687 uint8_t endpoint_address, 704 uint8_t endpoint_address,
688 scoped_refptr<net::IOBuffer> buffer, 705 scoped_refptr<net::IOBuffer> buffer,
689 size_t total_length, 706 size_t total_length,
690 const std::vector<uint32_t>& packet_lengths, 707 const std::vector<uint32_t>& packet_lengths,
691 unsigned int timeout, 708 unsigned int timeout,
692 const IsochronousTransferCallback& callback) { 709 const IsochronousTransferCallback& callback) {
710 DCHECK(sequence_checker_.CalledOnValidSequence());
693 if (!device_) { 711 if (!device_) {
694 ReportIsochronousError(packet_lengths, callback, 712 ReportIsochronousError(packet_lengths, callback,
695 UsbTransferStatus::DISCONNECT); 713 UsbTransferStatus::DISCONNECT);
696 return; 714 return;
697 } 715 }
698 716
699 auto it = endpoints_.find(endpoint_address); 717 auto it = endpoints_.find(endpoint_address);
700 if (it == endpoints_.end()) { 718 if (it == endpoints_.end()) {
701 USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address) 719 USB_LOG(USER) << "Endpoint address " << static_cast<int>(endpoint_address)
702 << " is not part of a claimed interface."; 720 << " is not part of a claimed interface.";
(...skipping 27 matching lines...) Expand all
730 } 748 }
731 749
732 void UsbDeviceHandleUsbfs::GenericTransferInternal( 750 void UsbDeviceHandleUsbfs::GenericTransferInternal(
733 UsbTransferDirection direction, 751 UsbTransferDirection direction,
734 uint8_t endpoint_number, 752 uint8_t endpoint_number,
735 scoped_refptr<net::IOBuffer> buffer, 753 scoped_refptr<net::IOBuffer> buffer,
736 size_t length, 754 size_t length,
737 unsigned int timeout, 755 unsigned int timeout,
738 const TransferCallback& callback, 756 const TransferCallback& callback,
739 scoped_refptr<base::SingleThreadTaskRunner> callback_runner) { 757 scoped_refptr<base::SingleThreadTaskRunner> callback_runner) {
758 DCHECK(sequence_checker_.CalledOnValidSequence());
740 if (!device_) { 759 if (!device_) {
741 callback_runner->PostTask( 760 callback_runner->PostTask(
742 FROM_HERE, 761 FROM_HERE,
743 base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0)); 762 base::Bind(callback, UsbTransferStatus::DISCONNECT, nullptr, 0));
744 return; 763 return;
745 } 764 }
746 765
747 uint8_t endpoint_address = 766 uint8_t endpoint_address =
748 ConvertEndpointDirection(direction) | endpoint_number; 767 ConvertEndpointDirection(direction) | endpoint_number;
749 auto it = endpoints_.find(endpoint_address); 768 auto it = endpoints_.find(endpoint_address);
(...skipping 22 matching lines...) Expand all
772 USB_PLOG(DEBUG) << "Failed to submit transfer"; 791 USB_PLOG(DEBUG) << "Failed to submit transfer";
773 callback_runner->PostTask( 792 callback_runner->PostTask(
774 FROM_HERE, base::Bind(callback, ConvertTransferResult(rc), nullptr, 0)); 793 FROM_HERE, base::Bind(callback, ConvertTransferResult(rc), nullptr, 0));
775 } else { 794 } else {
776 SetUpTimeoutCallback(transfer.get(), timeout); 795 SetUpTimeoutCallback(transfer.get(), timeout);
777 transfers_.push_back(std::move(transfer)); 796 transfers_.push_back(std::move(transfer));
778 } 797 }
779 } 798 }
780 799
781 void UsbDeviceHandleUsbfs::ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs) { 800 void UsbDeviceHandleUsbfs::ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs) {
801 DCHECK(sequence_checker_.CalledOnValidSequence());
782 for (auto* urb : urbs) { 802 for (auto* urb : urbs) {
783 Transfer* transfer = static_cast<Transfer*>(urb->usercontext); 803 Transfer* transfer = static_cast<Transfer*>(urb->usercontext);
784 DCHECK_EQ(urb, &transfer->urb); 804 DCHECK_EQ(urb, &transfer->urb);
785 805
786 if (transfer->cancelled) { 806 if (transfer->cancelled) {
787 transfer->reaped = true; 807 transfer->reaped = true;
788 if (transfer->discarded) 808 if (transfer->discarded)
789 RemoveFromTransferList(transfer); 809 RemoveFromTransferList(transfer);
790 } else { 810 } else {
791 TransferComplete(RemoveFromTransferList(transfer)); 811 TransferComplete(RemoveFromTransferList(transfer));
792 } 812 }
793 } 813 }
794 } 814 }
795 815
796 void UsbDeviceHandleUsbfs::TransferComplete( 816 void UsbDeviceHandleUsbfs::TransferComplete(
797 std::unique_ptr<Transfer> transfer) { 817 std::unique_ptr<Transfer> transfer) {
818 DCHECK(sequence_checker_.CalledOnValidSequence());
798 if (transfer->cancelled) 819 if (transfer->cancelled)
799 return; 820 return;
800 821
801 // The transfer will soon be freed. Cancel the timeout callback so that the 822 // The transfer will soon be freed. Cancel the timeout callback so that the
802 // raw pointer it holds to |transfer| is not used. 823 // raw pointer it holds to |transfer| is not used.
803 transfer->timeout_closure.Cancel(); 824 transfer->timeout_closure.Cancel();
804 825
805 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { 826 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) {
806 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); 827 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets);
807 for (size_t i = 0; i < packets.size(); ++i) { 828 for (size_t i = 0; i < packets.size(); ++i) {
(...skipping 14 matching lines...) Expand all
822 transfer->control_transfer_buffer->data() + 8, 843 transfer->control_transfer_buffer->data() + 8,
823 transfer->urb.actual_length); 844 transfer->urb.actual_length);
824 } 845 }
825 846
826 transfer->RunCallback(ConvertTransferResult(-transfer->urb.status), 847 transfer->RunCallback(ConvertTransferResult(-transfer->urb.status),
827 transfer->urb.actual_length); 848 transfer->urb.actual_length);
828 } 849 }
829 } 850 }
830 851
831 void UsbDeviceHandleUsbfs::RefreshEndpointInfo() { 852 void UsbDeviceHandleUsbfs::RefreshEndpointInfo() {
853 DCHECK(sequence_checker_.CalledOnValidSequence());
832 endpoints_.clear(); 854 endpoints_.clear();
833 855
834 const UsbConfigDescriptor* config = device_->active_configuration(); 856 const UsbConfigDescriptor* config = device_->active_configuration();
835 if (!config) 857 if (!config)
836 return; 858 return;
837 859
838 for (const auto& entry : interfaces_) { 860 for (const auto& entry : interfaces_) {
839 auto interface_it = std::find_if( 861 auto interface_it = std::find_if(
840 config->interfaces.begin(), config->interfaces.end(), 862 config->interfaces.begin(), config->interfaces.end(),
841 [entry](const UsbInterfaceDescriptor& interface) { 863 [entry](const UsbInterfaceDescriptor& interface) {
842 uint8_t interface_number = entry.first; 864 uint8_t interface_number = entry.first;
843 uint8_t alternate_setting = entry.second.alternate_setting; 865 uint8_t alternate_setting = entry.second.alternate_setting;
844 return interface.interface_number == interface_number && 866 return interface.interface_number == interface_number &&
845 interface.alternate_setting == alternate_setting; 867 interface.alternate_setting == alternate_setting;
846 }); 868 });
847 DCHECK(interface_it != config->interfaces.end()); 869 DCHECK(interface_it != config->interfaces.end());
848 870
849 for (const auto& endpoint : interface_it->endpoints) { 871 for (const auto& endpoint : interface_it->endpoints) {
850 EndpointInfo& info = endpoints_[endpoint.address]; 872 EndpointInfo& info = endpoints_[endpoint.address];
851 info.type = endpoint.transfer_type; 873 info.type = endpoint.transfer_type;
852 info.interface = &*interface_it; 874 info.interface = &*interface_it;
853 } 875 }
854 } 876 }
855 } 877 }
856 878
857 void UsbDeviceHandleUsbfs::ReportIsochronousError( 879 void UsbDeviceHandleUsbfs::ReportIsochronousError(
858 const std::vector<uint32_t>& packet_lengths, 880 const std::vector<uint32_t>& packet_lengths,
859 const UsbDeviceHandle::IsochronousTransferCallback& callback, 881 const UsbDeviceHandle::IsochronousTransferCallback& callback,
860 UsbTransferStatus status) { 882 UsbTransferStatus status) {
883 DCHECK(sequence_checker_.CalledOnValidSequence());
861 std::vector<UsbDeviceHandle::IsochronousPacket> packets( 884 std::vector<UsbDeviceHandle::IsochronousPacket> packets(
862 packet_lengths.size()); 885 packet_lengths.size());
863 for (size_t i = 0; i < packet_lengths.size(); ++i) { 886 for (size_t i = 0; i < packet_lengths.size(); ++i) {
864 packets[i].length = packet_lengths[i]; 887 packets[i].length = packet_lengths[i];
865 packets[i].transferred_length = 0; 888 packets[i].transferred_length = 0;
866 packets[i].status = status; 889 packets[i].status = status;
867 } 890 }
868 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr, packets)); 891 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr, packets));
869 } 892 }
870 893
871 void UsbDeviceHandleUsbfs::SetUpTimeoutCallback(Transfer* transfer, 894 void UsbDeviceHandleUsbfs::SetUpTimeoutCallback(Transfer* transfer,
872 unsigned int timeout) { 895 unsigned int timeout) {
873 if (timeout > 0) { 896 DCHECK(sequence_checker_.CalledOnValidSequence());
874 transfer->timeout_closure.Reset( 897 if (timeout == 0)
875 base::Bind(&UsbDeviceHandleUsbfs::CancelTransfer, this, transfer, 898 return;
876 UsbTransferStatus::TIMEOUT)); 899
877 task_runner_->PostDelayedTask(FROM_HERE, 900 transfer->timeout_closure.Reset(
878 transfer->timeout_closure.callback(), 901 base::Bind(&UsbDeviceHandleUsbfs::OnTimeout, this, transfer));
879 base::TimeDelta::FromMilliseconds(timeout)); 902 task_runner_->PostDelayedTask(FROM_HERE, transfer->timeout_closure.callback(),
880 } 903 base::TimeDelta::FromMilliseconds(timeout));
904 }
905
906 void UsbDeviceHandleUsbfs::OnTimeout(Transfer* transfer) {
907 CancelTransfer(transfer, UsbTransferStatus::TIMEOUT);
881 } 908 }
882 909
883 std::unique_ptr<UsbDeviceHandleUsbfs::Transfer> 910 std::unique_ptr<UsbDeviceHandleUsbfs::Transfer>
884 UsbDeviceHandleUsbfs::RemoveFromTransferList(Transfer* transfer_ptr) { 911 UsbDeviceHandleUsbfs::RemoveFromTransferList(Transfer* transfer_ptr) {
912 DCHECK(sequence_checker_.CalledOnValidSequence());
885 auto it = std::find_if( 913 auto it = std::find_if(
886 transfers_.begin(), transfers_.end(), 914 transfers_.begin(), transfers_.end(),
887 [transfer_ptr](const std::unique_ptr<Transfer>& transfer) -> bool { 915 [transfer_ptr](const std::unique_ptr<Transfer>& transfer) -> bool {
888 return transfer.get() == transfer_ptr; 916 return transfer.get() == transfer_ptr;
889 }); 917 });
890 DCHECK(it != transfers_.end()); 918 DCHECK(it != transfers_.end());
891 std::unique_ptr<Transfer> transfer = std::move(*it); 919 std::unique_ptr<Transfer> transfer = std::move(*it);
892 transfers_.erase(it); 920 transfers_.erase(it);
893 return transfer; 921 return transfer;
894 } 922 }
895 923
896 void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer, 924 void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer,
897 UsbTransferStatus status) { 925 UsbTransferStatus status) {
926 DCHECK(sequence_checker_.CalledOnValidSequence());
927 DCHECK(device_);
928
898 if (transfer->cancelled) 929 if (transfer->cancelled)
899 return; 930 return;
900 931
901 // |transfer| must stay in |transfers_| as it is still being processed by the 932 // |transfer| must stay in |transfers_| as it is still being processed by the
902 // kernel and will be reaped later. 933 // kernel and will be reaped later.
903 transfer->cancelled = true; 934 transfer->cancelled = true;
935
936 blocking_task_runner_->PostTask(
937 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::DiscardUrb,
938 base::Unretained(helper_.get()), transfer));
939
940 // Cancelling |timeout_closure| and running completion callbacks may free
941 // |this| so these operations must be performed at the end of this function.
904 transfer->timeout_closure.Cancel(); 942 transfer->timeout_closure.Cancel();
905 943
906 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { 944 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) {
907 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); 945 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets);
908 for (size_t i = 0; i < packets.size(); ++i) { 946 for (size_t i = 0; i < packets.size(); ++i) {
909 packets[i].length = transfer->urb.iso_frame_desc[i].length; 947 packets[i].length = transfer->urb.iso_frame_desc[i].length;
910 packets[i].transferred_length = 0; 948 packets[i].transferred_length = 0;
911 packets[i].status = status; 949 packets[i].status = status;
912 } 950 }
913 transfer->RunIsochronousCallback(packets); 951 transfer->RunIsochronousCallback(packets);
914 } else { 952 } else {
915 transfer->RunCallback(status, 0); 953 transfer->RunCallback(status, 0);
916 } 954 }
917
918 blocking_task_runner_->PostTask(
919 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::DiscardUrb,
920 base::Unretained(helper_.get()), transfer));
921 } 955 }
922 956
923
924 void UsbDeviceHandleUsbfs::UrbDiscarded(Transfer* transfer) { 957 void UsbDeviceHandleUsbfs::UrbDiscarded(Transfer* transfer) {
958 DCHECK(sequence_checker_.CalledOnValidSequence());
925 transfer->discarded = true; 959 transfer->discarded = true;
926 if (transfer->reaped) 960 if (transfer->reaped)
927 RemoveFromTransferList(transfer); 961 RemoveFromTransferList(transfer);
928 } 962 }
929 963
930 } // namespace device 964 } // namespace device
OLDNEW
« no previous file with comments | « device/usb/usb_device_handle_usbfs.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698