Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 Transfer(scoped_refptr<net::IOBuffer> buffer, | 229 Transfer(scoped_refptr<net::IOBuffer> buffer, |
| 230 const IsochronousTransferCallback& callback); | 230 const IsochronousTransferCallback& callback); |
| 231 ~Transfer(); | 231 ~Transfer(); |
| 232 | 232 |
| 233 void* operator new(std::size_t size, size_t number_of_iso_packets); | 233 void* operator new(std::size_t size, size_t number_of_iso_packets); |
| 234 void RunCallback(UsbTransferStatus status, size_t bytes_transferred); | 234 void RunCallback(UsbTransferStatus status, size_t bytes_transferred); |
| 235 void RunIsochronousCallback(const std::vector<IsochronousPacket>& packets); | 235 void RunIsochronousCallback(const std::vector<IsochronousPacket>& packets); |
| 236 | 236 |
| 237 scoped_refptr<net::IOBuffer> control_transfer_buffer; | 237 scoped_refptr<net::IOBuffer> control_transfer_buffer; |
| 238 scoped_refptr<net::IOBuffer> buffer; | 238 scoped_refptr<net::IOBuffer> buffer; |
| 239 TransferCallback callback; | |
| 240 IsochronousTransferCallback isoc_callback; | |
| 241 scoped_refptr<base::SingleThreadTaskRunner> callback_runner; | |
| 242 base::CancelableClosure timeout_closure; | 239 base::CancelableClosure timeout_closure; |
| 243 bool cancelled = false; | 240 bool cancelled = false; |
| 244 | 241 |
| 245 // When the URB is |cancelled| these two flags track whether the URB has both | 242 // When the URB is |cancelled| these two flags track whether the URB has both |
| 246 // been |discarded| and |reaped| since the possiblity of last-minute | 243 // been |discarded| and |reaped| since the possiblity of last-minute |
| 247 // completion makes these two conditions race. | 244 // completion makes these two conditions race. |
| 248 bool discarded = false; | 245 bool discarded = false; |
| 249 bool reaped = false; | 246 bool reaped = false; |
| 250 | 247 |
| 251 // The |urb| field must be the last in the struct so that the extra space | 248 // The |urb| field must be the last in the struct so that the extra space |
| 252 // allocated by the overridden new function above extends the length of its | 249 // allocated by the overridden new function above extends the length of its |
| 253 // |iso_frame_desc| field. | 250 // |iso_frame_desc| field. |
| 254 usbdevfs_urb urb; | 251 usbdevfs_urb urb; |
| 255 | 252 |
| 256 private: | 253 private: |
| 254 TransferCallback callback; | |
|
juncai
2016/12/20 18:18:54
The comment for the above |urb| variable says: "Th
Reilly Grant (use Gerrit)
2016/12/20 20:28:59
Done, good catch.
| |
| 255 IsochronousTransferCallback isoc_callback; | |
| 256 scoped_refptr<base::SingleThreadTaskRunner> callback_runner; | |
| 257 | |
| 257 DISALLOW_COPY_AND_ASSIGN(Transfer); | 258 DISALLOW_COPY_AND_ASSIGN(Transfer); |
| 258 }; | 259 }; |
| 259 | 260 |
| 260 UsbDeviceHandleUsbfs::Transfer::Transfer( | 261 UsbDeviceHandleUsbfs::Transfer::Transfer( |
| 261 scoped_refptr<net::IOBuffer> buffer, | 262 scoped_refptr<net::IOBuffer> buffer, |
| 262 const TransferCallback& callback, | 263 const TransferCallback& callback, |
| 263 scoped_refptr<base::SingleThreadTaskRunner> callback_runner) | 264 scoped_refptr<base::SingleThreadTaskRunner> callback_runner) |
| 264 : buffer(buffer), callback(callback), callback_runner(callback_runner) { | 265 : buffer(buffer), callback(callback), callback_runner(callback_runner) { |
| 265 memset(&urb, 0, sizeof(urb)); | 266 memset(&urb, 0, sizeof(urb)); |
| 266 urb.usercontext = this; | 267 urb.usercontext = this; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 285 void* p = ::operator new( | 286 void* p = ::operator new( |
| 286 size + sizeof(usbdevfs_iso_packet_desc) * number_of_iso_packets); | 287 size + sizeof(usbdevfs_iso_packet_desc) * number_of_iso_packets); |
| 287 Transfer* transfer = static_cast<Transfer*>(p); | 288 Transfer* transfer = static_cast<Transfer*>(p); |
| 288 transfer->urb.number_of_packets = number_of_iso_packets; | 289 transfer->urb.number_of_packets = number_of_iso_packets; |
| 289 return p; | 290 return p; |
| 290 } | 291 } |
| 291 | 292 |
| 292 void UsbDeviceHandleUsbfs::Transfer::RunCallback(UsbTransferStatus status, | 293 void UsbDeviceHandleUsbfs::Transfer::RunCallback(UsbTransferStatus status, |
| 293 size_t bytes_transferred) { | 294 size_t bytes_transferred) { |
| 294 DCHECK_NE(urb.type, USBDEVFS_URB_TYPE_ISO); | 295 DCHECK_NE(urb.type, USBDEVFS_URB_TYPE_ISO); |
| 295 DCHECK(!callback.is_null()); | 296 DCHECK(callback); |
| 296 if (!callback_runner || callback_runner->BelongsToCurrentThread()) { | 297 if (!callback_runner || callback_runner->BelongsToCurrentThread()) { |
| 297 callback.Run(status, buffer, bytes_transferred); | 298 callback.Run(status, buffer, bytes_transferred); |
| 298 } else { | 299 } else { |
| 299 callback_runner->PostTask( | 300 callback_runner->PostTask( |
| 300 FROM_HERE, base::Bind(callback, status, buffer, bytes_transferred)); | 301 FROM_HERE, base::Bind(callback, status, buffer, bytes_transferred)); |
| 301 } | 302 } |
| 303 callback.Reset(); | |
| 302 } | 304 } |
| 303 | 305 |
| 304 void UsbDeviceHandleUsbfs::Transfer::RunIsochronousCallback( | 306 void UsbDeviceHandleUsbfs::Transfer::RunIsochronousCallback( |
| 305 const std::vector<IsochronousPacket>& packets) { | 307 const std::vector<IsochronousPacket>& packets) { |
| 306 DCHECK_EQ(urb.type, USBDEVFS_URB_TYPE_ISO); | 308 DCHECK_EQ(urb.type, USBDEVFS_URB_TYPE_ISO); |
| 307 DCHECK(!isoc_callback.is_null()); | 309 DCHECK(isoc_callback); |
| 308 isoc_callback.Run(buffer, packets); | 310 isoc_callback.Run(buffer, packets); |
| 311 isoc_callback.Reset(); | |
| 309 } | 312 } |
| 310 | 313 |
| 311 UsbDeviceHandleUsbfs::UsbDeviceHandleUsbfs( | 314 UsbDeviceHandleUsbfs::UsbDeviceHandleUsbfs( |
| 312 scoped_refptr<UsbDevice> device, | 315 scoped_refptr<UsbDevice> device, |
| 313 base::ScopedFD fd, | 316 base::ScopedFD fd, |
| 314 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) | 317 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) |
| 315 : device_(device), | 318 : device_(device), |
| 316 fd_(std::move(fd)), | 319 fd_(std::move(fd)), |
| 317 blocking_task_runner_(blocking_task_runner) { | 320 blocking_task_runner_(blocking_task_runner) { |
| 318 DCHECK(device_); | 321 DCHECK(device_); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 332 return device_; | 335 return device_; |
| 333 } | 336 } |
| 334 | 337 |
| 335 void UsbDeviceHandleUsbfs::Close() { | 338 void UsbDeviceHandleUsbfs::Close() { |
| 336 if (!device_) | 339 if (!device_) |
| 337 return; // Already closed. | 340 return; // Already closed. |
| 338 | 341 |
| 339 // On the |task_runner_| thread check |device_| to see if the handle is | 342 // On the |task_runner_| thread check |device_| to see if the handle is |
| 340 // closed. On the |blocking_task_runner_| thread check |fd_.is_valid()| to | 343 // closed. On the |blocking_task_runner_| thread check |fd_.is_valid()| to |
| 341 // see if the handle is closed. | 344 // see if the handle is closed. |
| 345 device_->HandleClosed(this); | |
| 346 device_ = nullptr; | |
| 347 | |
| 342 for (const auto& transfer : transfers_) | 348 for (const auto& transfer : transfers_) |
| 343 CancelTransfer(transfer.get(), USB_TRANSFER_CANCELLED); | 349 CancelTransfer(transfer.get(), USB_TRANSFER_CANCELLED); |
| 344 device_->HandleClosed(this); | 350 |
| 345 device_ = nullptr; | |
| 346 blocking_task_runner_->PostTask( | 351 blocking_task_runner_->PostTask( |
| 347 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::CloseBlocking, this)); | 352 FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::CloseBlocking, this)); |
| 348 } | 353 } |
| 349 | 354 |
| 350 void UsbDeviceHandleUsbfs::SetConfiguration(int configuration_value, | 355 void UsbDeviceHandleUsbfs::SetConfiguration(int configuration_value, |
| 351 const ResultCallback& callback) { | 356 const ResultCallback& callback) { |
| 352 // USBDEVFS_SETCONFIGURATION synchronously issues a SET_CONFIGURATION request | 357 // USBDEVFS_SETCONFIGURATION synchronously issues a SET_CONFIGURATION request |
| 353 // to the device so it must be performed on a thread where it is okay to | 358 // to the device so it must be performed on a thread where it is okay to |
| 354 // block. | 359 // block. |
| 355 blocking_task_runner_->PostTask( | 360 blocking_task_runner_->PostTask( |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 841 return transfer.get() == transfer_ptr; | 846 return transfer.get() == transfer_ptr; |
| 842 }); | 847 }); |
| 843 DCHECK(it != transfers_.end()); | 848 DCHECK(it != transfers_.end()); |
| 844 std::unique_ptr<Transfer> transfer = std::move(*it); | 849 std::unique_ptr<Transfer> transfer = std::move(*it); |
| 845 transfers_.erase(it); | 850 transfers_.erase(it); |
| 846 return transfer; | 851 return transfer; |
| 847 } | 852 } |
| 848 | 853 |
| 849 void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer, | 854 void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer, |
| 850 UsbTransferStatus status) { | 855 UsbTransferStatus status) { |
| 856 if (transfer->cancelled) | |
| 857 return; | |
| 858 | |
| 851 // |transfer| must stay in |transfers_| as it is still being processed by the | 859 // |transfer| must stay in |transfers_| as it is still being processed by the |
| 852 // kernel and will be reaped later. | 860 // kernel and will be reaped later. |
| 853 transfer->cancelled = true; | 861 transfer->cancelled = true; |
| 854 transfer->timeout_closure.Cancel(); | 862 transfer->timeout_closure.Cancel(); |
| 855 | 863 |
| 856 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { | 864 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { |
| 857 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); | 865 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); |
| 858 for (size_t i = 0; i < packets.size(); ++i) { | 866 for (size_t i = 0; i < packets.size(); ++i) { |
| 859 packets[i].length = transfer->urb.iso_frame_desc[i].length; | 867 packets[i].length = transfer->urb.iso_frame_desc[i].length; |
| 860 packets[i].transferred_length = 0; | 868 packets[i].transferred_length = 0; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 879 base::Bind(&UsbDeviceHandleUsbfs::UrbDiscarded, this, transfer)); | 887 base::Bind(&UsbDeviceHandleUsbfs::UrbDiscarded, this, transfer)); |
| 880 } | 888 } |
| 881 | 889 |
| 882 void UsbDeviceHandleUsbfs::UrbDiscarded(Transfer* transfer) { | 890 void UsbDeviceHandleUsbfs::UrbDiscarded(Transfer* transfer) { |
| 883 transfer->discarded = true; | 891 transfer->discarded = true; |
| 884 if (transfer->reaped) | 892 if (transfer->reaped) |
| 885 RemoveFromTransferList(transfer); | 893 RemoveFromTransferList(transfer); |
| 886 } | 894 } |
| 887 | 895 |
| 888 } // namespace device | 896 } // namespace device |
| OLD | NEW |