diff options
Diffstat (limited to 'drivers/ide/ide-disk.c')
-rw-r--r-- | drivers/ide/ide-disk.c | 355 |
1 files changed, 137 insertions, 218 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 07ef88bd109b..01846f244b40 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -30,10 +30,8 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
32 | #include <linux/leds.h> | 32 | #include <linux/leds.h> |
33 | |||
34 | #define _IDE_DISK | ||
35 | |||
36 | #include <linux/ide.h> | 33 | #include <linux/ide.h> |
34 | #include <linux/hdreg.h> | ||
37 | 35 | ||
38 | #include <asm/byteorder.h> | 36 | #include <asm/byteorder.h> |
39 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
@@ -41,6 +39,12 @@ | |||
41 | #include <asm/io.h> | 39 | #include <asm/io.h> |
42 | #include <asm/div64.h> | 40 | #include <asm/div64.h> |
43 | 41 | ||
42 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | ||
43 | #define IDE_DISK_MINORS (1 << PARTN_BITS) | ||
44 | #else | ||
45 | #define IDE_DISK_MINORS 0 | ||
46 | #endif | ||
47 | |||
44 | struct ide_disk_obj { | 48 | struct ide_disk_obj { |
45 | ide_drive_t *drive; | 49 | ide_drive_t *drive; |
46 | ide_driver_t *driver; | 50 | ide_driver_t *driver; |
@@ -84,68 +88,19 @@ static void ide_disk_put(struct ide_disk_obj *idkp) | |||
84 | mutex_unlock(&idedisk_ref_mutex); | 88 | mutex_unlock(&idedisk_ref_mutex); |
85 | } | 89 | } |
86 | 90 | ||
87 | /* | ||
88 | * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity" | ||
89 | * value for this drive (from its reported identification information). | ||
90 | * | ||
91 | * Returns: 1 if lba_capacity looks sensible | ||
92 | * 0 otherwise | ||
93 | * | ||
94 | * It is called only once for each drive. | ||
95 | */ | ||
96 | static int lba_capacity_is_ok(struct hd_driveid *id) | ||
97 | { | ||
98 | unsigned long lba_sects, chs_sects, head, tail; | ||
99 | |||
100 | /* No non-LBA info .. so valid! */ | ||
101 | if (id->cyls == 0) | ||
102 | return 1; | ||
103 | |||
104 | /* | ||
105 | * The ATA spec tells large drives to return | ||
106 | * C/H/S = 16383/16/63 independent of their size. | ||
107 | * Some drives can be jumpered to use 15 heads instead of 16. | ||
108 | * Some drives can be jumpered to use 4092 cyls instead of 16383. | ||
109 | */ | ||
110 | if ((id->cyls == 16383 | ||
111 | || (id->cyls == 4092 && id->cur_cyls == 16383)) && | ||
112 | id->sectors == 63 && | ||
113 | (id->heads == 15 || id->heads == 16) && | ||
114 | (id->lba_capacity >= 16383*63*id->heads)) | ||
115 | return 1; | ||
116 | |||
117 | lba_sects = id->lba_capacity; | ||
118 | chs_sects = id->cyls * id->heads * id->sectors; | ||
119 | |||
120 | /* perform a rough sanity check on lba_sects: within 10% is OK */ | ||
121 | if ((lba_sects - chs_sects) < chs_sects/10) | ||
122 | return 1; | ||
123 | |||
124 | /* some drives have the word order reversed */ | ||
125 | head = ((lba_sects >> 16) & 0xffff); | ||
126 | tail = (lba_sects & 0xffff); | ||
127 | lba_sects = (head | (tail << 16)); | ||
128 | if ((lba_sects - chs_sects) < chs_sects/10) { | ||
129 | id->lba_capacity = lba_sects; | ||
130 | return 1; /* lba_capacity is (now) good */ | ||
131 | } | ||
132 | |||
133 | return 0; /* lba_capacity value may be bad */ | ||
134 | } | ||
135 | |||
136 | static const u8 ide_rw_cmds[] = { | 91 | static const u8 ide_rw_cmds[] = { |
137 | WIN_MULTREAD, | 92 | ATA_CMD_READ_MULTI, |
138 | WIN_MULTWRITE, | 93 | ATA_CMD_WRITE_MULTI, |
139 | WIN_MULTREAD_EXT, | 94 | ATA_CMD_READ_MULTI_EXT, |
140 | WIN_MULTWRITE_EXT, | 95 | ATA_CMD_WRITE_MULTI_EXT, |
141 | WIN_READ, | 96 | ATA_CMD_PIO_READ, |
142 | WIN_WRITE, | 97 | ATA_CMD_PIO_WRITE, |
143 | WIN_READ_EXT, | 98 | ATA_CMD_PIO_READ_EXT, |
144 | WIN_WRITE_EXT, | 99 | ATA_CMD_PIO_WRITE_EXT, |
145 | WIN_READDMA, | 100 | ATA_CMD_READ, |
146 | WIN_WRITEDMA, | 101 | ATA_CMD_WRITE, |
147 | WIN_READDMA_EXT, | 102 | ATA_CMD_READ_EXT, |
148 | WIN_WRITEDMA_EXT, | 103 | ATA_CMD_WRITE_EXT, |
149 | }; | 104 | }; |
150 | 105 | ||
151 | static const u8 ide_data_phases[] = { | 106 | static const u8 ide_data_phases[] = { |
@@ -316,9 +271,9 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) | |||
316 | /* Create IDE/ATA command request structure */ | 271 | /* Create IDE/ATA command request structure */ |
317 | memset(&args, 0, sizeof(ide_task_t)); | 272 | memset(&args, 0, sizeof(ide_task_t)); |
318 | if (lba48) | 273 | if (lba48) |
319 | tf->command = WIN_READ_NATIVE_MAX_EXT; | 274 | tf->command = ATA_CMD_READ_NATIVE_MAX_EXT; |
320 | else | 275 | else |
321 | tf->command = WIN_READ_NATIVE_MAX; | 276 | tf->command = ATA_CMD_READ_NATIVE_MAX; |
322 | tf->device = ATA_LBA; | 277 | tf->device = ATA_LBA; |
323 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 278 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
324 | if (lba48) | 279 | if (lba48) |
@@ -353,10 +308,10 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) | |||
353 | tf->hob_lbal = (addr_req >>= 8) & 0xff; | 308 | tf->hob_lbal = (addr_req >>= 8) & 0xff; |
354 | tf->hob_lbam = (addr_req >>= 8) & 0xff; | 309 | tf->hob_lbam = (addr_req >>= 8) & 0xff; |
355 | tf->hob_lbah = (addr_req >>= 8) & 0xff; | 310 | tf->hob_lbah = (addr_req >>= 8) & 0xff; |
356 | tf->command = WIN_SET_MAX_EXT; | 311 | tf->command = ATA_CMD_SET_MAX_EXT; |
357 | } else { | 312 | } else { |
358 | tf->device = (addr_req >>= 8) & 0x0f; | 313 | tf->device = (addr_req >>= 8) & 0x0f; |
359 | tf->command = WIN_SET_MAX; | 314 | tf->command = ATA_CMD_SET_MAX; |
360 | } | 315 | } |
361 | tf->device |= ATA_LBA; | 316 | tf->device |= ATA_LBA; |
362 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 317 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
@@ -379,25 +334,6 @@ static unsigned long long sectors_to_MB(unsigned long long n) | |||
379 | } | 334 | } |
380 | 335 | ||
381 | /* | 336 | /* |
382 | * Bits 10 of command_set_1 and cfs_enable_1 must be equal, | ||
383 | * so on non-buggy drives we need test only one. | ||
384 | * However, we should also check whether these fields are valid. | ||
385 | */ | ||
386 | static inline int idedisk_supports_hpa(const struct hd_driveid *id) | ||
387 | { | ||
388 | return (id->command_set_1 & 0x0400) && (id->cfs_enable_1 & 0x0400); | ||
389 | } | ||
390 | |||
391 | /* | ||
392 | * The same here. | ||
393 | */ | ||
394 | static inline int idedisk_supports_lba48(const struct hd_driveid *id) | ||
395 | { | ||
396 | return (id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) | ||
397 | && id->lba_capacity_2; | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * Some disks report total number of sectors instead of | 337 | * Some disks report total number of sectors instead of |
402 | * maximum sector address. We list them here. | 338 | * maximum sector address. We list them here. |
403 | */ | 339 | */ |
@@ -411,7 +347,7 @@ static const struct drive_list_entry hpa_list[] = { | |||
411 | static void idedisk_check_hpa(ide_drive_t *drive) | 347 | static void idedisk_check_hpa(ide_drive_t *drive) |
412 | { | 348 | { |
413 | unsigned long long capacity, set_max; | 349 | unsigned long long capacity, set_max; |
414 | int lba48 = idedisk_supports_lba48(drive->id); | 350 | int lba48 = ata_id_lba48_enabled(drive->id); |
415 | 351 | ||
416 | capacity = drive->capacity64; | 352 | capacity = drive->capacity64; |
417 | 353 | ||
@@ -447,23 +383,23 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
447 | 383 | ||
448 | static void init_idedisk_capacity(ide_drive_t *drive) | 384 | static void init_idedisk_capacity(ide_drive_t *drive) |
449 | { | 385 | { |
450 | struct hd_driveid *id = drive->id; | 386 | u16 *id = drive->id; |
451 | /* | 387 | /* |
452 | * If this drive supports the Host Protected Area feature set, | 388 | * If this drive supports the Host Protected Area feature set, |
453 | * then we may need to change our opinion about the drive's capacity. | 389 | * then we may need to change our opinion about the drive's capacity. |
454 | */ | 390 | */ |
455 | int hpa = idedisk_supports_hpa(id); | 391 | int hpa = ata_id_hpa_enabled(id); |
456 | 392 | ||
457 | if (idedisk_supports_lba48(id)) { | 393 | if (ata_id_lba48_enabled(id)) { |
458 | /* drive speaks 48-bit LBA */ | 394 | /* drive speaks 48-bit LBA */ |
459 | drive->select.b.lba = 1; | 395 | drive->select.b.lba = 1; |
460 | drive->capacity64 = id->lba_capacity_2; | 396 | drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); |
461 | if (hpa) | 397 | if (hpa) |
462 | idedisk_check_hpa(drive); | 398 | idedisk_check_hpa(drive); |
463 | } else if ((id->capability & 2) && lba_capacity_is_ok(id)) { | 399 | } else if (ata_id_has_lba(id) && ata_id_is_lba_capacity_ok(id)) { |
464 | /* drive speaks 28-bit LBA */ | 400 | /* drive speaks 28-bit LBA */ |
465 | drive->select.b.lba = 1; | 401 | drive->select.b.lba = 1; |
466 | drive->capacity64 = id->lba_capacity; | 402 | drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY); |
467 | if (hpa) | 403 | if (hpa) |
468 | idedisk_check_hpa(drive); | 404 | idedisk_check_hpa(drive); |
469 | } else { | 405 | } else { |
@@ -474,7 +410,7 @@ static void init_idedisk_capacity(ide_drive_t *drive) | |||
474 | 410 | ||
475 | static sector_t idedisk_capacity(ide_drive_t *drive) | 411 | static sector_t idedisk_capacity(ide_drive_t *drive) |
476 | { | 412 | { |
477 | return drive->capacity64 - drive->sect0; | 413 | return drive->capacity64; |
478 | } | 414 | } |
479 | 415 | ||
480 | #ifdef CONFIG_IDE_PROC_FS | 416 | #ifdef CONFIG_IDE_PROC_FS |
@@ -484,10 +420,10 @@ static int smart_enable(ide_drive_t *drive) | |||
484 | struct ide_taskfile *tf = &args.tf; | 420 | struct ide_taskfile *tf = &args.tf; |
485 | 421 | ||
486 | memset(&args, 0, sizeof(ide_task_t)); | 422 | memset(&args, 0, sizeof(ide_task_t)); |
487 | tf->feature = SMART_ENABLE; | 423 | tf->feature = ATA_SMART_ENABLE; |
488 | tf->lbam = SMART_LCYL_PASS; | 424 | tf->lbam = ATA_SMART_LBAM_PASS; |
489 | tf->lbah = SMART_HCYL_PASS; | 425 | tf->lbah = ATA_SMART_LBAH_PASS; |
490 | tf->command = WIN_SMART; | 426 | tf->command = ATA_CMD_SMART; |
491 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 427 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
492 | return ide_no_data_taskfile(drive, &args); | 428 | return ide_no_data_taskfile(drive, &args); |
493 | } | 429 | } |
@@ -500,9 +436,9 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) | |||
500 | memset(&args, 0, sizeof(ide_task_t)); | 436 | memset(&args, 0, sizeof(ide_task_t)); |
501 | tf->feature = sub_cmd; | 437 | tf->feature = sub_cmd; |
502 | tf->nsect = 0x01; | 438 | tf->nsect = 0x01; |
503 | tf->lbam = SMART_LCYL_PASS; | 439 | tf->lbam = ATA_SMART_LBAM_PASS; |
504 | tf->lbah = SMART_HCYL_PASS; | 440 | tf->lbah = ATA_SMART_LBAH_PASS; |
505 | tf->command = WIN_SMART; | 441 | tf->command = ATA_CMD_SMART; |
506 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 442 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
507 | args.data_phase = TASKFILE_IN; | 443 | args.data_phase = TASKFILE_IN; |
508 | (void) smart_enable(drive); | 444 | (void) smart_enable(drive); |
@@ -517,7 +453,7 @@ static int proc_idedisk_read_cache | |||
517 | int len; | 453 | int len; |
518 | 454 | ||
519 | if (drive->id_read) | 455 | if (drive->id_read) |
520 | len = sprintf(out, "%i\n", drive->id->buf_size / 2); | 456 | len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); |
521 | else | 457 | else |
522 | len = sprintf(out, "(none)\n"); | 458 | len = sprintf(out, "(none)\n"); |
523 | 459 | ||
@@ -543,13 +479,14 @@ static int proc_idedisk_read_smart(char *page, char **start, off_t off, | |||
543 | 479 | ||
544 | if (get_smart_data(drive, page, sub_cmd) == 0) { | 480 | if (get_smart_data(drive, page, sub_cmd) == 0) { |
545 | unsigned short *val = (unsigned short *) page; | 481 | unsigned short *val = (unsigned short *) page; |
546 | char *out = ((char *)val) + (SECTOR_WORDS * 4); | 482 | char *out = (char *)val + SECTOR_SIZE; |
483 | |||
547 | page = out; | 484 | page = out; |
548 | do { | 485 | do { |
549 | out += sprintf(out, "%04x%c", le16_to_cpu(*val), | 486 | out += sprintf(out, "%04x%c", le16_to_cpu(*val), |
550 | (++i & 7) ? ' ' : '\n'); | 487 | (++i & 7) ? ' ' : '\n'); |
551 | val += 1; | 488 | val += 1; |
552 | } while (i < (SECTOR_WORDS * 2)); | 489 | } while (i < SECTOR_SIZE / 2); |
553 | len = out - page; | 490 | len = out - page; |
554 | } | 491 | } |
555 | 492 | ||
@@ -560,14 +497,14 @@ static int proc_idedisk_read_sv | |||
560 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 497 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
561 | { | 498 | { |
562 | return proc_idedisk_read_smart(page, start, off, count, eof, data, | 499 | return proc_idedisk_read_smart(page, start, off, count, eof, data, |
563 | SMART_READ_VALUES); | 500 | ATA_SMART_READ_VALUES); |
564 | } | 501 | } |
565 | 502 | ||
566 | static int proc_idedisk_read_st | 503 | static int proc_idedisk_read_st |
567 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 504 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
568 | { | 505 | { |
569 | return proc_idedisk_read_smart(page, start, off, count, eof, data, | 506 | return proc_idedisk_read_smart(page, start, off, count, eof, data, |
570 | SMART_READ_THRESHOLDS); | 507 | ATA_SMART_READ_THRESHOLDS); |
571 | } | 508 | } |
572 | 509 | ||
573 | static ide_proc_entry_t idedisk_proc[] = { | 510 | static ide_proc_entry_t idedisk_proc[] = { |
@@ -589,11 +526,11 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | |||
589 | BUG_ON(task == NULL); | 526 | BUG_ON(task == NULL); |
590 | 527 | ||
591 | memset(task, 0, sizeof(*task)); | 528 | memset(task, 0, sizeof(*task)); |
592 | if (ide_id_has_flush_cache_ext(drive->id) && | 529 | if (ata_id_flush_ext_enabled(drive->id) && |
593 | (drive->capacity64 >= (1UL << 28))) | 530 | (drive->capacity64 >= (1UL << 28))) |
594 | task->tf.command = WIN_FLUSH_CACHE_EXT; | 531 | task->tf.command = ATA_CMD_FLUSH_EXT; |
595 | else | 532 | else |
596 | task->tf.command = WIN_FLUSH_CACHE; | 533 | task->tf.command = ATA_CMD_FLUSH; |
597 | task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | | 534 | task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | |
598 | IDE_TFLAG_DYN; | 535 | IDE_TFLAG_DYN; |
599 | task->data_phase = TASKFILE_NO_DATA; | 536 | task->data_phase = TASKFILE_NO_DATA; |
@@ -603,6 +540,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | |||
603 | rq->special = task; | 540 | rq->special = task; |
604 | } | 541 | } |
605 | 542 | ||
543 | ide_devset_get(multcount, mult_count); | ||
544 | |||
606 | /* | 545 | /* |
607 | * This is tightly woven into the driver->do_special can not touch. | 546 | * This is tightly woven into the driver->do_special can not touch. |
608 | * DON'T do it again until a total personality rewrite is committed. | 547 | * DON'T do it again until a total personality rewrite is committed. |
@@ -612,7 +551,7 @@ static int set_multcount(ide_drive_t *drive, int arg) | |||
612 | struct request *rq; | 551 | struct request *rq; |
613 | int error; | 552 | int error; |
614 | 553 | ||
615 | if (arg < 0 || arg > drive->id->max_multsect) | 554 | if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff)) |
616 | return -EINVAL; | 555 | return -EINVAL; |
617 | 556 | ||
618 | if (drive->special.b.set_multmode) | 557 | if (drive->special.b.set_multmode) |
@@ -629,22 +568,21 @@ static int set_multcount(ide_drive_t *drive, int arg) | |||
629 | return (drive->mult_count == arg) ? 0 : -EIO; | 568 | return (drive->mult_count == arg) ? 0 : -EIO; |
630 | } | 569 | } |
631 | 570 | ||
571 | ide_devset_get(nowerr, nowerr); | ||
572 | |||
632 | static int set_nowerr(ide_drive_t *drive, int arg) | 573 | static int set_nowerr(ide_drive_t *drive, int arg) |
633 | { | 574 | { |
634 | if (arg < 0 || arg > 1) | 575 | if (arg < 0 || arg > 1) |
635 | return -EINVAL; | 576 | return -EINVAL; |
636 | 577 | ||
637 | if (ide_spin_wait_hwgroup(drive)) | ||
638 | return -EBUSY; | ||
639 | drive->nowerr = arg; | 578 | drive->nowerr = arg; |
640 | drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; | 579 | drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; |
641 | spin_unlock_irq(&ide_lock); | ||
642 | return 0; | 580 | return 0; |
643 | } | 581 | } |
644 | 582 | ||
645 | static void update_ordered(ide_drive_t *drive) | 583 | static void update_ordered(ide_drive_t *drive) |
646 | { | 584 | { |
647 | struct hd_driveid *id = drive->id; | 585 | u16 *id = drive->id; |
648 | unsigned ordered = QUEUE_ORDERED_NONE; | 586 | unsigned ordered = QUEUE_ORDERED_NONE; |
649 | prepare_flush_fn *prep_fn = NULL; | 587 | prepare_flush_fn *prep_fn = NULL; |
650 | 588 | ||
@@ -660,9 +598,9 @@ static void update_ordered(ide_drive_t *drive) | |||
660 | * not available so we don't need to recheck that. | 598 | * not available so we don't need to recheck that. |
661 | */ | 599 | */ |
662 | capacity = idedisk_capacity(drive); | 600 | capacity = idedisk_capacity(drive); |
663 | barrier = ide_id_has_flush_cache(id) && !drive->noflush && | 601 | barrier = ata_id_flush_enabled(id) && !drive->noflush && |
664 | (drive->addressing == 0 || capacity <= (1ULL << 28) || | 602 | (drive->addressing == 0 || capacity <= (1ULL << 28) || |
665 | ide_id_has_flush_cache_ext(id)); | 603 | ata_id_flush_ext_enabled(id)); |
666 | 604 | ||
667 | printk(KERN_INFO "%s: cache flushes %ssupported\n", | 605 | printk(KERN_INFO "%s: cache flushes %ssupported\n", |
668 | drive->name, barrier ? "" : "not "); | 606 | drive->name, barrier ? "" : "not "); |
@@ -677,7 +615,9 @@ static void update_ordered(ide_drive_t *drive) | |||
677 | blk_queue_ordered(drive->queue, ordered, prep_fn); | 615 | blk_queue_ordered(drive->queue, ordered, prep_fn); |
678 | } | 616 | } |
679 | 617 | ||
680 | static int write_cache(ide_drive_t *drive, int arg) | 618 | ide_devset_get(wcache, wcache); |
619 | |||
620 | static int set_wcache(ide_drive_t *drive, int arg) | ||
681 | { | 621 | { |
682 | ide_task_t args; | 622 | ide_task_t args; |
683 | int err = 1; | 623 | int err = 1; |
@@ -685,11 +625,11 @@ static int write_cache(ide_drive_t *drive, int arg) | |||
685 | if (arg < 0 || arg > 1) | 625 | if (arg < 0 || arg > 1) |
686 | return -EINVAL; | 626 | return -EINVAL; |
687 | 627 | ||
688 | if (ide_id_has_flush_cache(drive->id)) { | 628 | if (ata_id_flush_enabled(drive->id)) { |
689 | memset(&args, 0, sizeof(ide_task_t)); | 629 | memset(&args, 0, sizeof(ide_task_t)); |
690 | args.tf.feature = arg ? | 630 | args.tf.feature = arg ? |
691 | SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; | 631 | SETFEATURES_WC_ON : SETFEATURES_WC_OFF; |
692 | args.tf.command = WIN_SETFEATURES; | 632 | args.tf.command = ATA_CMD_SET_FEATURES; |
693 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 633 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
694 | err = ide_no_data_taskfile(drive, &args); | 634 | err = ide_no_data_taskfile(drive, &args); |
695 | if (err == 0) | 635 | if (err == 0) |
@@ -706,14 +646,16 @@ static int do_idedisk_flushcache(ide_drive_t *drive) | |||
706 | ide_task_t args; | 646 | ide_task_t args; |
707 | 647 | ||
708 | memset(&args, 0, sizeof(ide_task_t)); | 648 | memset(&args, 0, sizeof(ide_task_t)); |
709 | if (ide_id_has_flush_cache_ext(drive->id)) | 649 | if (ata_id_flush_ext_enabled(drive->id)) |
710 | args.tf.command = WIN_FLUSH_CACHE_EXT; | 650 | args.tf.command = ATA_CMD_FLUSH_EXT; |
711 | else | 651 | else |
712 | args.tf.command = WIN_FLUSH_CACHE; | 652 | args.tf.command = ATA_CMD_FLUSH; |
713 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 653 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
714 | return ide_no_data_taskfile(drive, &args); | 654 | return ide_no_data_taskfile(drive, &args); |
715 | } | 655 | } |
716 | 656 | ||
657 | ide_devset_get(acoustic, acoustic); | ||
658 | |||
717 | static int set_acoustic(ide_drive_t *drive, int arg) | 659 | static int set_acoustic(ide_drive_t *drive, int arg) |
718 | { | 660 | { |
719 | ide_task_t args; | 661 | ide_task_t args; |
@@ -722,22 +664,24 @@ static int set_acoustic(ide_drive_t *drive, int arg) | |||
722 | return -EINVAL; | 664 | return -EINVAL; |
723 | 665 | ||
724 | memset(&args, 0, sizeof(ide_task_t)); | 666 | memset(&args, 0, sizeof(ide_task_t)); |
725 | args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM; | 667 | args.tf.feature = arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF; |
726 | args.tf.nsect = arg; | 668 | args.tf.nsect = arg; |
727 | args.tf.command = WIN_SETFEATURES; | 669 | args.tf.command = ATA_CMD_SET_FEATURES; |
728 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 670 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
729 | ide_no_data_taskfile(drive, &args); | 671 | ide_no_data_taskfile(drive, &args); |
730 | drive->acoustic = arg; | 672 | drive->acoustic = arg; |
731 | return 0; | 673 | return 0; |
732 | } | 674 | } |
733 | 675 | ||
676 | ide_devset_get(addressing, addressing); | ||
677 | |||
734 | /* | 678 | /* |
735 | * drive->addressing: | 679 | * drive->addressing: |
736 | * 0: 28-bit | 680 | * 0: 28-bit |
737 | * 1: 48-bit | 681 | * 1: 48-bit |
738 | * 2: 48-bit capable doing 28-bit | 682 | * 2: 48-bit capable doing 28-bit |
739 | */ | 683 | */ |
740 | static int set_lba_addressing(ide_drive_t *drive, int arg) | 684 | static int set_addressing(ide_drive_t *drive, int arg) |
741 | { | 685 | { |
742 | if (arg < 0 || arg > 2) | 686 | if (arg < 0 || arg > 2) |
743 | return -EINVAL; | 687 | return -EINVAL; |
@@ -747,52 +691,54 @@ static int set_lba_addressing(ide_drive_t *drive, int arg) | |||
747 | if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) | 691 | if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) |
748 | return 0; | 692 | return 0; |
749 | 693 | ||
750 | if (!idedisk_supports_lba48(drive->id)) | 694 | if (ata_id_lba48_enabled(drive->id) == 0) |
751 | return -EIO; | 695 | return -EIO; |
696 | |||
752 | drive->addressing = arg; | 697 | drive->addressing = arg; |
698 | |||
753 | return 0; | 699 | return 0; |
754 | } | 700 | } |
755 | 701 | ||
702 | ide_devset_rw(acoustic, acoustic); | ||
703 | ide_devset_rw(address, addressing); | ||
704 | ide_devset_rw(multcount, multcount); | ||
705 | ide_devset_rw(wcache, wcache); | ||
706 | |||
707 | ide_devset_rw_sync(nowerr, nowerr); | ||
708 | |||
756 | #ifdef CONFIG_IDE_PROC_FS | 709 | #ifdef CONFIG_IDE_PROC_FS |
757 | static void idedisk_add_settings(ide_drive_t *drive) | 710 | ide_devset_rw_field(bios_cyl, bios_cyl); |
758 | { | 711 | ide_devset_rw_field(bios_head, bios_head); |
759 | struct hd_driveid *id = drive->id; | 712 | ide_devset_rw_field(bios_sect, bios_sect); |
760 | 713 | ide_devset_rw_field(failures, failures); | |
761 | ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, | 714 | ide_devset_rw_field(lun, lun); |
762 | &drive->bios_cyl, NULL); | 715 | ide_devset_rw_field(max_failures, max_failures); |
763 | ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, | 716 | |
764 | &drive->bios_head, NULL); | 717 | static const struct ide_proc_devset idedisk_settings[] = { |
765 | ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, | 718 | IDE_PROC_DEVSET(acoustic, 0, 254), |
766 | &drive->bios_sect, NULL); | 719 | IDE_PROC_DEVSET(address, 0, 2), |
767 | ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, | 720 | IDE_PROC_DEVSET(bios_cyl, 0, 65535), |
768 | &drive->addressing, set_lba_addressing); | 721 | IDE_PROC_DEVSET(bios_head, 0, 255), |
769 | ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, | 722 | IDE_PROC_DEVSET(bios_sect, 0, 63), |
770 | id->max_multsect, 1, 1, &drive->mult_count, | 723 | IDE_PROC_DEVSET(failures, 0, 65535), |
771 | set_multcount); | 724 | IDE_PROC_DEVSET(lun, 0, 7), |
772 | ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, | 725 | IDE_PROC_DEVSET(max_failures, 0, 65535), |
773 | &drive->nowerr, set_nowerr); | 726 | IDE_PROC_DEVSET(multcount, 0, 16), |
774 | ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, | 727 | IDE_PROC_DEVSET(nowerr, 0, 1), |
775 | &drive->lun, NULL); | 728 | IDE_PROC_DEVSET(wcache, 0, 1), |
776 | ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, | 729 | { 0 }, |
777 | &drive->wcache, write_cache); | 730 | }; |
778 | ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1, | ||
779 | &drive->acoustic, set_acoustic); | ||
780 | ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, | ||
781 | &drive->failures, NULL); | ||
782 | ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, | ||
783 | 1, 1, &drive->max_failures, NULL); | ||
784 | } | ||
785 | #else | ||
786 | static inline void idedisk_add_settings(ide_drive_t *drive) { ; } | ||
787 | #endif | 731 | #endif |
788 | 732 | ||
789 | static void idedisk_setup(ide_drive_t *drive) | 733 | static void idedisk_setup(ide_drive_t *drive) |
790 | { | 734 | { |
735 | struct ide_disk_obj *idkp = drive->driver_data; | ||
791 | ide_hwif_t *hwif = drive->hwif; | 736 | ide_hwif_t *hwif = drive->hwif; |
792 | struct hd_driveid *id = drive->id; | 737 | u16 *id = drive->id; |
738 | char *m = (char *)&id[ATA_ID_PROD]; | ||
793 | unsigned long long capacity; | 739 | unsigned long long capacity; |
794 | 740 | ||
795 | idedisk_add_settings(drive); | 741 | ide_proc_register_driver(drive, idkp->driver); |
796 | 742 | ||
797 | if (drive->id_read == 0) | 743 | if (drive->id_read == 0) |
798 | return; | 744 | return; |
@@ -801,11 +747,11 @@ static void idedisk_setup(ide_drive_t *drive) | |||
801 | /* | 747 | /* |
802 | * Removable disks (eg. SYQUEST); ignore 'WD' drives | 748 | * Removable disks (eg. SYQUEST); ignore 'WD' drives |
803 | */ | 749 | */ |
804 | if (id->model[0] != 'W' || id->model[1] != 'D') | 750 | if (m[0] != 'W' || m[1] != 'D') |
805 | drive->doorlocking = 1; | 751 | drive->doorlocking = 1; |
806 | } | 752 | } |
807 | 753 | ||
808 | (void)set_lba_addressing(drive, 1); | 754 | (void)set_addressing(drive, 1); |
809 | 755 | ||
810 | if (drive->addressing == 1) { | 756 | if (drive->addressing == 1) { |
811 | int max_s = 2048; | 757 | int max_s = 2048; |
@@ -847,8 +793,7 @@ static void idedisk_setup(ide_drive_t *drive) | |||
847 | capacity = idedisk_capacity(drive); | 793 | capacity = idedisk_capacity(drive); |
848 | 794 | ||
849 | if (!drive->forced_geom) { | 795 | if (!drive->forced_geom) { |
850 | 796 | if (ata_id_lba48_enabled(drive->id)) { | |
851 | if (idedisk_supports_lba48(drive->id)) { | ||
852 | /* compatibility */ | 797 | /* compatibility */ |
853 | drive->bios_sect = 63; | 798 | drive->bios_sect = 63; |
854 | drive->bios_head = 255; | 799 | drive->bios_head = 255; |
@@ -874,22 +819,22 @@ static void idedisk_setup(ide_drive_t *drive) | |||
874 | drive->name, capacity, sectors_to_MB(capacity)); | 819 | drive->name, capacity, sectors_to_MB(capacity)); |
875 | 820 | ||
876 | /* Only print cache size when it was specified */ | 821 | /* Only print cache size when it was specified */ |
877 | if (id->buf_size) | 822 | if (id[ATA_ID_BUF_SIZE]) |
878 | printk(KERN_CONT " w/%dKiB Cache", id->buf_size / 2); | 823 | printk(KERN_CONT " w/%dKiB Cache", id[ATA_ID_BUF_SIZE] / 2); |
879 | 824 | ||
880 | printk(KERN_CONT ", CHS=%d/%d/%d\n", | 825 | printk(KERN_CONT ", CHS=%d/%d/%d\n", |
881 | drive->bios_cyl, drive->bios_head, drive->bios_sect); | 826 | drive->bios_cyl, drive->bios_head, drive->bios_sect); |
882 | 827 | ||
883 | /* write cache enabled? */ | 828 | /* write cache enabled? */ |
884 | if ((id->csfo & 1) || (id->cfs_enable_1 & (1 << 5))) | 829 | if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id)) |
885 | drive->wcache = 1; | 830 | drive->wcache = 1; |
886 | 831 | ||
887 | write_cache(drive, 1); | 832 | set_wcache(drive, 1); |
888 | } | 833 | } |
889 | 834 | ||
890 | static void ide_cacheflush_p(ide_drive_t *drive) | 835 | static void ide_cacheflush_p(ide_drive_t *drive) |
891 | { | 836 | { |
892 | if (!drive->wcache || !ide_id_has_flush_cache(drive->id)) | 837 | if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) |
893 | return; | 838 | return; |
894 | 839 | ||
895 | if (do_idedisk_flushcache(drive)) | 840 | if (do_idedisk_flushcache(drive)) |
@@ -931,7 +876,7 @@ static int ide_disk_probe(ide_drive_t *drive); | |||
931 | */ | 876 | */ |
932 | static void ide_disk_resume(ide_drive_t *drive) | 877 | static void ide_disk_resume(ide_drive_t *drive) |
933 | { | 878 | { |
934 | if (idedisk_supports_hpa(drive->id)) | 879 | if (ata_id_hpa_enabled(drive->id)) |
935 | init_idedisk_capacity(drive); | 880 | init_idedisk_capacity(drive); |
936 | } | 881 | } |
937 | 882 | ||
@@ -974,12 +919,12 @@ static ide_driver_t idedisk_driver = { | |||
974 | .shutdown = ide_device_shutdown, | 919 | .shutdown = ide_device_shutdown, |
975 | .version = IDEDISK_VERSION, | 920 | .version = IDEDISK_VERSION, |
976 | .media = ide_disk, | 921 | .media = ide_disk, |
977 | .supports_dsc_overlap = 0, | ||
978 | .do_request = ide_do_rw_disk, | 922 | .do_request = ide_do_rw_disk, |
979 | .end_request = ide_end_request, | 923 | .end_request = ide_end_request, |
980 | .error = __ide_error, | 924 | .error = __ide_error, |
981 | #ifdef CONFIG_IDE_PROC_FS | 925 | #ifdef CONFIG_IDE_PROC_FS |
982 | .proc = idedisk_proc, | 926 | .proc = idedisk_proc, |
927 | .settings = idedisk_settings, | ||
983 | #endif | 928 | #endif |
984 | }; | 929 | }; |
985 | 930 | ||
@@ -988,7 +933,7 @@ static int idedisk_set_doorlock(ide_drive_t *drive, int on) | |||
988 | ide_task_t task; | 933 | ide_task_t task; |
989 | 934 | ||
990 | memset(&task, 0, sizeof(task)); | 935 | memset(&task, 0, sizeof(task)); |
991 | task.tf.command = on ? WIN_DOORLOCK : WIN_DOORUNLOCK; | 936 | task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; |
992 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 937 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
993 | 938 | ||
994 | return ide_no_data_taskfile(drive, &task); | 939 | return ide_no_data_taskfile(drive, &task); |
@@ -1053,52 +998,28 @@ static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
1053 | return 0; | 998 | return 0; |
1054 | } | 999 | } |
1055 | 1000 | ||
1001 | static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { | ||
1002 | { HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address }, | ||
1003 | { HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount }, | ||
1004 | { HDIO_GET_NOWERR, HDIO_SET_NOWERR, &ide_devset_nowerr }, | ||
1005 | { HDIO_GET_WCACHE, HDIO_SET_WCACHE, &ide_devset_wcache }, | ||
1006 | { HDIO_GET_ACOUSTIC, HDIO_SET_ACOUSTIC, &ide_devset_acoustic }, | ||
1007 | { 0 } | ||
1008 | }; | ||
1009 | |||
1056 | static int idedisk_ioctl(struct inode *inode, struct file *file, | 1010 | static int idedisk_ioctl(struct inode *inode, struct file *file, |
1057 | unsigned int cmd, unsigned long arg) | 1011 | unsigned int cmd, unsigned long arg) |
1058 | { | 1012 | { |
1059 | unsigned long flags; | ||
1060 | struct block_device *bdev = inode->i_bdev; | 1013 | struct block_device *bdev = inode->i_bdev; |
1061 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); | 1014 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); |
1062 | ide_drive_t *drive = idkp->drive; | 1015 | ide_drive_t *drive = idkp->drive; |
1063 | int err, (*setfunc)(ide_drive_t *, int); | 1016 | int err; |
1064 | u8 *val; | ||
1065 | |||
1066 | switch (cmd) { | ||
1067 | case HDIO_GET_ADDRESS: val = &drive->addressing; goto read_val; | ||
1068 | case HDIO_GET_MULTCOUNT: val = &drive->mult_count; goto read_val; | ||
1069 | case HDIO_GET_NOWERR: val = &drive->nowerr; goto read_val; | ||
1070 | case HDIO_GET_WCACHE: val = &drive->wcache; goto read_val; | ||
1071 | case HDIO_GET_ACOUSTIC: val = &drive->acoustic; goto read_val; | ||
1072 | case HDIO_SET_ADDRESS: setfunc = set_lba_addressing; goto set_val; | ||
1073 | case HDIO_SET_MULTCOUNT: setfunc = set_multcount; goto set_val; | ||
1074 | case HDIO_SET_NOWERR: setfunc = set_nowerr; goto set_val; | ||
1075 | case HDIO_SET_WCACHE: setfunc = write_cache; goto set_val; | ||
1076 | case HDIO_SET_ACOUSTIC: setfunc = set_acoustic; goto set_val; | ||
1077 | } | ||
1078 | 1017 | ||
1079 | return generic_ide_ioctl(drive, file, bdev, cmd, arg); | 1018 | err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); |
1019 | if (err != -EOPNOTSUPP) | ||
1020 | return err; | ||
1080 | 1021 | ||
1081 | read_val: | 1022 | return generic_ide_ioctl(drive, file, bdev, cmd, arg); |
1082 | mutex_lock(&ide_setting_mtx); | ||
1083 | spin_lock_irqsave(&ide_lock, flags); | ||
1084 | err = *val; | ||
1085 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1086 | mutex_unlock(&ide_setting_mtx); | ||
1087 | return err >= 0 ? put_user(err, (long __user *)arg) : err; | ||
1088 | |||
1089 | set_val: | ||
1090 | if (bdev != bdev->bd_contains) | ||
1091 | err = -EINVAL; | ||
1092 | else { | ||
1093 | if (!capable(CAP_SYS_ADMIN)) | ||
1094 | err = -EACCES; | ||
1095 | else { | ||
1096 | mutex_lock(&ide_setting_mtx); | ||
1097 | err = setfunc(drive, arg); | ||
1098 | mutex_unlock(&ide_setting_mtx); | ||
1099 | } | ||
1100 | } | ||
1101 | return err; | ||
1102 | } | 1023 | } |
1103 | 1024 | ||
1104 | static int idedisk_media_changed(struct gendisk *disk) | 1025 | static int idedisk_media_changed(struct gendisk *disk) |
@@ -1142,8 +1063,7 @@ static int ide_disk_probe(ide_drive_t *drive) | |||
1142 | /* strstr("foo", "") is non-NULL */ | 1063 | /* strstr("foo", "") is non-NULL */ |
1143 | if (!strstr("ide-disk", drive->driver_req)) | 1064 | if (!strstr("ide-disk", drive->driver_req)) |
1144 | goto failed; | 1065 | goto failed; |
1145 | if (!drive->present) | 1066 | |
1146 | goto failed; | ||
1147 | if (drive->media != ide_disk) | 1067 | if (drive->media != ide_disk) |
1148 | goto failed; | 1068 | goto failed; |
1149 | 1069 | ||
@@ -1151,15 +1071,12 @@ static int ide_disk_probe(ide_drive_t *drive) | |||
1151 | if (!idkp) | 1071 | if (!idkp) |
1152 | goto failed; | 1072 | goto failed; |
1153 | 1073 | ||
1154 | g = alloc_disk_node(1 << PARTN_BITS, | 1074 | g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); |
1155 | hwif_to_node(drive->hwif)); | ||
1156 | if (!g) | 1075 | if (!g) |
1157 | goto out_free_idkp; | 1076 | goto out_free_idkp; |
1158 | 1077 | ||
1159 | ide_init_disk(g, drive); | 1078 | ide_init_disk(g, drive); |
1160 | 1079 | ||
1161 | ide_proc_register_driver(drive, &idedisk_driver); | ||
1162 | |||
1163 | kref_init(&idkp->kref); | 1080 | kref_init(&idkp->kref); |
1164 | 1081 | ||
1165 | idkp->drive = drive; | 1082 | idkp->drive = drive; |
@@ -1178,9 +1095,11 @@ static int ide_disk_probe(ide_drive_t *drive) | |||
1178 | } else | 1095 | } else |
1179 | drive->attach = 1; | 1096 | drive->attach = 1; |
1180 | 1097 | ||
1181 | g->minors = 1 << PARTN_BITS; | 1098 | g->minors = IDE_DISK_MINORS; |
1182 | g->driverfs_dev = &drive->gendev; | 1099 | g->driverfs_dev = &drive->gendev; |
1183 | g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; | 1100 | g->flags |= GENHD_FL_EXT_DEVT; |
1101 | if (drive->removable) | ||
1102 | g->flags |= GENHD_FL_REMOVABLE; | ||
1184 | set_capacity(g, idedisk_capacity(drive)); | 1103 | set_capacity(g, idedisk_capacity(drive)); |
1185 | g->fops = &idedisk_ops; | 1104 | g->fops = &idedisk_ops; |
1186 | add_disk(g); | 1105 | add_disk(g); |