freemyipod r337 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r336‎ | r337 | r338 >
Date:16:12, 19 December 2010
Author:theseven
Status:new
Tags:
Comment:
emBIOS: iPod Classic: Software bad block remapping support
Modified paths:
  • /embios/trunk/target/ipodclassic/config.h (modified) (history)
  • /embios/trunk/target/ipodclassic/storage_ata.c (modified) (history)
  • /embios/trunk/tools (modified) (history)
  • /embios/trunk/tools/genbbt.c (added) (history)

Diff [purge]

Index: embios/trunk/tools/genbbt.c
@@ -0,0 +1,195 @@
 2+#include <stdio.h>
 3+#include <stdint.h>
 4+#include <stdbool.h>
 5+#include <fcntl.h>
 6+
 7+static void mark_bad(uint32_t* bitmap, int sector)
 8+{
 9+ bitmap[sector >> 5] &= ~(1 << (sector & 31));
 10+}
 11+
 12+static bool is_good(uint32_t* bitmap, int sector)
 13+{
 14+ return bitmap[sector >> 5] & (1 << (sector & 31));
 15+}
 16+
 17+int main(int argc, char** argv)
 18+{
 19+ int sectors;
 20+ sscanf(argv[3], "%i", &sectors);
 21+ size_t bitmapsize = ((sectors + 65535) & ~0xffff) >> 3;
 22+ uint32_t* bitmap = malloc(bitmapsize);
 23+ memset(bitmap, 0xff, bitmapsize);
 24+ FILE* in = fopen(argv[1], "r");
 25+ if (!in)
 26+ {
 27+ perror("Failed to open input file");
 28+ return 2;
 29+ }
 30+ char line[256];
 31+ while (fgets(line, sizeof(line), in))
 32+ {
 33+ int sector;
 34+ if (sscanf(line, "%i", &sector) == 1 && sector) mark_bad(bitmap, sector);
 35+ }
 36+ fclose(in);
 37+ int l0count = (sectors + 0xfffff) >> 19;
 38+ int bbtpages = 64 + ((l0count + 0x3f) & ~0x3f);
 39+ int bbtsize;
 40+ uint16_t (*bbt)[0x20];
 41+ bool success = false;
 42+ while (bbtpages <= 32832)
 43+ {
 44+ bbtsize = bbtpages << 6;
 45+ bbt = malloc(bbtsize);
 46+ memset(bbt, 0, bbtsize);
 47+ int logical = 0;
 48+ int physical = 1;
 49+ int remapbase;
 50+ int bbtgood;
 51+ for (bbtgood = 0; bbtgood < (bbtpages >> 6) - 1; physical++)
 52+ if (is_good(bitmap, physical))
 53+ {
 54+ ((uint32_t*)bbt)[0x200 + bbtgood] = physical;
 55+ bbtgood++;
 56+ }
 57+ int bbtused = 64 + l0count;
 58+ int level;
 59+ uint16_t *l1, *l2, *l3;
 60+ int l1count = 0, l2count = 0, l3count = 0;
 61+ while (!success)
 62+ {
 63+ if (!(logical & 0x7fff)) level = 0;
 64+ else if (!(logical & 0x3ff)) level = 1;
 65+ else if (!(logical & 0x1f)) level = 2;
 66+ else level = 3;
 67+ if (!level) remapbase = ((physical - logical) >> 12) << 12;
 68+ if (physical - logical - remapbase > 0x7fff || remapbase > 0xffff)
 69+ {
 70+ printf("Need to remap across too high distance!\n");
 71+ return 5;
 72+ }
 73+ int clean;
 74+ for (clean = 0; clean < (1 << ((3 - level) * 5)) && physical + clean < sectors; clean++)
 75+ if (!is_good(bitmap, physical + clean))
 76+ break;
 77+ if (clean >= 32768)
 78+ {
 79+ bbt[64][(logical >> 15) << 1] = physical - logical - remapbase;
 80+ bbt[64][((logical >> 15) << 1) | 1] = remapbase >> 12;
 81+ physical += 32768;
 82+ logical += 32768;
 83+ }
 84+ else if (clean >= 1024)
 85+ {
 86+ if (level == 0)
 87+ {
 88+ if (bbtused == bbtpages) break;
 89+ level = 1;
 90+ l1 = bbt[bbtused];
 91+ bbt[64][(logical >> 15) << 1] = 0x8000 | (bbtused - 64);
 92+ bbt[64][((logical >> 15) << 1) | 1] = remapbase >> 12;
 93+ bbtused++;
 94+ l1count++;
 95+ }
 96+ l1[(logical >> 10) & 0x1f] = physical - logical - remapbase;
 97+ physical += 1024;
 98+ logical += 1024;
 99+ }
 100+ else if (clean >= 32)
 101+ {
 102+ if (level == 0)
 103+ {
 104+ if (bbtused == bbtpages) break;
 105+ level = 1;
 106+ l1 = bbt[bbtused];
 107+ bbt[64][(logical >> 15) << 1] = 0x8000 | (bbtused - 64);
 108+ bbt[64][((logical >> 15) << 1) | 1] = remapbase >> 12;
 109+ bbtused++;
 110+ l1count++;
 111+ }
 112+ if (level == 1)
 113+ {
 114+ if (bbtused == bbtpages) break;
 115+ level = 2;
 116+ l2 = bbt[bbtused];
 117+ l1[(logical >> 10) & 0x1f] = 0x8000 | (bbtused - 64);
 118+ bbtused++;
 119+ l2count++;
 120+ }
 121+ l2[(logical >> 5) & 0x1f] = physical - logical - remapbase;
 122+ physical += 32;
 123+ logical += 32;
 124+ }
 125+ else if (clean >= 1)
 126+ {
 127+ if (level == 0)
 128+ {
 129+ if (bbtused == bbtpages) break;
 130+ level = 1;
 131+ l1 = bbt[bbtused];
 132+ bbt[64][(logical >> 15) << 1] = 0x8000 | (bbtused - 64);
 133+ bbt[64][((logical >> 15) << 1) | 1] = remapbase >> 12;
 134+ bbtused++;
 135+ l1count++;
 136+ }
 137+ if (level == 1)
 138+ {
 139+ if (bbtused == bbtpages) break;
 140+ level = 2;
 141+ l2 = bbt[bbtused];
 142+ l1[(logical >> 10) & 0x1f] = 0x8000 | (bbtused - 64);
 143+ bbtused++;
 144+ l2count++;
 145+ }
 146+ if (level == 2)
 147+ {
 148+ if (bbtused == bbtpages) break;
 149+ level = 3;
 150+ l3 = bbt[bbtused];
 151+ l2[(logical >> 5) & 0x1f] = 0x8000 | (bbtused - 64);
 152+ bbtused++;
 153+ l3count++;
 154+ }
 155+ l3[logical & 0x1f] = physical - logical - remapbase;
 156+ physical++;
 157+ logical++;
 158+ }
 159+ else physical++;
 160+ if (physical >= sectors) success = true;
 161+ }
 162+ if (success)
 163+ {
 164+ printf("BBT using %d sectors (%d KiB)\n", bbtgood + 1, bbtsize >> 10);
 165+ printf("Level 0: %d pages, Level 1: %d pages, Level 2: %d pages, Level 3: %d pages\n",
 166+ l0count, l1count, l2count, l3count);
 167+ printf("User data sectors: %d (%d KiB)\n", logical, logical << 2);
 168+ memcpy(bbt, "emBIbbth", 8);
 169+ ((uint32_t*)bbt)[0x1fe] = logical;
 170+ ((uint32_t*)bbt)[0x1ff] = (bbtpages >> 6) - 1;
 171+ break;
 172+ }
 173+ free(bbt);
 174+ bbtpages += 64;
 175+ }
 176+ if (success)
 177+ {
 178+ int out = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);
 179+ if (out < 0)
 180+ {
 181+ perror("Failed to open output file");
 182+ return 3;
 183+ }
 184+ int rc;
 185+ while (bbtsize && (rc = write(out, bbt, bbtsize)) >= 0) bbtsize -= rc;
 186+ if (rc < 0)
 187+ {
 188+ perror("Failed to open output file");
 189+ return 4;
 190+ }
 191+ close(out);
 192+ return 0;
 193+ }
 194+ printf("Can't fit BBT into 2052 KiB!\n");
 195+ return 1;
 196+}
Index: embios/trunk/tools
Property changes on: embios/trunk/tools
___________________________________________________________________
Added: svn:ignore
## -0,0 +1 ##
 197+genbbt.exe
Index: embios/trunk/target/ipodclassic/storage_ata.c
@@ -42,6 +42,8 @@
4343 #include "panic.h"
4444 uint16_t ata_bbt[ATA_BBT_PAGES][0x20];
4545 uint32_t ata_virtual_sectors;
 46+uint32_t ata_last_offset;
 47+uint64_t ata_last_phys;
4648
4749 int ata_rw_sectors_internal(uint64_t sector, uint32_t count, void* buffer, bool write);
4850
@@ -226,8 +228,8 @@
227229 }
228230 ata_dma = param ? true : false;
229231 PASS_RC(ata_set_feature(0xef, param), 2, 1);
230 - if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x82, 0), 2, 2);
231 - if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0xaa, 0), 2, 3);
 232+ if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2);
 233+ if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3);
232234 ATA_PIO_TIME = piotime;
233235 ATA_MDMA_TIME = mdmatime;
234236 ATA_UDMA_TIME = udmatime;
@@ -250,6 +252,85 @@
251253 i2c_sendbyte(0, 0xe6, 0x1b, 0);
252254 }
253255
 256+int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write)
 257+{
 258+ PASS_RC(ata_wait_for_rdy(100000), 2, 0);
 259+ ata_write_cbr(&ATA_PIO_DVR, 0);
 260+ if (ata_lba48)
 261+ {
 262+ ata_write_cbr(&ATA_PIO_SCR, cnt >> 5);
 263+ ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
 264+ ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff);
 265+ ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff);
 266+ ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff);
 267+ ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
 268+ ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
 269+ ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
 270+ ata_write_cbr(&ATA_PIO_DVR, BIT(6));
 271+ if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39);
 272+ else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29);
 273+ }
 274+ else
 275+ {
 276+ ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
 277+ ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
 278+ ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
 279+ ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
 280+ ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf));
 281+ if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30);
 282+ else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4);
 283+ }
 284+ if (ata_dma)
 285+ {
 286+ PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
 287+ if (write)
 288+ {
 289+ ATA_SBUF_START = buffer;
 290+ ATA_SBUF_SIZE = SECTOR_SIZE * cnt;
 291+ ATA_CFG |= BIT(4);
 292+ }
 293+ else
 294+ {
 295+ ATA_TBUF_START = buffer;
 296+ ATA_TBUF_SIZE = SECTOR_SIZE * cnt;
 297+ ATA_CFG &= ~BIT(4);
 298+ }
 299+ ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
 300+ ATA_CFG |= ata_dma_flags;
 301+ ATA_CFG &= ~(BIT(7) | BIT(8));
 302+ wakeup_wait(&ata_wakeup, TIMEOUT_NONE);
 303+ ATA_IRQ = BITRANGE(0, 4);
 304+ ATA_IRQ_MASK = BIT(0);
 305+ ATA_COMMAND = BIT(0);
 306+ if (wakeup_wait(&ata_wakeup, 500000) == THREAD_TIMEOUT)
 307+ {
 308+ ATA_COMMAND = BIT(1);
 309+ ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
 310+ RET_ERR(2);
 311+ }
 312+ ATA_COMMAND = BIT(1);
 313+ ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
 314+ }
 315+ else
 316+ {
 317+ cnt *= SECTOR_SIZE / 512;
 318+ while (cnt--)
 319+ {
 320+ int i;
 321+ PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
 322+ if (write)
 323+ for (i = 0; i < 256; i++)
 324+ ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
 325+ else
 326+ for (i = 0; i < 256; i++)
 327+ ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
 328+ buffer += 512;
 329+ }
 330+ }
 331+ PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
 332+ return 0;
 333+}
 334+
254335 int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
255336 {
256337 #ifdef ATA_HAVE_BBT
@@ -256,13 +337,13 @@
257338 if (sector + count > ata_virtual_sectors) RET_ERR(0);
258339 while (count)
259340 {
 341+ uint32_t offset;
260342 uint32_t l0idx = sector >> 15;
261343 uint32_t l0offs = sector & 0x7fff;
262344 uint32_t cnt = MIN(count, 0x8000 - l0offs);
263345 uint32_t l0data = ata_bbt[0][l0idx << 1];
264346 uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
265 - uint32_t phys;
266 - if (l0data < 0x8000) phys = sector + l0data + base;
 347+ if (l0data < 0x8000) offset = l0data + base;
267348 else
268349 {
269350 uint32_t l1idx = (sector >> 10) & 0x1f;
@@ -269,7 +350,7 @@
270351 uint32_t l1offs = sector & 0x3ff;
271352 cnt = MIN(count, 0x400 - l1offs);
272353 uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
273 - if (l1data < 0x8000) phys = sector + l1data + base;
 354+ if (l1data < 0x8000) offset = l1data + base;
274355 else
275356 {
276357 uint32_t l2idx = (sector >> 5) & 0x1f;
@@ -276,18 +357,22 @@
277358 uint32_t l2offs = sector & 0x1f;
278359 cnt = MIN(count, 0x20 - l2offs);
279360 uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
280 - if (l2data < 0x8000) phys = sector + l2data + base;
 361+ if (l2data < 0x8000) offset = l2data + base;
281362 else
282363 {
283364 uint32_t l3idx = sector & 0x1f;
284 - phys = ata_bbt[l2data & 0x7fff][l3idx];
 365+ uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
285366 for (cnt = 1; cnt < count && l3idx + cnt < 0x20; cnt++)
286 - if (ata_bbt[l2data & 0x7fff][l3idx + cnt] != phys)
 367+ if (ata_bbt[l2data & 0x7fff][l3idx + cnt] != l3data)
287368 break;
288 - phys += sector + base;
 369+ offset = l3data + base;
289370 }
290371 }
291372 }
 373+ uint64_t phys = sector + offset;
 374+ if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
 375+ ata_last_offset = offset;
 376+ ata_last_phys = phys + cnt;
292377 PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
293378 buffer += cnt * SECTOR_SIZE;
294379 sector += cnt;
@@ -308,83 +393,34 @@
309394 while (count)
310395 {
311396 uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
312 - PASS_RC(ata_wait_for_rdy(100000), 2, 1);
313 - ata_write_cbr(&ATA_PIO_DVR, 0);
314 - if (ata_lba48)
 397+ int rc = -1;
 398+ int tries = 3;
 399+ while (tries-- && rc)
315400 {
316 - ata_write_cbr(&ATA_PIO_SCR, cnt >> 5);
317 - ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
318 - ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff);
319 - ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff);
320 - ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff);
321 - ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
322 - ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
323 - ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
324 - ata_write_cbr(&ATA_PIO_DVR, BIT(6));
325 - if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39);
326 - else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29);
 401+ rc = ata_rw_chunk(sector, cnt, buffer, write);
 402+ if (rc) ata_soft_reset();
327403 }
328 - else
 404+ if (rc)
329405 {
330 - ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
331 - ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
332 - ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
333 - ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
334 - ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf));
335 - if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30);
336 - else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4);
 406+ void* buf = buffer;
 407+ int sect;
 408+ for (sect = sector; sect < sector + cnt; sect++)
 409+ {
 410+ rc = -1;
 411+ tries = 3;
 412+ while (tries-- && rc)
 413+ {
 414+ rc = ata_rw_chunk(sect, 1, buf, write);
 415+ if (rc) ata_soft_reset();
 416+ }
 417+ if (rc) break;
 418+ buf += SECTOR_SIZE;
 419+ }
337420 }
 421+ PASS_RC(rc, 1, 1);
 422+ buffer += SECTOR_SIZE * cnt;
338423 sector += cnt;
339424 count -= cnt;
340 - if (ata_dma)
341 - {
342 - PASS_RC(ata_wait_for_start_of_transfer(1500000), 2, 2);
343 - if (write)
344 - {
345 - ATA_SBUF_START = buffer;
346 - ATA_SBUF_SIZE = SECTOR_SIZE * cnt;
347 - ATA_CFG |= BIT(4);
348 - }
349 - else
350 - {
351 - ATA_TBUF_START = buffer;
352 - ATA_TBUF_SIZE = SECTOR_SIZE * cnt;
353 - ATA_CFG &= ~BIT(4);
354 - }
355 - ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
356 - ATA_CFG |= ata_dma_flags;
357 - ATA_CFG &= ~(BIT(7) | BIT(8));
358 - wakeup_wait(&ata_wakeup, TIMEOUT_NONE);
359 - ATA_IRQ = BITRANGE(0, 4);
360 - ATA_IRQ_MASK = BIT(0);
361 - ATA_COMMAND = BIT(0);
362 - if (wakeup_wait(&ata_wakeup, 1500000) == THREAD_TIMEOUT)
363 - {
364 - ATA_COMMAND = BIT(1);
365 - ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
366 - RET_ERR(3);
367 - }
368 - ATA_COMMAND = BIT(1);
369 - ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
370 - buffer += SECTOR_SIZE * cnt;
371 - }
372 - else
373 - {
374 - cnt *= SECTOR_SIZE / 512;
375 - while (cnt--)
376 - {
377 - int i;
378 - PASS_RC(ata_wait_for_start_of_transfer(1500000), 2, 2);
379 - if (write)
380 - for (i = 0; i < 256; i++)
381 - ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
382 - else
383 - for (i = 0; i < 256; i++)
384 - ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
385 - buffer += 512;
386 - }
387 - }
388 - PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
389425 }
390426 ata_set_active();
391427 return 0;
@@ -411,7 +447,7 @@
412448 ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
413449 sleep(10);
414450 ata_write_cbr(&ATA_PIO_DAD, 0);
415 - PASS_RC_MTX(ata_wait_for_rdy(5000000), 0, 0, &ata_mutex);
 451+ PASS_RC_MTX(ata_wait_for_rdy(60000000), 0, 0, &ata_mutex);
416452 ata_set_active();
417453 mutex_unlock(&ata_mutex);
418454 }
@@ -420,13 +456,7 @@
421457 void* inbuf)
422458 {
423459 mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
424 - int tries = 1;
425 - int rc = -1;
426 - while (tries-- && rc)
427 - {
428 - rc = ata_rw_sectors(start, incount, inbuf, false);
429 - if (rc) ata_soft_reset();
430 - }
 460+ int rc = ata_rw_sectors(start, incount, inbuf, false);
431461 mutex_unlock(&ata_mutex);
432462 return rc;
433463 }
@@ -435,21 +465,15 @@
436466 const void* outbuf)
437467 {
438468 mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
439 - int tries = 1;
440 - int rc = -1;
441 - while (tries-- && rc)
442 - {
443 - rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true);
444 - if (rc) ata_soft_reset();
445 - }
 469+ int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true);
446470 mutex_unlock(&ata_mutex);
447471 return rc;
448472 }
449473
450 -void ata_spindown(int seconds)
451 -{
452 - ata_sleep_timeout = seconds * 1000000;
453 -}
 474+void ata_spindown(int seconds)
 475+{
 476+ ata_sleep_timeout = seconds * 1000000;
 477+}
454478
455479 void ata_sleep(void)
456480 {
@@ -512,7 +536,7 @@
513537 ata_virtual_sectors = buf[0x1fe];
514538 uint32_t count = buf[0x1ff];
515539 if (count > (ATA_BBT_PAGES >> 6))
516 - panicf(PANIC_KILLTHREAD, "ATA: BBT too big!\n");
 540+ panicf(PANIC_KILLTHREAD, "ATA: BBT too big! (%d pages, limit: %d)\n", count << 6, ATA_BBT_PAGES);
517541 uint32_t i;
518542 uint32_t cnt;
519543 for (i = 0; i < count; i += cnt)
Index: embios/trunk/target/ipodclassic/config.h
@@ -37,4 +37,8 @@
3838 //#define DEBUG_PRINT_SOURCE_LINE
3939
4040
 41+//#define ATA_HAVE_BBT
 42+//#define ATA_BBT_PAGES 2304
 43+
 44+
4145 #endif
\ No newline at end of file