summaryrefslogtreecommitdiffstats
path: root/fastboot
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-05-21 13:20:47 -0700
committerJeff Brown <jeffbrown@google.com>2010-05-21 13:24:25 -0700
commitb64063737e93638a09205e9310b58d8ddd7138ec (patch)
treeef2fa3aba61285639dc8f6462b536ec1a3c6ae40 /fastboot
parent53a79a841b4afa5e7dc3e05cfd04b5ae44de95b6 (diff)
downloadsystem_core-b64063737e93638a09205e9310b58d8ddd7138ec.zip
system_core-b64063737e93638a09205e9310b58d8ddd7138ec.tar.gz
system_core-b64063737e93638a09205e9310b58d8ddd7138ec.tar.bz2
Fix kernel panics in fastboot on OS X.
The kernel panic seems to be related to the driver trying to allocate too many pages from the IO mapper. That may be caused by the fact that we try to perform a 100+ MiB transfer in a single IO operation. This change breaks the transfer down into 1 MiB chunks. So far after a day of testing, no kernel panics have occurred compared to 5 in the previous 24 hours! Change-Id: I8d27a546e0c0bf4fe2f0fc7fcad65a88d3e6bee0
Diffstat (limited to 'fastboot')
-rw-r--r--fastboot/usb_osx.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/fastboot/usb_osx.c b/fastboot/usb_osx.c
index 0b0512d..9488687 100644
--- a/fastboot/usb_osx.c
+++ b/fastboot/usb_osx.c
@@ -64,7 +64,7 @@ struct usb_handle
/** Try out all the interfaces and see if there's a match. Returns 0 on
* success, -1 on failure. */
-static int try_interfaces(IOUSBDeviceInterface **dev, usb_handle *handle) {
+static int try_interfaces(IOUSBDeviceInterface182 **dev, usb_handle *handle) {
IOReturn kr;
IOUSBFindInterfaceRequest request;
io_iterator_t iterator;
@@ -515,8 +515,29 @@ int usb_write(usb_handle *h, const void *data, int len) {
return -1;
}
+#if 0
result = (*h->interface)->WritePipe(
h->interface, h->bulkOut, (void *)data, len);
+#else
+ /* Attempt to work around crashes in the USB driver that may be caused
+ * by trying to write too much data at once. The kernel IOCopyMapper
+ * panics if a single iovmAlloc needs more than half of its mapper pages.
+ */
+ const int maxLenToSend = 1048576; // 1 MiB
+ int lenRemaining = len;
+ result = 0;
+ while (lenRemaining > 0) {
+ int lenToSend = lenRemaining > maxLenToSend
+ ? maxLenToSend : lenRemaining;
+
+ result = (*h->interface)->WritePipe(
+ h->interface, h->bulkOut, (void *)data, lenToSend);
+ if (result != 0) break;
+
+ lenRemaining -= lenToSend;
+ data = (const char*)data + lenToSend;
+ }
+#endif
#if 0
if ((result == 0) && (h->zero_mask)) {