diff options
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r-- | firmware/drivers/ata.c | 63 |
1 files changed, 27 insertions, 36 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index db8bdf92a0..549a7bf920 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -89,7 +89,6 @@ static bool initialized = false; | |||
89 | static long last_user_activity = -1; | 89 | static long last_user_activity = -1; |
90 | long last_disk_activity = -1; | 90 | long last_disk_activity = -1; |
91 | 91 | ||
92 | static unsigned long total_sectors; | ||
93 | static int multisectors; /* number of supported multisectors */ | 92 | static int multisectors; /* number of supported multisectors */ |
94 | static unsigned short identify_info[SECTOR_SIZE/2]; | 93 | static unsigned short identify_info[SECTOR_SIZE/2]; |
95 | 94 | ||
@@ -285,11 +284,6 @@ int ata_read_sectors(IF_MV2(int drive,) | |||
285 | mutex_lock(&ata_mtx); | 284 | mutex_lock(&ata_mtx); |
286 | #endif | 285 | #endif |
287 | 286 | ||
288 | if (start + incount > total_sectors) { | ||
289 | ret = -1; | ||
290 | goto error; | ||
291 | } | ||
292 | |||
293 | last_disk_activity = current_tick; | 287 | last_disk_activity = current_tick; |
294 | spinup_start = current_tick; | 288 | spinup_start = current_tick; |
295 | 289 | ||
@@ -299,14 +293,16 @@ int ata_read_sectors(IF_MV2(int drive,) | |||
299 | spinup = true; | 293 | spinup = true; |
300 | if (poweroff) { | 294 | if (poweroff) { |
301 | if (ata_power_on()) { | 295 | if (ata_power_on()) { |
302 | ret = -2; | 296 | mutex_unlock(&ata_mtx); |
303 | goto error; | 297 | ata_led(false); |
298 | return -1; | ||
304 | } | 299 | } |
305 | } | 300 | } |
306 | else { | 301 | else { |
307 | if (perform_soft_reset()) { | 302 | if (perform_soft_reset()) { |
308 | ret = -2; | 303 | mutex_unlock(&ata_mtx); |
309 | goto error; | 304 | ata_led(false); |
305 | return -1; | ||
310 | } | 306 | } |
311 | } | 307 | } |
312 | } | 308 | } |
@@ -316,8 +312,9 @@ int ata_read_sectors(IF_MV2(int drive,) | |||
316 | SET_REG(ATA_SELECT, ata_device); | 312 | SET_REG(ATA_SELECT, ata_device); |
317 | if (!wait_for_rdy()) | 313 | if (!wait_for_rdy()) |
318 | { | 314 | { |
319 | ret = -3; | 315 | mutex_unlock(&ata_mtx); |
320 | goto error; | 316 | ata_led(false); |
317 | return -2; | ||
321 | } | 318 | } |
322 | 319 | ||
323 | retry: | 320 | retry: |
@@ -374,7 +371,7 @@ int ata_read_sectors(IF_MV2(int drive,) | |||
374 | We choose alternative 2. | 371 | We choose alternative 2. |
375 | */ | 372 | */ |
376 | perform_soft_reset(); | 373 | perform_soft_reset(); |
377 | ret = -5; | 374 | ret = -4; |
378 | goto retry; | 375 | goto retry; |
379 | } | 376 | } |
380 | 377 | ||
@@ -406,7 +403,7 @@ int ata_read_sectors(IF_MV2(int drive,) | |||
406 | */ | 403 | */ |
407 | if ( status & (STATUS_BSY | STATUS_ERR | STATUS_DF) ) { | 404 | if ( status & (STATUS_BSY | STATUS_ERR | STATUS_DF) ) { |
408 | perform_soft_reset(); | 405 | perform_soft_reset(); |
409 | ret = -6; | 406 | ret = -5; |
410 | goto retry; | 407 | goto retry; |
411 | } | 408 | } |
412 | 409 | ||
@@ -418,14 +415,13 @@ int ata_read_sectors(IF_MV2(int drive,) | |||
418 | 415 | ||
419 | if(!ret && !wait_for_end_of_transfer()) { | 416 | if(!ret && !wait_for_end_of_transfer()) { |
420 | perform_soft_reset(); | 417 | perform_soft_reset(); |
421 | ret = -4; | 418 | ret = -3; |
422 | goto retry; | 419 | goto retry; |
423 | } | 420 | } |
424 | break; | 421 | break; |
425 | } | 422 | } |
426 | |||
427 | error: | ||
428 | ata_led(false); | 423 | ata_led(false); |
424 | |||
429 | #ifndef MAX_PHYS_SECTOR_SIZE | 425 | #ifndef MAX_PHYS_SECTOR_SIZE |
430 | mutex_unlock(&ata_mtx); | 426 | mutex_unlock(&ata_mtx); |
431 | #endif | 427 | #endif |
@@ -493,9 +489,6 @@ int ata_write_sectors(IF_MV2(int drive,) | |||
493 | mutex_lock(&ata_mtx); | 489 | mutex_lock(&ata_mtx); |
494 | #endif | 490 | #endif |
495 | 491 | ||
496 | if (start + count > total_sectors) | ||
497 | panicf("Writing past end of disk"); | ||
498 | |||
499 | last_disk_activity = current_tick; | 492 | last_disk_activity = current_tick; |
500 | spinup_start = current_tick; | 493 | spinup_start = current_tick; |
501 | 494 | ||
@@ -505,14 +498,16 @@ int ata_write_sectors(IF_MV2(int drive,) | |||
505 | spinup = true; | 498 | spinup = true; |
506 | if (poweroff) { | 499 | if (poweroff) { |
507 | if (ata_power_on()) { | 500 | if (ata_power_on()) { |
508 | ret = -1; | 501 | mutex_unlock(&ata_mtx); |
509 | goto error; | 502 | ata_led(false); |
503 | return -1; | ||
510 | } | 504 | } |
511 | } | 505 | } |
512 | else { | 506 | else { |
513 | if (perform_soft_reset()) { | 507 | if (perform_soft_reset()) { |
514 | ret = -1; | 508 | mutex_unlock(&ata_mtx); |
515 | goto error; | 509 | ata_led(false); |
510 | return -1; | ||
516 | } | 511 | } |
517 | } | 512 | } |
518 | } | 513 | } |
@@ -520,8 +515,9 @@ int ata_write_sectors(IF_MV2(int drive,) | |||
520 | SET_REG(ATA_SELECT, ata_device); | 515 | SET_REG(ATA_SELECT, ata_device); |
521 | if (!wait_for_rdy()) | 516 | if (!wait_for_rdy()) |
522 | { | 517 | { |
523 | ret = -2; | 518 | mutex_unlock(&ata_mtx); |
524 | goto error; | 519 | ata_led(false); |
520 | return -2; | ||
525 | } | 521 | } |
526 | 522 | ||
527 | #ifdef HAVE_LBA48 | 523 | #ifdef HAVE_LBA48 |
@@ -579,8 +575,8 @@ int ata_write_sectors(IF_MV2(int drive,) | |||
579 | ret = -4; | 575 | ret = -4; |
580 | } | 576 | } |
581 | 577 | ||
582 | error: | ||
583 | ata_led(false); | 578 | ata_led(false); |
579 | |||
584 | #ifndef MAX_PHYS_SECTOR_SIZE | 580 | #ifndef MAX_PHYS_SECTOR_SIZE |
585 | mutex_unlock(&ata_mtx); | 581 | mutex_unlock(&ata_mtx); |
586 | #endif | 582 | #endif |
@@ -1244,16 +1240,11 @@ int ata_init(void) | |||
1244 | phys_sector_mult * SECTOR_SIZE); | 1240 | phys_sector_mult * SECTOR_SIZE); |
1245 | #endif | 1241 | #endif |
1246 | 1242 | ||
1247 | total_sectors = identify_info[60] | (identify_info[60] << 16); | ||
1248 | |||
1249 | #ifdef HAVE_LBA48 | 1243 | #ifdef HAVE_LBA48 |
1250 | if (identify_info[83] & 0x0400 /* 48 bit address support */ | 1244 | if (identify_info[83] & 0x0400 /* 48 bit address support */ |
1251 | && total_sectors == 0x0FFFFFFF) /* and disk size >= 128 GiB */ | 1245 | && identify_info[60] == 0xFFFF /* and disk size >= 128 GiB */ |
1252 | { /* (needs BigLBA addressing) */ | 1246 | && identify_info[61] == 0x0FFF) /* (needs BigLBA addressing) */ |
1253 | if (identify_info[102] || identify_info[103]) | 1247 | { |
1254 | panicf("Unsupported disk size, >= 2^32 sectors"); | ||
1255 | |||
1256 | total_sectors = identify_info[100] | (identify_info[101] << 16); | ||
1257 | lba48 = true; /* use BigLBA */ | 1248 | lba48 = true; /* use BigLBA */ |
1258 | } | 1249 | } |
1259 | #endif | 1250 | #endif |