summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libirecovery.c212
1 files changed, 151 insertions, 61 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c
index f0acce0..9742cb5 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -454,6 +454,26 @@ static unsigned int crc32_lookup_t1[256] = {
454#define crc32_step(a,b) \ 454#define crc32_step(a,b) \
455 a = (crc32_lookup_t1[(a & 0xFF) ^ ((unsigned char)b)] ^ (a >> 8)) 455 a = (crc32_lookup_t1[(a & 0xFF) ^ ((unsigned char)b)] ^ (a >> 8))
456 456
457#ifdef WIN32
458#pragma pack(1)
459typedef struct {
460 uint16_t vid;
461 uint16_t pid;
462 uint32_t unk;
463 char nonces[255];
464 char serial[255];
465 char manufacturer[255];
466 char product[255];
467} KIS_device_info;
468
469typedef struct {
470 uint8_t data[0x4000];
471 uint32_t size;
472 uint32_t unused;
473 uint64_t address;
474} KIS_upload_chunk;
475#pragma pack()
476#else
457#pragma pack(1) 477#pragma pack(1)
458typedef struct { 478typedef struct {
459 uint16_t sequence; // A sequence number 479 uint16_t sequence; // A sequence number
@@ -525,6 +545,7 @@ typedef struct {
525 uint32_t status; 545 uint32_t status;
526} KIS_generic_reply; 546} KIS_generic_reply;
527#pragma pack() 547#pragma pack()
548#endif
528 549
529static THREAD_T th_event_handler = THREAD_T_NULL; 550static THREAD_T th_event_handler = THREAD_T_NULL;
530struct collection listeners; 551struct collection listeners;
@@ -873,6 +894,7 @@ static void irecv_copy_nonce_with_tag(irecv_client_t client, const char* tag, un
873 irecv_copy_nonce_with_tag_from_buffer(tag,nonce,nonce_size,buf); 894 irecv_copy_nonce_with_tag_from_buffer(tag,nonce,nonce_size,buf);
874} 895}
875 896
897#ifndef WIN32
876static irecv_error_t irecv_kis_request_init(KIS_req_header *hdr, uint8_t portal, uint16_t index, size_t argCount, size_t payloadSize, size_t rplWords) 898static irecv_error_t irecv_kis_request_init(KIS_req_header *hdr, uint8_t portal, uint16_t index, size_t argCount, size_t payloadSize, size_t rplWords)
877{ 899{
878 if (argCount > UINT8_MAX) { 900 if (argCount > UINT8_MAX) {
@@ -1001,9 +1023,11 @@ static int irecv_kis_read_string(KIS_device_info *di, size_t off, char *buf, siz
1001 1023
1002 return len/2; 1024 return len/2;
1003} 1025}
1026#endif
1004 1027
1005static irecv_error_t irecv_kis_init(irecv_client_t client) 1028static irecv_error_t irecv_kis_init(irecv_client_t client)
1006{ 1029{
1030#ifndef WIN32
1007 irecv_error_t err = irecv_kis_config_write32(client, KIS_PORTAL_CONFIG, KIS_INDEX_ENABLE_A, KIS_ENABLE_A_VAL); 1031 irecv_error_t err = irecv_kis_config_write32(client, KIS_PORTAL_CONFIG, KIS_INDEX_ENABLE_A, KIS_ENABLE_A_VAL);
1008 if (err != IRECV_E_SUCCESS) { 1032 if (err != IRECV_E_SUCCESS) {
1009 debug("Failed to write to KIS_INDEX_ENABLE_A, error %d\n", err); 1033 debug("Failed to write to KIS_INDEX_ENABLE_A, error %d\n", err);
@@ -1015,7 +1039,7 @@ static irecv_error_t irecv_kis_init(irecv_client_t client)
1015 debug("Failed to write to KIS_INDEX_ENABLE_B, error %d\n", err); 1039 debug("Failed to write to KIS_INDEX_ENABLE_B, error %d\n", err);
1016 return err; 1040 return err;
1017 } 1041 }
1018 1042#endif
1019 client->isKIS = 1; 1043 client->isKIS = 1;
1020 1044
1021 return IRECV_E_SUCCESS; 1045 return IRECV_E_SUCCESS;
@@ -1024,7 +1048,23 @@ static irecv_error_t irecv_kis_init(irecv_client_t client)
1024static irecv_error_t irecv_kis_load_device_info(irecv_client_t client) 1048static irecv_error_t irecv_kis_load_device_info(irecv_client_t client)
1025{ 1049{
1026 debug("Loading device info in KIS mode...\n"); 1050 debug("Loading device info in KIS mode...\n");
1027 1051#ifdef WIN32
1052 KIS_device_info kisInfo;
1053 DWORD transferred = 0;
1054 int ret = DeviceIoControl(client->handle, 0x220004, NULL, 0, &kisInfo, sizeof(kisInfo), (PDWORD)&transferred, NULL);
1055 if (ret) {
1056 debug("Serial: %s\n", kisInfo.serial);
1057 irecv_load_device_info_from_iboot_string(client, kisInfo.serial);
1058 debug("Manufacturer: %s\n", kisInfo.manufacturer);
1059 debug("Product: %s\n", kisInfo.product);
1060 debug("Nonces: %s\n", kisInfo.nonces);
1061 irecv_copy_nonce_with_tag_from_buffer("NONC", &client->device_info.ap_nonce, &client->device_info.ap_nonce_size, kisInfo.nonces);
1062 irecv_copy_nonce_with_tag_from_buffer("SNON", &client->device_info.sep_nonce, &client->device_info.sep_nonce_size, kisInfo.nonces);
1063 debug("VID: 0x%04x\n", kisInfo.vid);
1064 debug("PID: 0x%04x\n", kisInfo.pid);
1065 }
1066 client->mode = kisInfo.pid;
1067#else
1028 KIS_req_header req = {}; 1068 KIS_req_header req = {};
1029 KIS_device_info di = {}; 1069 KIS_device_info di = {};
1030 irecv_error_t err = irecv_kis_request_init(&req, KIS_PORTAL_RSM, KIS_INDEX_GET_INFO, 0, 0, sizeof(di.deviceInfo)/4); 1070 irecv_error_t err = irecv_kis_request_init(&req, KIS_PORTAL_RSM, KIS_INDEX_GET_INFO, 0, 0, sizeof(di.deviceInfo)/4);
@@ -1072,13 +1112,14 @@ static irecv_error_t irecv_kis_load_device_info(irecv_client_t client)
1072 debug("PID: 0x%04x\n", di.deviceDescriptor.idProduct); 1112 debug("PID: 0x%04x\n", di.deviceDescriptor.idProduct);
1073 1113
1074 client->mode = di.deviceDescriptor.idProduct; 1114 client->mode = di.deviceDescriptor.idProduct;
1075 1115#endif
1076 return IRECV_E_SUCCESS; 1116 return IRECV_E_SUCCESS;
1077} 1117}
1078 1118
1079#ifdef WIN32 1119#ifdef WIN32
1080static const GUID GUID_DEVINTERFACE_IBOOT = {0xED82A167L, 0xD61A, 0x4AF6, {0x9A, 0xB6, 0x11, 0xE5, 0x22, 0x36, 0xC5, 0x76}}; 1120static const GUID GUID_DEVINTERFACE_IBOOT = {0xED82A167L, 0xD61A, 0x4AF6, {0x9A, 0xB6, 0x11, 0xE5, 0x22, 0x36, 0xC5, 0x76}};
1081static const GUID GUID_DEVINTERFACE_DFU = {0xB8085869L, 0xFEB9, 0x404B, {0x8C, 0xB1, 0x1E, 0x5C, 0x14, 0xFA, 0x8C, 0x54}}; 1121static const GUID GUID_DEVINTERFACE_DFU = {0xB8085869L, 0xFEB9, 0x404B, {0x8C, 0xB1, 0x1E, 0x5C, 0x14, 0xFA, 0x8C, 0x54}};
1122static const GUID GUID_DEVINTERFACE_KIS = {0xB36F4137L, 0xF4EF, 0x4BFC, {0xA2, 0x5A, 0xC2, 0x41, 0x07, 0x68, 0xEE, 0x37}};
1082 1123
1083typedef struct usb_control_request { 1124typedef struct usb_control_request {
1084 uint8_t bmRequestType; 1125 uint8_t bmRequestType;
@@ -1093,7 +1134,7 @@ typedef struct usb_control_request {
1093static irecv_error_t win32_open_with_ecid(irecv_client_t* client, uint64_t ecid) 1134static irecv_error_t win32_open_with_ecid(irecv_client_t* client, uint64_t ecid)
1094{ 1135{
1095 int found = 0; 1136 int found = 0;
1096 const GUID *guids[] = { &GUID_DEVINTERFACE_DFU, &GUID_DEVINTERFACE_IBOOT, NULL }; 1137 const GUID *guids[] = { &GUID_DEVINTERFACE_KIS, &GUID_DEVINTERFACE_DFU, &GUID_DEVINTERFACE_IBOOT, NULL };
1097 irecv_client_t _client = (irecv_client_t) malloc(sizeof(struct irecv_client_private)); 1138 irecv_client_t _client = (irecv_client_t) malloc(sizeof(struct irecv_client_private));
1098 memset(_client, 0, sizeof(struct irecv_client_private)); 1139 memset(_client, 0, sizeof(struct irecv_client_private));
1099 1140
@@ -1117,21 +1158,32 @@ static irecv_error_t win32_open_with_ecid(irecv_client_t* client, uint64_t ecid)
1117 } 1158 }
1118 1159
1119 unsigned int pid = 0; 1160 unsigned int pid = 0;
1120 if (sscanf(details->DevicePath, "\\\\?\\usb#vid_05ac&pid_%04x", &pid)!= 1) { 1161 unsigned int vid = 0;
1121 debug("%s: ERROR: failed to parse PID! path: %s\n", __func__, details->DevicePath); 1162 if (sscanf(details->DevicePath, "\\\\?\\%*3s#vid_%04x&pid_%04x", &vid, &pid) != 2) {
1163 debug("%s: ERROR: failed to parse VID/PID! path: %s\n", __func__, details->DevicePath);
1122 free(details); 1164 free(details);
1123 continue; 1165 continue;
1124 } 1166 }
1167 if (vid != APPLE_VENDOR_ID) {
1168 free(details);
1169 continue;
1170 }
1171
1125 // make sure the current device is actually in the right mode for the given driver interface 1172 // make sure the current device is actually in the right mode for the given driver interface
1126 if ((guids[k] == &GUID_DEVINTERFACE_DFU && pid != IRECV_K_DFU_MODE && pid != IRECV_K_WTF_MODE) 1173 if ((guids[k] == &GUID_DEVINTERFACE_DFU && pid != IRECV_K_DFU_MODE && pid != IRECV_K_WTF_MODE)
1127 || (guids[k] == &GUID_DEVINTERFACE_IBOOT && (pid < IRECV_K_RECOVERY_MODE_1 || pid > IRECV_K_RECOVERY_MODE_4)) 1174 || (guids[k] == &GUID_DEVINTERFACE_IBOOT && (pid < IRECV_K_RECOVERY_MODE_1 || pid > IRECV_K_RECOVERY_MODE_4))
1175 || (guids[k] == &GUID_DEVINTERFACE_KIS && pid != 1)
1128 ) { 1176 ) {
1129 free(details); 1177 free(details);
1130 continue; 1178 continue;
1131 } 1179 }
1180 if (guids[k] == &GUID_DEVINTERFACE_KIS) {
1181 pid = KIS_PRODUCT_ID;
1182 }
1132 1183
1133 _client->handle = CreateFileA(details->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 1184 _client->handle = CreateFileA(details->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
1134 if (_client->handle == INVALID_HANDLE_VALUE) { 1185 if (_client->handle == INVALID_HANDLE_VALUE) {
1186 debug("%s: Failed to open device path %s: %d\n", __func__, details->DevicePath, (int)GetLastError());
1135 free(details); 1187 free(details);
1136 continue; 1188 continue;
1137 } 1189 }
@@ -1158,34 +1210,35 @@ static irecv_error_t win32_open_with_ecid(irecv_client_t* client, uint64_t ecid)
1158 char serial_str[256]; 1210 char serial_str[256];
1159 serial_str[0] = '\0'; 1211 serial_str[0] = '\0';
1160 1212
1161 char *p = (char*)details->DevicePath; 1213 if (_client->mode != KIS_PRODUCT_ID) {
1162 while ((p = strstr(p, "\\usb"))) { 1214 char *p = (char*)details->DevicePath;
1163 if (sscanf(p, "\\usb#vid_05ac&pid_%*04x#%s", serial_str) == 1) 1215 while ((p = strstr(p, "\\usb"))) {
1164 break; 1216 if (sscanf(p, "\\usb#vid_05ac&pid_%*04x#%s", serial_str) == 1)
1165 p += 4; 1217 break;
1166 } 1218 p += 4;
1167 free(details); 1219 }
1168 1220 free(details);
1169 if (serial_str[0] == '\0') {
1170 CloseHandle(_client->handle);
1171 continue;
1172 }
1173 1221
1174 p = strchr(serial_str, '#'); 1222 if (serial_str[0] == '\0') {
1175 if (p) { 1223 CloseHandle(_client->handle);
1176 *p = '\0'; 1224 continue;
1177 } 1225 }
1226 p = strchr(serial_str, '#');
1227 if (p) {
1228 *p = '\0';
1229 }
1178 1230
1179 unsigned int j; 1231 unsigned int j;
1180 for (j = 0; j < strlen(serial_str); j++) { 1232 for (j = 0; j < strlen(serial_str); j++) {
1181 if (serial_str[j] == '_') { 1233 if (serial_str[j] == '_') {
1182 serial_str[j] = ' '; 1234 serial_str[j] = ' ';
1183 } else { 1235 } else {
1184 serial_str[j] = toupper(serial_str[j]); 1236 serial_str[j] = toupper(serial_str[j]);
1237 }
1185 } 1238 }
1186 }
1187 1239
1188 irecv_load_device_info_from_iboot_string(_client, serial_str); 1240 irecv_load_device_info_from_iboot_string(_client, serial_str);
1241 }
1189 1242
1190 if (ecid != 0) { 1243 if (ecid != 0) {
1191 if (_client->device_info.ecid != ecid) { 1244 if (_client->device_info.ecid != ecid) {
@@ -1434,7 +1487,7 @@ int irecv_usb_bulk_transfer(irecv_client_t client,
1434#endif 1487#endif
1435#else 1488#else
1436 if (endpoint==0x4) { 1489 if (endpoint==0x4) {
1437 ret = DeviceIoControl(client->handle, 0x220195, data, length, data, length, (PDWORD) transferred, NULL); 1490 ret = DeviceIoControl(client->handle, 0x2201B6, data, length, data, length, (PDWORD) transferred, NULL);
1438 } else { 1491 } else {
1439 ret = 0; 1492 ret = 0;
1440 } 1493 }
@@ -2202,40 +2255,51 @@ static void* _irecv_handle_device_add(void *userdata)
2202 2255
2203 unsigned int pid = 0; 2256 unsigned int pid = 0;
2204 2257
2205 char *p = result; 2258 if (strncmp(result, "\\\\?\\kis#", 8) == 0) {
2206 while ((p = strstr(p, "\\usb"))) { 2259 pid = KIS_PRODUCT_ID;
2207 if (sscanf(p, "\\usb#vid_05ac&pid_%04x#%s", &pid, serial_str) == 2) 2260 } else {
2208 break; 2261 char *p = result;
2209 p += 4; 2262 while ((p = strstr(p, "\\usb"))) {
2210 } 2263 if (sscanf(p, "\\usb#vid_05ac&pid_%04x#%s", &pid, serial_str) == 2)
2211 2264 break;
2212 if (serial_str[0] == '\0') { 2265 p += 4;
2213 debug("%s: ERROR: failed to parse DevicePath?!\n", __func__); 2266 }
2214 return NULL;
2215 }
2216
2217 if (!_irecv_is_recovery_device(p)) {
2218 return NULL;
2219 }
2220 2267
2221 p = strchr(serial_str, '#'); 2268 if (serial_str[0] == '\0') {
2222 if (p) { 2269 debug("%s: ERROR: failed to parse DevicePath?!\n", __func__);
2223 *p = '\0'; 2270 return NULL;
2224 } 2271 }
2225 2272
2226 unsigned int j; 2273 if (!_irecv_is_recovery_device(p)) {
2227 for (j = 0; j < strlen(serial_str); j++) { 2274 return NULL;
2228 if (serial_str[j] == '_') {
2229 serial_str[j] = ' ';
2230 } else {
2231 serial_str[j] = toupper(serial_str[j]);
2232 } 2275 }
2233 } 2276 }
2277
2234 product_id = (uint16_t)pid; 2278 product_id = (uint16_t)pid;
2235 2279
2236 if (product_id == KIS_PRODUCT_ID) { 2280 if (product_id == KIS_PRODUCT_ID) {
2237 debug("%s: ERROR: KIS currently not supported with this backend!\n", __func__); 2281 client = (irecv_client_t)malloc(sizeof(struct irecv_client_private));
2238 return NULL; 2282 client->handle = CreateFileA(result, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
2283 if (client->handle == INVALID_HANDLE_VALUE) {
2284 debug("%s: Failed to open device path %s\n", __func__, result);
2285 free(client);
2286 return NULL;
2287 }
2288 client->mode = pid;
2289 } else {
2290 char* p = strchr(serial_str, '#');
2291 if (p) {
2292 *p = '\0';
2293 }
2294
2295 unsigned int j;
2296 for (j = 0; j < strlen(serial_str); j++) {
2297 if (serial_str[j] == '_') {
2298 serial_str[j] = ' ';
2299 } else {
2300 serial_str[j] = toupper(serial_str[j]);
2301 }
2302 }
2239 } 2303 }
2240 2304
2241#else /* !WIN32 */ 2305#else /* !WIN32 */
@@ -2523,7 +2587,7 @@ static void *_irecv_event_handler(void* data)
2523 struct _irecv_event_handler_info* info = (struct _irecv_event_handler_info*)data; 2587 struct _irecv_event_handler_info* info = (struct _irecv_event_handler_info*)data;
2524#ifdef WIN32 2588#ifdef WIN32
2525 struct collection newDevices; 2589 struct collection newDevices;
2526 const GUID *guids[] = { &GUID_DEVINTERFACE_DFU, &GUID_DEVINTERFACE_IBOOT, NULL }; 2590 const GUID *guids[] = { &GUID_DEVINTERFACE_KIS, &GUID_DEVINTERFACE_DFU, &GUID_DEVINTERFACE_IBOOT, NULL };
2527 int running = 1; 2591 int running = 1;
2528 2592
2529 collection_init(&newDevices); 2593 collection_init(&newDevices);
@@ -2606,15 +2670,22 @@ static void *_irecv_event_handler(void* data)
2606 } ENDFOREACH 2670 } ENDFOREACH
2607 2671
2608 unsigned int pid = 0; 2672 unsigned int pid = 0;
2609 if (sscanf(details->DevicePath, "\\\\?\\usb#vid_05ac&pid_%04x", &pid)!= 1) { 2673 unsigned int vid = 0;
2610 debug("%s: ERROR: failed to parse PID! path: %s\n", __func__, details->DevicePath); 2674 if (sscanf(details->DevicePath, "\\\\?\\%*3s#vid_%04x&pid_%04x", &vid, &pid)!= 2) {
2675 debug("%s: ERROR: failed to parse VID/PID! path: %s\n", __func__, details->DevicePath);
2611 free(details); 2676 free(details);
2612 continue; 2677 continue;
2613 } 2678 }
2679 if (vid != APPLE_VENDOR_ID) {
2680 free(details);
2681 continue;
2682 }
2683
2614 // make sure the current device is actually in the right mode for the given driver interface 2684 // make sure the current device is actually in the right mode for the given driver interface
2615 int skip = 0; 2685 int skip = 0;
2616 if ((guids[k] == &GUID_DEVINTERFACE_DFU && pid != IRECV_K_DFU_MODE && pid != IRECV_K_WTF_MODE) 2686 if ((guids[k] == &GUID_DEVINTERFACE_DFU && pid != IRECV_K_DFU_MODE && pid != IRECV_K_WTF_MODE)
2617 || (guids[k] == &GUID_DEVINTERFACE_IBOOT && (pid < IRECV_K_RECOVERY_MODE_1 || pid > IRECV_K_RECOVERY_MODE_4)) 2687 || (guids[k] == &GUID_DEVINTERFACE_IBOOT && (pid < IRECV_K_RECOVERY_MODE_1 || pid > IRECV_K_RECOVERY_MODE_4))
2688 || (guids[k] == &GUID_DEVINTERFACE_KIS && pid != 1)
2618 ) { 2689 ) {
2619 skip = 1; 2690 skip = 1;
2620 } 2691 }
@@ -3109,6 +3180,11 @@ static irecv_error_t irecv_kis_send_buffer(irecv_client_t client, unsigned char*
3109 if (toUpload > 0x4000) 3180 if (toUpload > 0x4000)
3110 toUpload = 0x4000; 3181 toUpload = 0x4000;
3111 3182
3183#ifdef WIN32
3184 memcpy(chunk->data, buffer, toUpload);
3185 chunk->size = toUpload;
3186 chunk->address = address;
3187#else
3112 irecv_error_t error = irecv_kis_request_init(&chunk->hdr, KIS_PORTAL_RSM, KIS_INDEX_UPLOAD, 3, toUpload, 0); 3188 irecv_error_t error = irecv_kis_request_init(&chunk->hdr, KIS_PORTAL_RSM, KIS_INDEX_UPLOAD, 3, toUpload, 0);
3113 if (error != IRECV_E_SUCCESS) { 3189 if (error != IRECV_E_SUCCESS) {
3114 free(chunk); 3190 free(chunk);
@@ -3119,10 +3195,17 @@ static irecv_error_t irecv_kis_send_buffer(irecv_client_t client, unsigned char*
3119 chunk->address = address; 3195 chunk->address = address;
3120 chunk->size = toUpload; 3196 chunk->size = toUpload;
3121 memcpy(chunk->data, buffer, toUpload); 3197 memcpy(chunk->data, buffer, toUpload);
3198#endif
3122 3199
3200#ifdef WIN32
3201 DWORD transferred = 0;
3202 int ret = DeviceIoControl(client->handle, 0x220008, chunk, sizeof(*chunk), NULL, 0, (PDWORD)&transferred, NULL);
3203 irecv_error_t error = (ret) ? IRECV_E_SUCCESS : IRECV_E_USB_UPLOAD;
3204#else
3123 KIS_generic_reply reply; 3205 KIS_generic_reply reply;
3124 size_t rcvSize = sizeof(reply); 3206 size_t rcvSize = sizeof(reply);
3125 error = irecv_kis_request(client, &chunk->hdr, sizeof(*chunk) - (0x4000 - toUpload), &reply.hdr, &rcvSize); 3207 error = irecv_kis_request(client, &chunk->hdr, sizeof(*chunk) - (0x4000 - toUpload), &reply.hdr, &rcvSize);
3208#endif
3126 if (error != IRECV_E_SUCCESS) { 3209 if (error != IRECV_E_SUCCESS) {
3127 free(chunk); 3210 free(chunk);
3128 debug("Failed to upload chunk, error %d\n", error); 3211 debug("Failed to upload chunk, error %d\n", error);
@@ -3147,7 +3230,14 @@ static irecv_error_t irecv_kis_send_buffer(irecv_client_t client, unsigned char*
3147 free(chunk); 3230 free(chunk);
3148 3231
3149 if (dfu_notify_finished) { 3232 if (dfu_notify_finished) {
3233#ifdef WIN32
3234 DWORD amount = (DWORD)origLen;
3235 DWORD transferred = 0;
3236 int ret = DeviceIoControl(client->handle, 0x22000C, &amount, 4, NULL, 0, (PDWORD)&transferred, NULL);
3237 irecv_error_t error = (ret) ? IRECV_E_SUCCESS : IRECV_E_USB_UPLOAD;
3238#else
3150 irecv_error_t error = irecv_kis_config_write32(client, KIS_PORTAL_RSM, KIS_INDEX_BOOT_IMG, origLen); 3239 irecv_error_t error = irecv_kis_config_write32(client, KIS_PORTAL_RSM, KIS_INDEX_BOOT_IMG, origLen);
3240#endif
3151 if (error != IRECV_E_SUCCESS) { 3241 if (error != IRECV_E_SUCCESS) {
3152 debug("Failed to boot image, error %d\n", error); 3242 debug("Failed to boot image, error %d\n", error);
3153 return error; 3243 return error;