Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6406373 authored by Jeff Brown's avatar Jeff Brown
Browse files

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
parent 53a79a84
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -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)) {