diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-25 16:17:06 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-25 16:17:06 -0500 |
commit | 7a3b7512d0d7e78353e99f4538eb6d3354019d92 (patch) | |
tree | 678b3fee02297f3dea5df8182198ecd701e69649 /drivers/ide | |
parent | 650d841d9e053a618dd8ce753422f91b493cf2f6 (diff) |
ide-disk: merge LBA28 and LBA48 Host Protected Area support code (take 2)
* Merge idedisk_{read_native,set}_max_address_ext() into
idedisk_{read_native,set}_max_address().
v2:
* Remove LBA48 code leftover from idedisk_read_native_max_address()
('high' variable initialization). (Noticed by Sergei).
There should be no functionality changes caused by this patch.
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-disk.c | 103 |
1 files changed, 32 insertions, 71 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index a4c4d4350560..88c270fad684 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -307,16 +307,19 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s | |||
307 | * Queries for true maximum capacity of the drive. | 307 | * Queries for true maximum capacity of the drive. |
308 | * Returns maximum LBA address (> 0) of the drive, 0 if failed. | 308 | * Returns maximum LBA address (> 0) of the drive, 0 if failed. |
309 | */ | 309 | */ |
310 | static unsigned long idedisk_read_native_max_address(ide_drive_t *drive) | 310 | static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) |
311 | { | 311 | { |
312 | ide_task_t args; | 312 | ide_task_t args; |
313 | struct ide_taskfile *tf = &args.tf; | 313 | struct ide_taskfile *tf = &args.tf; |
314 | unsigned long addr = 0; | 314 | u64 addr = 0; |
315 | 315 | ||
316 | /* Create IDE/ATA command request structure */ | 316 | /* Create IDE/ATA command request structure */ |
317 | memset(&args, 0, sizeof(ide_task_t)); | 317 | memset(&args, 0, sizeof(ide_task_t)); |
318 | if (lba48) | ||
319 | tf->command = WIN_READ_NATIVE_MAX_EXT; | ||
320 | else | ||
321 | tf->command = WIN_READ_NATIVE_MAX; | ||
318 | tf->device = ATA_LBA; | 322 | tf->device = ATA_LBA; |
319 | tf->command = WIN_READ_NATIVE_MAX; | ||
320 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 323 | args.command_type = IDE_DRIVE_TASK_NO_DATA; |
321 | args.handler = &task_no_data_intr; | 324 | args.handler = &task_no_data_intr; |
322 | /* submit command request */ | 325 | /* submit command request */ |
@@ -324,33 +327,13 @@ static unsigned long idedisk_read_native_max_address(ide_drive_t *drive) | |||
324 | 327 | ||
325 | /* if OK, compute maximum address value */ | 328 | /* if OK, compute maximum address value */ |
326 | if ((tf->status & 0x01) == 0) { | 329 | if ((tf->status & 0x01) == 0) { |
327 | addr = ((tf->device & 0xf) << 24) | | ||
328 | (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; | ||
329 | addr++; /* since the return value is (maxlba - 1), we add 1 */ | ||
330 | } | ||
331 | return addr; | ||
332 | } | ||
333 | |||
334 | static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive) | ||
335 | { | ||
336 | ide_task_t args; | ||
337 | struct ide_taskfile *tf = &args.tf; | ||
338 | unsigned long long addr = 0; | ||
339 | |||
340 | /* Create IDE/ATA command request structure */ | ||
341 | memset(&args, 0, sizeof(ide_task_t)); | ||
342 | tf->device = ATA_LBA; | ||
343 | tf->command = WIN_READ_NATIVE_MAX_EXT; | ||
344 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | ||
345 | args.handler = &task_no_data_intr; | ||
346 | /* submit command request */ | ||
347 | ide_raw_taskfile(drive, &args, NULL); | ||
348 | |||
349 | /* if OK, compute maximum address value */ | ||
350 | if ((tf->status & 0x01) == 0) { | ||
351 | u32 high, low; | 330 | u32 high, low; |
352 | 331 | ||
353 | high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | tf->hob_lbal; | 332 | if (lba48) |
333 | high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | | ||
334 | tf->hob_lbal; | ||
335 | else | ||
336 | high = tf->device & 0xf; | ||
354 | low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; | 337 | low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; |
355 | addr = ((__u64)high << 24) | low; | 338 | addr = ((__u64)high << 24) | low; |
356 | addr++; /* since the return value is (maxlba - 1), we add 1 */ | 339 | addr++; /* since the return value is (maxlba - 1), we add 1 */ |
@@ -362,38 +345,11 @@ static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive | |||
362 | * Sets maximum virtual LBA address of the drive. | 345 | * Sets maximum virtual LBA address of the drive. |
363 | * Returns new maximum virtual LBA address (> 0) or 0 on failure. | 346 | * Returns new maximum virtual LBA address (> 0) or 0 on failure. |
364 | */ | 347 | */ |
365 | static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req) | 348 | static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) |
366 | { | 349 | { |
367 | ide_task_t args; | 350 | ide_task_t args; |
368 | struct ide_taskfile *tf = &args.tf; | 351 | struct ide_taskfile *tf = &args.tf; |
369 | unsigned long addr_set = 0; | 352 | u64 addr_set = 0; |
370 | |||
371 | addr_req--; | ||
372 | /* Create IDE/ATA command request structure */ | ||
373 | memset(&args, 0, sizeof(ide_task_t)); | ||
374 | tf->lbal = (addr_req >> 0) & 0xff; | ||
375 | tf->lbam = (addr_req >> 8) & 0xff; | ||
376 | tf->lbah = (addr_req >> 16) & 0xff; | ||
377 | tf->device = ((addr_req >> 24) & 0x0f) | ATA_LBA; | ||
378 | tf->command = WIN_SET_MAX; | ||
379 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | ||
380 | args.handler = &task_no_data_intr; | ||
381 | /* submit command request */ | ||
382 | ide_raw_taskfile(drive, &args, NULL); | ||
383 | /* if OK, read new maximum address value */ | ||
384 | if ((tf->status & 0x01) == 0) { | ||
385 | addr_set = ((tf->device & 0xf) << 24) | | ||
386 | (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; | ||
387 | addr_set++; | ||
388 | } | ||
389 | return addr_set; | ||
390 | } | ||
391 | |||
392 | static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsigned long long addr_req) | ||
393 | { | ||
394 | ide_task_t args; | ||
395 | struct ide_taskfile *tf = &args.tf; | ||
396 | unsigned long long addr_set = 0; | ||
397 | 353 | ||
398 | addr_req--; | 354 | addr_req--; |
399 | /* Create IDE/ATA command request structure */ | 355 | /* Create IDE/ATA command request structure */ |
@@ -401,11 +357,16 @@ static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsign | |||
401 | tf->lbal = (addr_req >> 0) & 0xff; | 357 | tf->lbal = (addr_req >> 0) & 0xff; |
402 | tf->lbam = (addr_req >>= 8) & 0xff; | 358 | tf->lbam = (addr_req >>= 8) & 0xff; |
403 | tf->lbah = (addr_req >>= 8) & 0xff; | 359 | tf->lbah = (addr_req >>= 8) & 0xff; |
404 | tf->device = ATA_LBA; | 360 | if (lba48) { |
405 | tf->command = WIN_SET_MAX_EXT; | 361 | tf->hob_lbal = (addr_req >>= 8) & 0xff; |
406 | tf->hob_lbal = (addr_req >>= 8) & 0xff; | 362 | tf->hob_lbam = (addr_req >>= 8) & 0xff; |
407 | tf->hob_lbam = (addr_req >>= 8) & 0xff; | 363 | tf->hob_lbah = (addr_req >>= 8) & 0xff; |
408 | tf->hob_lbah = (addr_req >>= 8) & 0xff; | 364 | tf->command = WIN_SET_MAX_EXT; |
365 | } else { | ||
366 | tf->device = (addr_req >>= 8) & 0x0f; | ||
367 | tf->command = WIN_SET_MAX; | ||
368 | } | ||
369 | tf->device |= ATA_LBA; | ||
409 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 370 | args.command_type = IDE_DRIVE_TASK_NO_DATA; |
410 | args.handler = &task_no_data_intr; | 371 | args.handler = &task_no_data_intr; |
411 | /* submit command request */ | 372 | /* submit command request */ |
@@ -414,7 +375,11 @@ static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsign | |||
414 | if ((tf->status & 0x01) == 0) { | 375 | if ((tf->status & 0x01) == 0) { |
415 | u32 high, low; | 376 | u32 high, low; |
416 | 377 | ||
417 | high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | tf->hob_lbal; | 378 | if (lba48) |
379 | high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | | ||
380 | tf->hob_lbal; | ||
381 | else | ||
382 | high = tf->device & 0xf; | ||
418 | low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; | 383 | low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; |
419 | addr_set = ((__u64)high << 24) | low; | 384 | addr_set = ((__u64)high << 24) | low; |
420 | addr_set++; | 385 | addr_set++; |
@@ -464,10 +429,8 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
464 | int lba48 = idedisk_supports_lba48(drive->id); | 429 | int lba48 = idedisk_supports_lba48(drive->id); |
465 | 430 | ||
466 | capacity = drive->capacity64; | 431 | capacity = drive->capacity64; |
467 | if (lba48) | 432 | |
468 | set_max = idedisk_read_native_max_address_ext(drive); | 433 | set_max = idedisk_read_native_max_address(drive, lba48); |
469 | else | ||
470 | set_max = idedisk_read_native_max_address(drive); | ||
471 | 434 | ||
472 | if (ide_in_drive_list(drive->id, hpa_list)) { | 435 | if (ide_in_drive_list(drive->id, hpa_list)) { |
473 | /* | 436 | /* |
@@ -488,10 +451,8 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
488 | capacity, sectors_to_MB(capacity), | 451 | capacity, sectors_to_MB(capacity), |
489 | set_max, sectors_to_MB(set_max)); | 452 | set_max, sectors_to_MB(set_max)); |
490 | 453 | ||
491 | if (lba48) | 454 | set_max = idedisk_set_max_address(drive, set_max, lba48); |
492 | set_max = idedisk_set_max_address_ext(drive, set_max); | 455 | |
493 | else | ||
494 | set_max = idedisk_set_max_address(drive, set_max); | ||
495 | if (set_max) { | 456 | if (set_max) { |
496 | drive->capacity64 = set_max; | 457 | drive->capacity64 = set_max; |
497 | printk(KERN_INFO "%s: Host Protected Area disabled.\n", | 458 | printk(KERN_INFO "%s: Host Protected Area disabled.\n", |