diff options
author | David S. Miller <davem@davemloft.net> | 2009-06-15 06:02:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-15 06:02:23 -0400 |
commit | 9cbc1cb8cd46ce1f7645b9de249b2ce8460129bb (patch) | |
tree | 8d104ec2a459346b99413b0b77421ca7b9936c1a /drivers/ide/ide-disk.c | |
parent | ca44d6e60f9de26281fda203f58b570e1748c015 (diff) | |
parent | 45e3e1935e2857c54783291107d33323b3ef33c8 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
Documentation/feature-removal-schedule.txt
drivers/scsi/fcoe/fcoe.c
net/core/drop_monitor.c
net/core/net-traces.c
Diffstat (limited to 'drivers/ide/ide-disk.c')
-rw-r--r-- | drivers/ide/ide-disk.c | 86 |
1 files changed, 68 insertions, 18 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index a9fbe2c31210..6a1de2169709 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -82,7 +82,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
82 | sector_t block) | 82 | sector_t block) |
83 | { | 83 | { |
84 | ide_hwif_t *hwif = drive->hwif; | 84 | ide_hwif_t *hwif = drive->hwif; |
85 | u16 nsectors = (u16)rq->nr_sectors; | 85 | u16 nsectors = (u16)blk_rq_sectors(rq); |
86 | u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); | 86 | u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); |
87 | u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | 87 | u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); |
88 | struct ide_cmd cmd; | 88 | struct ide_cmd cmd; |
@@ -90,7 +90,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
90 | ide_startstop_t rc; | 90 | ide_startstop_t rc; |
91 | 91 | ||
92 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { | 92 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { |
93 | if (block + rq->nr_sectors > 1ULL << 28) | 93 | if (block + blk_rq_sectors(rq) > 1ULL << 28) |
94 | dma = 0; | 94 | dma = 0; |
95 | else | 95 | else |
96 | lba48 = 0; | 96 | lba48 = 0; |
@@ -195,9 +195,9 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
195 | 195 | ||
196 | ledtrig_ide_activity(); | 196 | ledtrig_ide_activity(); |
197 | 197 | ||
198 | pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", | 198 | pr_debug("%s: %sing: block=%llu, sectors=%u, buffer=0x%08lx\n", |
199 | drive->name, rq_data_dir(rq) == READ ? "read" : "writ", | 199 | drive->name, rq_data_dir(rq) == READ ? "read" : "writ", |
200 | (unsigned long long)block, rq->nr_sectors, | 200 | (unsigned long long)block, blk_rq_sectors(rq), |
201 | (unsigned long)rq->buffer); | 201 | (unsigned long)rq->buffer); |
202 | 202 | ||
203 | if (hwif->rw_disk) | 203 | if (hwif->rw_disk) |
@@ -302,14 +302,12 @@ static const struct drive_list_entry hpa_list[] = { | |||
302 | { NULL, NULL } | 302 | { NULL, NULL } |
303 | }; | 303 | }; |
304 | 304 | ||
305 | static void idedisk_check_hpa(ide_drive_t *drive) | 305 | static 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 | |||
324 | static 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 | |||
333 | static 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 | ||
342 | static int ide_disk_get_capacity(ide_drive_t *drive) | 362 | static 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 | ||
417 | static 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 | } | ||
441 | out: | ||
442 | return drive->capacity64; | ||
443 | } | ||
444 | |||
395 | static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | 445 | static 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; |
@@ -411,7 +461,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | |||
411 | cmd->protocol = ATA_PROT_NODATA; | 461 | cmd->protocol = ATA_PROT_NODATA; |
412 | 462 | ||
413 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; | 463 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; |
414 | rq->cmd_flags |= REQ_SOFTBARRIER; | ||
415 | rq->special = cmd; | 464 | rq->special = cmd; |
416 | } | 465 | } |
417 | 466 | ||
@@ -429,14 +478,14 @@ static int set_multcount(ide_drive_t *drive, int arg) | |||
429 | if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff)) | 478 | if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff)) |
430 | return -EINVAL; | 479 | return -EINVAL; |
431 | 480 | ||
432 | if (drive->special.b.set_multmode) | 481 | if (drive->special_flags & IDE_SFLAG_SET_MULTMODE) |
433 | return -EBUSY; | 482 | return -EBUSY; |
434 | 483 | ||
435 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | 484 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); |
436 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; | 485 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; |
437 | 486 | ||
438 | drive->mult_req = arg; | 487 | drive->mult_req = arg; |
439 | drive->special.b.set_multmode = 1; | 488 | drive->special_flags |= IDE_SFLAG_SET_MULTMODE; |
440 | error = blk_execute_rq(drive->queue, NULL, rq, 0); | 489 | error = blk_execute_rq(drive->queue, NULL, rq, 0); |
441 | blk_put_request(rq); | 490 | blk_put_request(rq); |
442 | 491 | ||
@@ -640,7 +689,7 @@ static void ide_disk_setup(ide_drive_t *drive) | |||
640 | } | 689 | } |
641 | 690 | ||
642 | printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, | 691 | printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name, |
643 | q->max_sectors / 2); | 692 | queue_max_sectors(q) / 2); |
644 | 693 | ||
645 | if (ata_id_is_ssd(id)) | 694 | if (ata_id_is_ssd(id)) |
646 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); | 695 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q); |
@@ -741,6 +790,7 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, | |||
741 | 790 | ||
742 | const struct ide_disk_ops ide_ata_disk_ops = { | 791 | const struct ide_disk_ops ide_ata_disk_ops = { |
743 | .check = ide_disk_check, | 792 | .check = ide_disk_check, |
793 | .set_capacity = ide_disk_set_capacity, | ||
744 | .get_capacity = ide_disk_get_capacity, | 794 | .get_capacity = ide_disk_get_capacity, |
745 | .setup = ide_disk_setup, | 795 | .setup = ide_disk_setup, |
746 | .flush = ide_disk_flush, | 796 | .flush = ide_disk_flush, |