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