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 |