aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-disk.c')
-rw-r--r--drivers/ide/ide-disk.c75
1 files changed, 63 insertions, 12 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index c6f7fcfb9d67..6a1de2169709 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -302,14 +302,12 @@ static const struct drive_list_entry hpa_list[] = {
302 { NULL, NULL } 302 { NULL, NULL }
303}; 303};
304 304
305static void idedisk_check_hpa(ide_drive_t *drive) 305static u64 ide_disk_hpa_get_native_capacity(ide_drive_t *drive, int lba48)
306{ 306{
307 unsigned long long capacity, set_max; 307 u64 capacity, set_max;
308 int lba48 = ata_id_lba48_enabled(drive->id);
309 308
310 capacity = drive->capacity64; 309 capacity = drive->capacity64;
311 310 set_max = idedisk_read_native_max_address(drive, lba48);
312 set_max = idedisk_read_native_max_address(drive, lba48);
313 311
314 if (ide_in_drive_list(drive->id, hpa_list)) { 312 if (ide_in_drive_list(drive->id, hpa_list)) {
315 /* 313 /*
@@ -320,9 +318,31 @@ static void idedisk_check_hpa(ide_drive_t *drive)
320 set_max--; 318 set_max--;
321 } 319 }
322 320
321 return set_max;
322}
323
324static u64 ide_disk_hpa_set_capacity(ide_drive_t *drive, u64 set_max, int lba48)
325{
326 set_max = idedisk_set_max_address(drive, set_max, lba48);
327 if (set_max)
328 drive->capacity64 = set_max;
329
330 return set_max;
331}
332
333static void idedisk_check_hpa(ide_drive_t *drive)
334{
335 u64 capacity, set_max;
336 int lba48 = ata_id_lba48_enabled(drive->id);
337
338 capacity = drive->capacity64;
339 set_max = ide_disk_hpa_get_native_capacity(drive, lba48);
340
323 if (set_max <= capacity) 341 if (set_max <= capacity)
324 return; 342 return;
325 343
344 drive->probed_capacity = set_max;
345
326 printk(KERN_INFO "%s: Host Protected Area detected.\n" 346 printk(KERN_INFO "%s: Host Protected Area detected.\n"
327 "\tcurrent capacity is %llu sectors (%llu MB)\n" 347 "\tcurrent capacity is %llu sectors (%llu MB)\n"
328 "\tnative capacity is %llu sectors (%llu MB)\n", 348 "\tnative capacity is %llu sectors (%llu MB)\n",
@@ -330,13 +350,13 @@ static void idedisk_check_hpa(ide_drive_t *drive)
330 capacity, sectors_to_MB(capacity), 350 capacity, sectors_to_MB(capacity),
331 set_max, sectors_to_MB(set_max)); 351 set_max, sectors_to_MB(set_max));
332 352
333 set_max = idedisk_set_max_address(drive, set_max, lba48); 353 if ((drive->dev_flags & IDE_DFLAG_NOHPA) == 0)
354 return;
334 355
335 if (set_max) { 356 set_max = ide_disk_hpa_set_capacity(drive, set_max, lba48);
336 drive->capacity64 = set_max; 357 if (set_max)
337 printk(KERN_INFO "%s: Host Protected Area disabled.\n", 358 printk(KERN_INFO "%s: Host Protected Area disabled.\n",
338 drive->name); 359 drive->name);
339 }
340} 360}
341 361
342static int ide_disk_get_capacity(ide_drive_t *drive) 362static int ide_disk_get_capacity(ide_drive_t *drive)
@@ -358,6 +378,8 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
358 drive->capacity64 = drive->cyl * drive->head * drive->sect; 378 drive->capacity64 = drive->cyl * drive->head * drive->sect;
359 } 379 }
360 380
381 drive->probed_capacity = drive->capacity64;
382
361 if (lba) { 383 if (lba) {
362 drive->dev_flags |= IDE_DFLAG_LBA; 384 drive->dev_flags |= IDE_DFLAG_LBA;
363 385
@@ -376,7 +398,7 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
376 "%llu sectors (%llu MB)\n", 398 "%llu sectors (%llu MB)\n",
377 drive->name, (unsigned long long)drive->capacity64, 399 drive->name, (unsigned long long)drive->capacity64,
378 sectors_to_MB(drive->capacity64)); 400 sectors_to_MB(drive->capacity64));
379 drive->capacity64 = 1ULL << 28; 401 drive->probed_capacity = drive->capacity64 = 1ULL << 28;
380 } 402 }
381 403
382 if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && 404 if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
@@ -392,6 +414,34 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
392 return 0; 414 return 0;
393} 415}
394 416
417static u64 ide_disk_set_capacity(ide_drive_t *drive, u64 capacity)
418{
419 u64 set = min(capacity, drive->probed_capacity);
420 u16 *id = drive->id;
421 int lba48 = ata_id_lba48_enabled(id);
422
423 if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 ||
424 ata_id_hpa_enabled(id) == 0)
425 goto out;
426
427 /*
428 * according to the spec the SET MAX ADDRESS command shall be
429 * immediately preceded by a READ NATIVE MAX ADDRESS command
430 */
431 capacity = ide_disk_hpa_get_native_capacity(drive, lba48);
432 if (capacity == 0)
433 goto out;
434
435 set = ide_disk_hpa_set_capacity(drive, set, lba48);
436 if (set) {
437 /* needed for ->resume to disable HPA */
438 drive->dev_flags |= IDE_DFLAG_NOHPA;
439 return set;
440 }
441out:
442 return drive->capacity64;
443}
444
395static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) 445static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
396{ 446{
397 ide_drive_t *drive = q->queuedata; 447 ide_drive_t *drive = q->queuedata;
@@ -428,14 +478,14 @@ static int set_multcount(ide_drive_t *drive, int arg)
428 if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff)) 478 if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff))
429 return -EINVAL; 479 return -EINVAL;
430 480
431 if (drive->special.b.set_multmode) 481 if (drive->special_flags & IDE_SFLAG_SET_MULTMODE)
432 return -EBUSY; 482 return -EBUSY;
433 483
434 rq = blk_get_request(drive->queue, READ, __GFP_WAIT); 484 rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
435 rq->cmd_type = REQ_TYPE_ATA_TASKFILE; 485 rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
436 486
437 drive->mult_req = arg; 487 drive->mult_req = arg;
438 drive->special.b.set_multmode = 1; 488 drive->special_flags |= IDE_SFLAG_SET_MULTMODE;
439 error = blk_execute_rq(drive->queue, NULL, rq, 0); 489 error = blk_execute_rq(drive->queue, NULL, rq, 0);
440 blk_put_request(rq); 490 blk_put_request(rq);
441 491
@@ -740,6 +790,7 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
740 790
741const struct ide_disk_ops ide_ata_disk_ops = { 791const struct ide_disk_ops ide_ata_disk_ops = {
742 .check = ide_disk_check, 792 .check = ide_disk_check,
793 .set_capacity = ide_disk_set_capacity,
743 .get_capacity = ide_disk_get_capacity, 794 .get_capacity = ide_disk_get_capacity,
744 .setup = ide_disk_setup, 795 .setup = ide_disk_setup,
745 .flush = ide_disk_flush, 796 .flush = ide_disk_flush,