aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-disk.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-01-25 16:17:06 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-01-25 16:17:06 -0500
commit7a3b7512d0d7e78353e99f4538eb6d3354019d92 (patch)
tree678b3fee02297f3dea5df8182198ecd701e69649 /drivers/ide/ide-disk.c
parent650d841d9e053a618dd8ce753422f91b493cf2f6 (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/ide-disk.c')
-rw-r--r--drivers/ide/ide-disk.c103
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 */
310static unsigned long idedisk_read_native_max_address(ide_drive_t *drive) 310static 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
334static 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 */
365static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req) 348static 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
392static 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",