| 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", §ors);
|
| | 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", §or) == 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 @@ |
| 43 | 43 | #include "panic.h"
|
| 44 | 44 | uint16_t ata_bbt[ATA_BBT_PAGES][0x20];
|
| 45 | 45 | uint32_t ata_virtual_sectors;
|
| | 46 | +uint32_t ata_last_offset;
|
| | 47 | +uint64_t ata_last_phys;
|
| 46 | 48 |
|
| 47 | 49 | int ata_rw_sectors_internal(uint64_t sector, uint32_t count, void* buffer, bool write);
|
| 48 | 50 |
|
| — | — | @@ -226,8 +228,8 @@ |
| 227 | 229 | }
|
| 228 | 230 | ata_dma = param ? true : false;
|
| 229 | 231 | 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);
|
| 232 | 234 | ATA_PIO_TIME = piotime;
|
| 233 | 235 | ATA_MDMA_TIME = mdmatime;
|
| 234 | 236 | ATA_UDMA_TIME = udmatime;
|
| — | — | @@ -250,6 +252,85 @@ |
| 251 | 253 | i2c_sendbyte(0, 0xe6, 0x1b, 0);
|
| 252 | 254 | }
|
| 253 | 255 |
|
| | 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 | +
|
| 254 | 335 | int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
|
| 255 | 336 | {
|
| 256 | 337 | #ifdef ATA_HAVE_BBT
|
| — | — | @@ -256,13 +337,13 @@ |
| 257 | 338 | if (sector + count > ata_virtual_sectors) RET_ERR(0);
|
| 258 | 339 | while (count)
|
| 259 | 340 | {
|
| | 341 | + uint32_t offset;
|
| 260 | 342 | uint32_t l0idx = sector >> 15;
|
| 261 | 343 | uint32_t l0offs = sector & 0x7fff;
|
| 262 | 344 | uint32_t cnt = MIN(count, 0x8000 - l0offs);
|
| 263 | 345 | uint32_t l0data = ata_bbt[0][l0idx << 1];
|
| 264 | 346 | 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;
|
| 267 | 348 | else
|
| 268 | 349 | {
|
| 269 | 350 | uint32_t l1idx = (sector >> 10) & 0x1f;
|
| — | — | @@ -269,7 +350,7 @@ |
| 270 | 351 | uint32_t l1offs = sector & 0x3ff;
|
| 271 | 352 | cnt = MIN(count, 0x400 - l1offs);
|
| 272 | 353 | uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
|
| 273 | | - if (l1data < 0x8000) phys = sector + l1data + base;
|
| | 354 | + if (l1data < 0x8000) offset = l1data + base;
|
| 274 | 355 | else
|
| 275 | 356 | {
|
| 276 | 357 | uint32_t l2idx = (sector >> 5) & 0x1f;
|
| — | — | @@ -276,18 +357,22 @@ |
| 277 | 358 | uint32_t l2offs = sector & 0x1f;
|
| 278 | 359 | cnt = MIN(count, 0x20 - l2offs);
|
| 279 | 360 | uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
|
| 280 | | - if (l2data < 0x8000) phys = sector + l2data + base;
|
| | 361 | + if (l2data < 0x8000) offset = l2data + base;
|
| 281 | 362 | else
|
| 282 | 363 | {
|
| 283 | 364 | uint32_t l3idx = sector & 0x1f;
|
| 284 | | - phys = ata_bbt[l2data & 0x7fff][l3idx];
|
| | 365 | + uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
|
| 285 | 366 | 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)
|
| 287 | 368 | break;
|
| 288 | | - phys += sector + base;
|
| | 369 | + offset = l3data + base;
|
| 289 | 370 | }
|
| 290 | 371 | }
|
| 291 | 372 | }
|
| | 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;
|
| 292 | 377 | PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
|
| 293 | 378 | buffer += cnt * SECTOR_SIZE;
|
| 294 | 379 | sector += cnt;
|
| — | — | @@ -308,83 +393,34 @@ |
| 309 | 394 | while (count)
|
| 310 | 395 | {
|
| 311 | 396 | 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)
|
| 315 | 400 | {
|
| 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();
|
| 327 | 403 | }
|
| 328 | | - else
|
| | 404 | + if (rc)
|
| 329 | 405 | {
|
| 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 | + }
|
| 337 | 420 | }
|
| | 421 | + PASS_RC(rc, 1, 1);
|
| | 422 | + buffer += SECTOR_SIZE * cnt;
|
| 338 | 423 | sector += cnt;
|
| 339 | 424 | 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);
|
| 389 | 425 | }
|
| 390 | 426 | ata_set_active();
|
| 391 | 427 | return 0;
|
| — | — | @@ -411,7 +447,7 @@ |
| 412 | 448 | ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
|
| 413 | 449 | sleep(10);
|
| 414 | 450 | 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);
|
| 416 | 452 | ata_set_active();
|
| 417 | 453 | mutex_unlock(&ata_mutex);
|
| 418 | 454 | }
|
| — | — | @@ -420,13 +456,7 @@ |
| 421 | 457 | void* inbuf)
|
| 422 | 458 | {
|
| 423 | 459 | 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);
|
| 431 | 461 | mutex_unlock(&ata_mutex);
|
| 432 | 462 | return rc;
|
| 433 | 463 | }
|
| — | — | @@ -435,21 +465,15 @@ |
| 436 | 466 | const void* outbuf)
|
| 437 | 467 | {
|
| 438 | 468 | 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);
|
| 446 | 470 | mutex_unlock(&ata_mutex);
|
| 447 | 471 | return rc;
|
| 448 | 472 | }
|
| 449 | 473 |
|
| 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 | +}
|
| 454 | 478 |
|
| 455 | 479 | void ata_sleep(void)
|
| 456 | 480 | {
|
| — | — | @@ -512,7 +536,7 @@ |
| 513 | 537 | ata_virtual_sectors = buf[0x1fe];
|
| 514 | 538 | uint32_t count = buf[0x1ff];
|
| 515 | 539 | 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);
|
| 517 | 541 | uint32_t i;
|
| 518 | 542 | uint32_t cnt;
|
| 519 | 543 | for (i = 0; i < count; i += cnt)
|
| Index: embios/trunk/target/ipodclassic/config.h |
| — | — | @@ -37,4 +37,8 @@ |
| 38 | 38 | //#define DEBUG_PRINT_SOURCE_LINE
|
| 39 | 39 |
|
| 40 | 40 |
|
| | 41 | +//#define ATA_HAVE_BBT
|
| | 42 | +//#define ATA_BBT_PAGES 2304
|
| | 43 | +
|
| | 44 | +
|
| 41 | 45 | #endif |
| \ No newline at end of file |