diff options
Diffstat (limited to 'drivers/ide/ide-disk.c')
-rw-r--r-- | drivers/ide/ide-disk.c | 380 |
1 files changed, 143 insertions, 237 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 28d85b410f7c..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; |
@@ -65,11 +69,10 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | |||
65 | mutex_lock(&idedisk_ref_mutex); | 69 | mutex_lock(&idedisk_ref_mutex); |
66 | idkp = ide_disk_g(disk); | 70 | idkp = ide_disk_g(disk); |
67 | if (idkp) { | 71 | if (idkp) { |
68 | kref_get(&idkp->kref); | 72 | if (ide_device_get(idkp->drive)) |
69 | if (ide_device_get(idkp->drive)) { | ||
70 | kref_put(&idkp->kref, ide_disk_release); | ||
71 | idkp = NULL; | 73 | idkp = NULL; |
72 | } | 74 | else |
75 | kref_get(&idkp->kref); | ||
73 | } | 76 | } |
74 | mutex_unlock(&idedisk_ref_mutex); | 77 | mutex_unlock(&idedisk_ref_mutex); |
75 | return idkp; | 78 | return idkp; |
@@ -77,74 +80,27 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | |||
77 | 80 | ||
78 | static void ide_disk_put(struct ide_disk_obj *idkp) | 81 | static void ide_disk_put(struct ide_disk_obj *idkp) |
79 | { | 82 | { |
83 | ide_drive_t *drive = idkp->drive; | ||
84 | |||
80 | mutex_lock(&idedisk_ref_mutex); | 85 | mutex_lock(&idedisk_ref_mutex); |
81 | ide_device_put(idkp->drive); | ||
82 | kref_put(&idkp->kref, ide_disk_release); | 86 | kref_put(&idkp->kref, ide_disk_release); |
87 | ide_device_put(drive); | ||
83 | mutex_unlock(&idedisk_ref_mutex); | 88 | mutex_unlock(&idedisk_ref_mutex); |
84 | } | 89 | } |
85 | 90 | ||
86 | /* | ||
87 | * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity" | ||
88 | * value for this drive (from its reported identification information). | ||
89 | * | ||
90 | * Returns: 1 if lba_capacity looks sensible | ||
91 | * 0 otherwise | ||
92 | * | ||
93 | * It is called only once for each drive. | ||
94 | */ | ||
95 | static int lba_capacity_is_ok(struct hd_driveid *id) | ||
96 | { | ||
97 | unsigned long lba_sects, chs_sects, head, tail; | ||
98 | |||
99 | /* No non-LBA info .. so valid! */ | ||
100 | if (id->cyls == 0) | ||
101 | return 1; | ||
102 | |||
103 | /* | ||
104 | * The ATA spec tells large drives to return | ||
105 | * C/H/S = 16383/16/63 independent of their size. | ||
106 | * Some drives can be jumpered to use 15 heads instead of 16. | ||
107 | * Some drives can be jumpered to use 4092 cyls instead of 16383. | ||
108 | */ | ||
109 | if ((id->cyls == 16383 | ||
110 | || (id->cyls == 4092 && id->cur_cyls == 16383)) && | ||
111 | id->sectors == 63 && | ||
112 | (id->heads == 15 || id->heads == 16) && | ||
113 | (id->lba_capacity >= 16383*63*id->heads)) | ||
114 | return 1; | ||
115 | |||
116 | lba_sects = id->lba_capacity; | ||
117 | chs_sects = id->cyls * id->heads * id->sectors; | ||
118 | |||
119 | /* perform a rough sanity check on lba_sects: within 10% is OK */ | ||
120 | if ((lba_sects - chs_sects) < chs_sects/10) | ||
121 | return 1; | ||
122 | |||
123 | /* some drives have the word order reversed */ | ||
124 | head = ((lba_sects >> 16) & 0xffff); | ||
125 | tail = (lba_sects & 0xffff); | ||
126 | lba_sects = (head | (tail << 16)); | ||
127 | if ((lba_sects - chs_sects) < chs_sects/10) { | ||
128 | id->lba_capacity = lba_sects; | ||
129 | return 1; /* lba_capacity is (now) good */ | ||
130 | } | ||
131 | |||
132 | return 0; /* lba_capacity value may be bad */ | ||
133 | } | ||
134 | |||
135 | static const u8 ide_rw_cmds[] = { | 91 | static const u8 ide_rw_cmds[] = { |
136 | WIN_MULTREAD, | 92 | ATA_CMD_READ_MULTI, |
137 | WIN_MULTWRITE, | 93 | ATA_CMD_WRITE_MULTI, |
138 | WIN_MULTREAD_EXT, | 94 | ATA_CMD_READ_MULTI_EXT, |
139 | WIN_MULTWRITE_EXT, | 95 | ATA_CMD_WRITE_MULTI_EXT, |
140 | WIN_READ, | 96 | ATA_CMD_PIO_READ, |
141 | WIN_WRITE, | 97 | ATA_CMD_PIO_WRITE, |
142 | WIN_READ_EXT, | 98 | ATA_CMD_PIO_READ_EXT, |
143 | WIN_WRITE_EXT, | 99 | ATA_CMD_PIO_WRITE_EXT, |
144 | WIN_READDMA, | 100 | ATA_CMD_READ, |
145 | WIN_WRITEDMA, | 101 | ATA_CMD_WRITE, |
146 | WIN_READDMA_EXT, | 102 | ATA_CMD_READ_EXT, |
147 | WIN_WRITEDMA_EXT, | 103 | ATA_CMD_WRITE_EXT, |
148 | }; | 104 | }; |
149 | 105 | ||
150 | static const u8 ide_data_phases[] = { | 106 | static const u8 ide_data_phases[] = { |
@@ -315,9 +271,9 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) | |||
315 | /* Create IDE/ATA command request structure */ | 271 | /* Create IDE/ATA command request structure */ |
316 | memset(&args, 0, sizeof(ide_task_t)); | 272 | memset(&args, 0, sizeof(ide_task_t)); |
317 | if (lba48) | 273 | if (lba48) |
318 | tf->command = WIN_READ_NATIVE_MAX_EXT; | 274 | tf->command = ATA_CMD_READ_NATIVE_MAX_EXT; |
319 | else | 275 | else |
320 | tf->command = WIN_READ_NATIVE_MAX; | 276 | tf->command = ATA_CMD_READ_NATIVE_MAX; |
321 | tf->device = ATA_LBA; | 277 | tf->device = ATA_LBA; |
322 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 278 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
323 | if (lba48) | 279 | if (lba48) |
@@ -352,10 +308,10 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) | |||
352 | tf->hob_lbal = (addr_req >>= 8) & 0xff; | 308 | tf->hob_lbal = (addr_req >>= 8) & 0xff; |
353 | tf->hob_lbam = (addr_req >>= 8) & 0xff; | 309 | tf->hob_lbam = (addr_req >>= 8) & 0xff; |
354 | tf->hob_lbah = (addr_req >>= 8) & 0xff; | 310 | tf->hob_lbah = (addr_req >>= 8) & 0xff; |
355 | tf->command = WIN_SET_MAX_EXT; | 311 | tf->command = ATA_CMD_SET_MAX_EXT; |
356 | } else { | 312 | } else { |
357 | tf->device = (addr_req >>= 8) & 0x0f; | 313 | tf->device = (addr_req >>= 8) & 0x0f; |
358 | tf->command = WIN_SET_MAX; | 314 | tf->command = ATA_CMD_SET_MAX; |
359 | } | 315 | } |
360 | tf->device |= ATA_LBA; | 316 | tf->device |= ATA_LBA; |
361 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 317 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
@@ -378,25 +334,6 @@ static unsigned long long sectors_to_MB(unsigned long long n) | |||
378 | } | 334 | } |
379 | 335 | ||
380 | /* | 336 | /* |
381 | * Bits 10 of command_set_1 and cfs_enable_1 must be equal, | ||
382 | * so on non-buggy drives we need test only one. | ||
383 | * However, we should also check whether these fields are valid. | ||
384 | */ | ||
385 | static inline int idedisk_supports_hpa(const struct hd_driveid *id) | ||
386 | { | ||
387 | return (id->command_set_1 & 0x0400) && (id->cfs_enable_1 & 0x0400); | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * The same here. | ||
392 | */ | ||
393 | static inline int idedisk_supports_lba48(const struct hd_driveid *id) | ||
394 | { | ||
395 | return (id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) | ||
396 | && id->lba_capacity_2; | ||
397 | } | ||
398 | |||
399 | /* | ||
400 | * Some disks report total number of sectors instead of | 337 | * Some disks report total number of sectors instead of |
401 | * maximum sector address. We list them here. | 338 | * maximum sector address. We list them here. |
402 | */ | 339 | */ |
@@ -410,7 +347,7 @@ static const struct drive_list_entry hpa_list[] = { | |||
410 | static void idedisk_check_hpa(ide_drive_t *drive) | 347 | static void idedisk_check_hpa(ide_drive_t *drive) |
411 | { | 348 | { |
412 | unsigned long long capacity, set_max; | 349 | unsigned long long capacity, set_max; |
413 | int lba48 = idedisk_supports_lba48(drive->id); | 350 | int lba48 = ata_id_lba48_enabled(drive->id); |
414 | 351 | ||
415 | capacity = drive->capacity64; | 352 | capacity = drive->capacity64; |
416 | 353 | ||
@@ -444,39 +381,25 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
444 | } | 381 | } |
445 | } | 382 | } |
446 | 383 | ||
447 | /* | ||
448 | * Compute drive->capacity, the full capacity of the drive | ||
449 | * Called with drive->id != NULL. | ||
450 | * | ||
451 | * To compute capacity, this uses either of | ||
452 | * | ||
453 | * 1. CHS value set by user (whatever user sets will be trusted) | ||
454 | * 2. LBA value from target drive (require new ATA feature) | ||
455 | * 3. LBA value from system BIOS (new one is OK, old one may break) | ||
456 | * 4. CHS value from system BIOS (traditional style) | ||
457 | * | ||
458 | * in above order (i.e., if value of higher priority is available, | ||
459 | * reset will be ignored). | ||
460 | */ | ||
461 | static void init_idedisk_capacity(ide_drive_t *drive) | 384 | static void init_idedisk_capacity(ide_drive_t *drive) |
462 | { | 385 | { |
463 | struct hd_driveid *id = drive->id; | 386 | u16 *id = drive->id; |
464 | /* | 387 | /* |
465 | * If this drive supports the Host Protected Area feature set, | 388 | * If this drive supports the Host Protected Area feature set, |
466 | * 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. |
467 | */ | 390 | */ |
468 | int hpa = idedisk_supports_hpa(id); | 391 | int hpa = ata_id_hpa_enabled(id); |
469 | 392 | ||
470 | if (idedisk_supports_lba48(id)) { | 393 | if (ata_id_lba48_enabled(id)) { |
471 | /* drive speaks 48-bit LBA */ | 394 | /* drive speaks 48-bit LBA */ |
472 | drive->select.b.lba = 1; | 395 | drive->select.b.lba = 1; |
473 | drive->capacity64 = id->lba_capacity_2; | 396 | drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); |
474 | if (hpa) | 397 | if (hpa) |
475 | idedisk_check_hpa(drive); | 398 | idedisk_check_hpa(drive); |
476 | } 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)) { |
477 | /* drive speaks 28-bit LBA */ | 400 | /* drive speaks 28-bit LBA */ |
478 | drive->select.b.lba = 1; | 401 | drive->select.b.lba = 1; |
479 | drive->capacity64 = id->lba_capacity; | 402 | drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY); |
480 | if (hpa) | 403 | if (hpa) |
481 | idedisk_check_hpa(drive); | 404 | idedisk_check_hpa(drive); |
482 | } else { | 405 | } else { |
@@ -487,7 +410,7 @@ static void init_idedisk_capacity(ide_drive_t *drive) | |||
487 | 410 | ||
488 | static sector_t idedisk_capacity(ide_drive_t *drive) | 411 | static sector_t idedisk_capacity(ide_drive_t *drive) |
489 | { | 412 | { |
490 | return drive->capacity64 - drive->sect0; | 413 | return drive->capacity64; |
491 | } | 414 | } |
492 | 415 | ||
493 | #ifdef CONFIG_IDE_PROC_FS | 416 | #ifdef CONFIG_IDE_PROC_FS |
@@ -497,10 +420,10 @@ static int smart_enable(ide_drive_t *drive) | |||
497 | struct ide_taskfile *tf = &args.tf; | 420 | struct ide_taskfile *tf = &args.tf; |
498 | 421 | ||
499 | memset(&args, 0, sizeof(ide_task_t)); | 422 | memset(&args, 0, sizeof(ide_task_t)); |
500 | tf->feature = SMART_ENABLE; | 423 | tf->feature = ATA_SMART_ENABLE; |
501 | tf->lbam = SMART_LCYL_PASS; | 424 | tf->lbam = ATA_SMART_LBAM_PASS; |
502 | tf->lbah = SMART_HCYL_PASS; | 425 | tf->lbah = ATA_SMART_LBAH_PASS; |
503 | tf->command = WIN_SMART; | 426 | tf->command = ATA_CMD_SMART; |
504 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 427 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
505 | return ide_no_data_taskfile(drive, &args); | 428 | return ide_no_data_taskfile(drive, &args); |
506 | } | 429 | } |
@@ -513,9 +436,9 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) | |||
513 | memset(&args, 0, sizeof(ide_task_t)); | 436 | memset(&args, 0, sizeof(ide_task_t)); |
514 | tf->feature = sub_cmd; | 437 | tf->feature = sub_cmd; |
515 | tf->nsect = 0x01; | 438 | tf->nsect = 0x01; |
516 | tf->lbam = SMART_LCYL_PASS; | 439 | tf->lbam = ATA_SMART_LBAM_PASS; |
517 | tf->lbah = SMART_HCYL_PASS; | 440 | tf->lbah = ATA_SMART_LBAH_PASS; |
518 | tf->command = WIN_SMART; | 441 | tf->command = ATA_CMD_SMART; |
519 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 442 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
520 | args.data_phase = TASKFILE_IN; | 443 | args.data_phase = TASKFILE_IN; |
521 | (void) smart_enable(drive); | 444 | (void) smart_enable(drive); |
@@ -530,7 +453,7 @@ static int proc_idedisk_read_cache | |||
530 | int len; | 453 | int len; |
531 | 454 | ||
532 | if (drive->id_read) | 455 | if (drive->id_read) |
533 | len = sprintf(out, "%i\n", drive->id->buf_size / 2); | 456 | len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2); |
534 | else | 457 | else |
535 | len = sprintf(out, "(none)\n"); | 458 | len = sprintf(out, "(none)\n"); |
536 | 459 | ||
@@ -556,13 +479,14 @@ static int proc_idedisk_read_smart(char *page, char **start, off_t off, | |||
556 | 479 | ||
557 | if (get_smart_data(drive, page, sub_cmd) == 0) { | 480 | if (get_smart_data(drive, page, sub_cmd) == 0) { |
558 | unsigned short *val = (unsigned short *) page; | 481 | unsigned short *val = (unsigned short *) page; |
559 | char *out = ((char *)val) + (SECTOR_WORDS * 4); | 482 | char *out = (char *)val + SECTOR_SIZE; |
483 | |||
560 | page = out; | 484 | page = out; |
561 | do { | 485 | do { |
562 | out += sprintf(out, "%04x%c", le16_to_cpu(*val), | 486 | out += sprintf(out, "%04x%c", le16_to_cpu(*val), |
563 | (++i & 7) ? ' ' : '\n'); | 487 | (++i & 7) ? ' ' : '\n'); |
564 | val += 1; | 488 | val += 1; |
565 | } while (i < (SECTOR_WORDS * 2)); | 489 | } while (i < SECTOR_SIZE / 2); |
566 | len = out - page; | 490 | len = out - page; |
567 | } | 491 | } |
568 | 492 | ||
@@ -573,14 +497,14 @@ static int proc_idedisk_read_sv | |||
573 | (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) |
574 | { | 498 | { |
575 | return proc_idedisk_read_smart(page, start, off, count, eof, data, | 499 | return proc_idedisk_read_smart(page, start, off, count, eof, data, |
576 | SMART_READ_VALUES); | 500 | ATA_SMART_READ_VALUES); |
577 | } | 501 | } |
578 | 502 | ||
579 | static int proc_idedisk_read_st | 503 | static int proc_idedisk_read_st |
580 | (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) |
581 | { | 505 | { |
582 | return proc_idedisk_read_smart(page, start, off, count, eof, data, | 506 | return proc_idedisk_read_smart(page, start, off, count, eof, data, |
583 | SMART_READ_THRESHOLDS); | 507 | ATA_SMART_READ_THRESHOLDS); |
584 | } | 508 | } |
585 | 509 | ||
586 | static ide_proc_entry_t idedisk_proc[] = { | 510 | static ide_proc_entry_t idedisk_proc[] = { |
@@ -602,11 +526,11 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | |||
602 | BUG_ON(task == NULL); | 526 | BUG_ON(task == NULL); |
603 | 527 | ||
604 | memset(task, 0, sizeof(*task)); | 528 | memset(task, 0, sizeof(*task)); |
605 | if (ide_id_has_flush_cache_ext(drive->id) && | 529 | if (ata_id_flush_ext_enabled(drive->id) && |
606 | (drive->capacity64 >= (1UL << 28))) | 530 | (drive->capacity64 >= (1UL << 28))) |
607 | task->tf.command = WIN_FLUSH_CACHE_EXT; | 531 | task->tf.command = ATA_CMD_FLUSH_EXT; |
608 | else | 532 | else |
609 | task->tf.command = WIN_FLUSH_CACHE; | 533 | task->tf.command = ATA_CMD_FLUSH; |
610 | task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | | 534 | task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | |
611 | IDE_TFLAG_DYN; | 535 | IDE_TFLAG_DYN; |
612 | task->data_phase = TASKFILE_NO_DATA; | 536 | task->data_phase = TASKFILE_NO_DATA; |
@@ -616,6 +540,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | |||
616 | rq->special = task; | 540 | rq->special = task; |
617 | } | 541 | } |
618 | 542 | ||
543 | ide_devset_get(multcount, mult_count); | ||
544 | |||
619 | /* | 545 | /* |
620 | * 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. |
621 | * 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. |
@@ -625,7 +551,7 @@ static int set_multcount(ide_drive_t *drive, int arg) | |||
625 | struct request *rq; | 551 | struct request *rq; |
626 | int error; | 552 | int error; |
627 | 553 | ||
628 | if (arg < 0 || arg > drive->id->max_multsect) | 554 | if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff)) |
629 | return -EINVAL; | 555 | return -EINVAL; |
630 | 556 | ||
631 | if (drive->special.b.set_multmode) | 557 | if (drive->special.b.set_multmode) |
@@ -642,22 +568,21 @@ static int set_multcount(ide_drive_t *drive, int arg) | |||
642 | return (drive->mult_count == arg) ? 0 : -EIO; | 568 | return (drive->mult_count == arg) ? 0 : -EIO; |
643 | } | 569 | } |
644 | 570 | ||
571 | ide_devset_get(nowerr, nowerr); | ||
572 | |||
645 | static int set_nowerr(ide_drive_t *drive, int arg) | 573 | static int set_nowerr(ide_drive_t *drive, int arg) |
646 | { | 574 | { |
647 | if (arg < 0 || arg > 1) | 575 | if (arg < 0 || arg > 1) |
648 | return -EINVAL; | 576 | return -EINVAL; |
649 | 577 | ||
650 | if (ide_spin_wait_hwgroup(drive)) | ||
651 | return -EBUSY; | ||
652 | drive->nowerr = arg; | 578 | drive->nowerr = arg; |
653 | drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; | 579 | drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; |
654 | spin_unlock_irq(&ide_lock); | ||
655 | return 0; | 580 | return 0; |
656 | } | 581 | } |
657 | 582 | ||
658 | static void update_ordered(ide_drive_t *drive) | 583 | static void update_ordered(ide_drive_t *drive) |
659 | { | 584 | { |
660 | struct hd_driveid *id = drive->id; | 585 | u16 *id = drive->id; |
661 | unsigned ordered = QUEUE_ORDERED_NONE; | 586 | unsigned ordered = QUEUE_ORDERED_NONE; |
662 | prepare_flush_fn *prep_fn = NULL; | 587 | prepare_flush_fn *prep_fn = NULL; |
663 | 588 | ||
@@ -673,9 +598,9 @@ static void update_ordered(ide_drive_t *drive) | |||
673 | * not available so we don't need to recheck that. | 598 | * not available so we don't need to recheck that. |
674 | */ | 599 | */ |
675 | capacity = idedisk_capacity(drive); | 600 | capacity = idedisk_capacity(drive); |
676 | barrier = ide_id_has_flush_cache(id) && !drive->noflush && | 601 | barrier = ata_id_flush_enabled(id) && !drive->noflush && |
677 | (drive->addressing == 0 || capacity <= (1ULL << 28) || | 602 | (drive->addressing == 0 || capacity <= (1ULL << 28) || |
678 | ide_id_has_flush_cache_ext(id)); | 603 | ata_id_flush_ext_enabled(id)); |
679 | 604 | ||
680 | printk(KERN_INFO "%s: cache flushes %ssupported\n", | 605 | printk(KERN_INFO "%s: cache flushes %ssupported\n", |
681 | drive->name, barrier ? "" : "not "); | 606 | drive->name, barrier ? "" : "not "); |
@@ -690,7 +615,9 @@ static void update_ordered(ide_drive_t *drive) | |||
690 | blk_queue_ordered(drive->queue, ordered, prep_fn); | 615 | blk_queue_ordered(drive->queue, ordered, prep_fn); |
691 | } | 616 | } |
692 | 617 | ||
693 | 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) | ||
694 | { | 621 | { |
695 | ide_task_t args; | 622 | ide_task_t args; |
696 | int err = 1; | 623 | int err = 1; |
@@ -698,11 +625,11 @@ static int write_cache(ide_drive_t *drive, int arg) | |||
698 | if (arg < 0 || arg > 1) | 625 | if (arg < 0 || arg > 1) |
699 | return -EINVAL; | 626 | return -EINVAL; |
700 | 627 | ||
701 | if (ide_id_has_flush_cache(drive->id)) { | 628 | if (ata_id_flush_enabled(drive->id)) { |
702 | memset(&args, 0, sizeof(ide_task_t)); | 629 | memset(&args, 0, sizeof(ide_task_t)); |
703 | args.tf.feature = arg ? | 630 | args.tf.feature = arg ? |
704 | SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; | 631 | SETFEATURES_WC_ON : SETFEATURES_WC_OFF; |
705 | args.tf.command = WIN_SETFEATURES; | 632 | args.tf.command = ATA_CMD_SET_FEATURES; |
706 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 633 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
707 | err = ide_no_data_taskfile(drive, &args); | 634 | err = ide_no_data_taskfile(drive, &args); |
708 | if (err == 0) | 635 | if (err == 0) |
@@ -719,14 +646,16 @@ static int do_idedisk_flushcache(ide_drive_t *drive) | |||
719 | ide_task_t args; | 646 | ide_task_t args; |
720 | 647 | ||
721 | memset(&args, 0, sizeof(ide_task_t)); | 648 | memset(&args, 0, sizeof(ide_task_t)); |
722 | if (ide_id_has_flush_cache_ext(drive->id)) | 649 | if (ata_id_flush_ext_enabled(drive->id)) |
723 | args.tf.command = WIN_FLUSH_CACHE_EXT; | 650 | args.tf.command = ATA_CMD_FLUSH_EXT; |
724 | else | 651 | else |
725 | args.tf.command = WIN_FLUSH_CACHE; | 652 | args.tf.command = ATA_CMD_FLUSH; |
726 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 653 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
727 | return ide_no_data_taskfile(drive, &args); | 654 | return ide_no_data_taskfile(drive, &args); |
728 | } | 655 | } |
729 | 656 | ||
657 | ide_devset_get(acoustic, acoustic); | ||
658 | |||
730 | static int set_acoustic(ide_drive_t *drive, int arg) | 659 | static int set_acoustic(ide_drive_t *drive, int arg) |
731 | { | 660 | { |
732 | ide_task_t args; | 661 | ide_task_t args; |
@@ -735,22 +664,24 @@ static int set_acoustic(ide_drive_t *drive, int arg) | |||
735 | return -EINVAL; | 664 | return -EINVAL; |
736 | 665 | ||
737 | memset(&args, 0, sizeof(ide_task_t)); | 666 | memset(&args, 0, sizeof(ide_task_t)); |
738 | args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM; | 667 | args.tf.feature = arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF; |
739 | args.tf.nsect = arg; | 668 | args.tf.nsect = arg; |
740 | args.tf.command = WIN_SETFEATURES; | 669 | args.tf.command = ATA_CMD_SET_FEATURES; |
741 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 670 | args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
742 | ide_no_data_taskfile(drive, &args); | 671 | ide_no_data_taskfile(drive, &args); |
743 | drive->acoustic = arg; | 672 | drive->acoustic = arg; |
744 | return 0; | 673 | return 0; |
745 | } | 674 | } |
746 | 675 | ||
676 | ide_devset_get(addressing, addressing); | ||
677 | |||
747 | /* | 678 | /* |
748 | * drive->addressing: | 679 | * drive->addressing: |
749 | * 0: 28-bit | 680 | * 0: 28-bit |
750 | * 1: 48-bit | 681 | * 1: 48-bit |
751 | * 2: 48-bit capable doing 28-bit | 682 | * 2: 48-bit capable doing 28-bit |
752 | */ | 683 | */ |
753 | static int set_lba_addressing(ide_drive_t *drive, int arg) | 684 | static int set_addressing(ide_drive_t *drive, int arg) |
754 | { | 685 | { |
755 | if (arg < 0 || arg > 2) | 686 | if (arg < 0 || arg > 2) |
756 | return -EINVAL; | 687 | return -EINVAL; |
@@ -760,52 +691,54 @@ static int set_lba_addressing(ide_drive_t *drive, int arg) | |||
760 | if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) | 691 | if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) |
761 | return 0; | 692 | return 0; |
762 | 693 | ||
763 | if (!idedisk_supports_lba48(drive->id)) | 694 | if (ata_id_lba48_enabled(drive->id) == 0) |
764 | return -EIO; | 695 | return -EIO; |
696 | |||
765 | drive->addressing = arg; | 697 | drive->addressing = arg; |
698 | |||
766 | return 0; | 699 | return 0; |
767 | } | 700 | } |
768 | 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 | |||
769 | #ifdef CONFIG_IDE_PROC_FS | 709 | #ifdef CONFIG_IDE_PROC_FS |
770 | static void idedisk_add_settings(ide_drive_t *drive) | 710 | ide_devset_rw_field(bios_cyl, bios_cyl); |
771 | { | 711 | ide_devset_rw_field(bios_head, bios_head); |
772 | struct hd_driveid *id = drive->id; | 712 | ide_devset_rw_field(bios_sect, bios_sect); |
773 | 713 | ide_devset_rw_field(failures, failures); | |
774 | ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, | 714 | ide_devset_rw_field(lun, lun); |
775 | &drive->bios_cyl, NULL); | 715 | ide_devset_rw_field(max_failures, max_failures); |
776 | ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, | 716 | |
777 | &drive->bios_head, NULL); | 717 | static const struct ide_proc_devset idedisk_settings[] = { |
778 | ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, | 718 | IDE_PROC_DEVSET(acoustic, 0, 254), |
779 | &drive->bios_sect, NULL); | 719 | IDE_PROC_DEVSET(address, 0, 2), |
780 | ide_add_setting(drive, "address", SETTING_RW, TYPE_BYTE, 0, 2, 1, 1, | 720 | IDE_PROC_DEVSET(bios_cyl, 0, 65535), |
781 | &drive->addressing, set_lba_addressing); | 721 | IDE_PROC_DEVSET(bios_head, 0, 255), |
782 | ide_add_setting(drive, "multcount", SETTING_RW, TYPE_BYTE, 0, | 722 | IDE_PROC_DEVSET(bios_sect, 0, 63), |
783 | id->max_multsect, 1, 1, &drive->mult_count, | 723 | IDE_PROC_DEVSET(failures, 0, 65535), |
784 | set_multcount); | 724 | IDE_PROC_DEVSET(lun, 0, 7), |
785 | ide_add_setting(drive, "nowerr", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, | 725 | IDE_PROC_DEVSET(max_failures, 0, 65535), |
786 | &drive->nowerr, set_nowerr); | 726 | IDE_PROC_DEVSET(multcount, 0, 16), |
787 | ide_add_setting(drive, "lun", SETTING_RW, TYPE_INT, 0, 7, 1, 1, | 727 | IDE_PROC_DEVSET(nowerr, 0, 1), |
788 | &drive->lun, NULL); | 728 | IDE_PROC_DEVSET(wcache, 0, 1), |
789 | ide_add_setting(drive, "wcache", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, | 729 | { 0 }, |
790 | &drive->wcache, write_cache); | 730 | }; |
791 | ide_add_setting(drive, "acoustic", SETTING_RW, TYPE_BYTE, 0, 254, 1, 1, | ||
792 | &drive->acoustic, set_acoustic); | ||
793 | ide_add_setting(drive, "failures", SETTING_RW, TYPE_INT, 0, 65535, 1, 1, | ||
794 | &drive->failures, NULL); | ||
795 | ide_add_setting(drive, "max_failures", SETTING_RW, TYPE_INT, 0, 65535, | ||
796 | 1, 1, &drive->max_failures, NULL); | ||
797 | } | ||
798 | #else | ||
799 | static inline void idedisk_add_settings(ide_drive_t *drive) { ; } | ||
800 | #endif | 731 | #endif |
801 | 732 | ||
802 | static void idedisk_setup(ide_drive_t *drive) | 733 | static void idedisk_setup(ide_drive_t *drive) |
803 | { | 734 | { |
735 | struct ide_disk_obj *idkp = drive->driver_data; | ||
804 | ide_hwif_t *hwif = drive->hwif; | 736 | ide_hwif_t *hwif = drive->hwif; |
805 | struct hd_driveid *id = drive->id; | 737 | u16 *id = drive->id; |
738 | char *m = (char *)&id[ATA_ID_PROD]; | ||
806 | unsigned long long capacity; | 739 | unsigned long long capacity; |
807 | 740 | ||
808 | idedisk_add_settings(drive); | 741 | ide_proc_register_driver(drive, idkp->driver); |
809 | 742 | ||
810 | if (drive->id_read == 0) | 743 | if (drive->id_read == 0) |
811 | return; | 744 | return; |
@@ -814,11 +747,11 @@ static void idedisk_setup(ide_drive_t *drive) | |||
814 | /* | 747 | /* |
815 | * Removable disks (eg. SYQUEST); ignore 'WD' drives | 748 | * Removable disks (eg. SYQUEST); ignore 'WD' drives |
816 | */ | 749 | */ |
817 | if (id->model[0] != 'W' || id->model[1] != 'D') | 750 | if (m[0] != 'W' || m[1] != 'D') |
818 | drive->doorlocking = 1; | 751 | drive->doorlocking = 1; |
819 | } | 752 | } |
820 | 753 | ||
821 | (void)set_lba_addressing(drive, 1); | 754 | (void)set_addressing(drive, 1); |
822 | 755 | ||
823 | if (drive->addressing == 1) { | 756 | if (drive->addressing == 1) { |
824 | int max_s = 2048; | 757 | int max_s = 2048; |
@@ -860,8 +793,7 @@ static void idedisk_setup(ide_drive_t *drive) | |||
860 | capacity = idedisk_capacity(drive); | 793 | capacity = idedisk_capacity(drive); |
861 | 794 | ||
862 | if (!drive->forced_geom) { | 795 | if (!drive->forced_geom) { |
863 | 796 | if (ata_id_lba48_enabled(drive->id)) { | |
864 | if (idedisk_supports_lba48(drive->id)) { | ||
865 | /* compatibility */ | 797 | /* compatibility */ |
866 | drive->bios_sect = 63; | 798 | drive->bios_sect = 63; |
867 | drive->bios_head = 255; | 799 | drive->bios_head = 255; |
@@ -887,22 +819,22 @@ static void idedisk_setup(ide_drive_t *drive) | |||
887 | drive->name, capacity, sectors_to_MB(capacity)); | 819 | drive->name, capacity, sectors_to_MB(capacity)); |
888 | 820 | ||
889 | /* Only print cache size when it was specified */ | 821 | /* Only print cache size when it was specified */ |
890 | if (id->buf_size) | 822 | if (id[ATA_ID_BUF_SIZE]) |
891 | printk(KERN_CONT " w/%dKiB Cache", id->buf_size / 2); | 823 | printk(KERN_CONT " w/%dKiB Cache", id[ATA_ID_BUF_SIZE] / 2); |
892 | 824 | ||
893 | printk(KERN_CONT ", CHS=%d/%d/%d\n", | 825 | printk(KERN_CONT ", CHS=%d/%d/%d\n", |
894 | drive->bios_cyl, drive->bios_head, drive->bios_sect); | 826 | drive->bios_cyl, drive->bios_head, drive->bios_sect); |
895 | 827 | ||
896 | /* write cache enabled? */ | 828 | /* write cache enabled? */ |
897 | if ((id->csfo & 1) || (id->cfs_enable_1 & (1 << 5))) | 829 | if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id)) |
898 | drive->wcache = 1; | 830 | drive->wcache = 1; |
899 | 831 | ||
900 | write_cache(drive, 1); | 832 | set_wcache(drive, 1); |
901 | } | 833 | } |
902 | 834 | ||
903 | static void ide_cacheflush_p(ide_drive_t *drive) | 835 | static void ide_cacheflush_p(ide_drive_t *drive) |
904 | { | 836 | { |
905 | if (!drive->wcache || !ide_id_has_flush_cache(drive->id)) | 837 | if (!drive->wcache || ata_id_flush_enabled(drive->id) == 0) |
906 | return; | 838 | return; |
907 | 839 | ||
908 | if (do_idedisk_flushcache(drive)) | 840 | if (do_idedisk_flushcache(drive)) |
@@ -944,7 +876,7 @@ static int ide_disk_probe(ide_drive_t *drive); | |||
944 | */ | 876 | */ |
945 | static void ide_disk_resume(ide_drive_t *drive) | 877 | static void ide_disk_resume(ide_drive_t *drive) |
946 | { | 878 | { |
947 | if (idedisk_supports_hpa(drive->id)) | 879 | if (ata_id_hpa_enabled(drive->id)) |
948 | init_idedisk_capacity(drive); | 880 | init_idedisk_capacity(drive); |
949 | } | 881 | } |
950 | 882 | ||
@@ -987,12 +919,12 @@ static ide_driver_t idedisk_driver = { | |||
987 | .shutdown = ide_device_shutdown, | 919 | .shutdown = ide_device_shutdown, |
988 | .version = IDEDISK_VERSION, | 920 | .version = IDEDISK_VERSION, |
989 | .media = ide_disk, | 921 | .media = ide_disk, |
990 | .supports_dsc_overlap = 0, | ||
991 | .do_request = ide_do_rw_disk, | 922 | .do_request = ide_do_rw_disk, |
992 | .end_request = ide_end_request, | 923 | .end_request = ide_end_request, |
993 | .error = __ide_error, | 924 | .error = __ide_error, |
994 | #ifdef CONFIG_IDE_PROC_FS | 925 | #ifdef CONFIG_IDE_PROC_FS |
995 | .proc = idedisk_proc, | 926 | .proc = idedisk_proc, |
927 | .settings = idedisk_settings, | ||
996 | #endif | 928 | #endif |
997 | }; | 929 | }; |
998 | 930 | ||
@@ -1001,7 +933,7 @@ static int idedisk_set_doorlock(ide_drive_t *drive, int on) | |||
1001 | ide_task_t task; | 933 | ide_task_t task; |
1002 | 934 | ||
1003 | memset(&task, 0, sizeof(task)); | 935 | memset(&task, 0, sizeof(task)); |
1004 | task.tf.command = on ? WIN_DOORLOCK : WIN_DOORUNLOCK; | 936 | task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; |
1005 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 937 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
1006 | 938 | ||
1007 | return ide_no_data_taskfile(drive, &task); | 939 | return ide_no_data_taskfile(drive, &task); |
@@ -1066,52 +998,28 @@ static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
1066 | return 0; | 998 | return 0; |
1067 | } | 999 | } |
1068 | 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 | |||
1069 | static int idedisk_ioctl(struct inode *inode, struct file *file, | 1010 | static int idedisk_ioctl(struct inode *inode, struct file *file, |
1070 | unsigned int cmd, unsigned long arg) | 1011 | unsigned int cmd, unsigned long arg) |
1071 | { | 1012 | { |
1072 | unsigned long flags; | ||
1073 | struct block_device *bdev = inode->i_bdev; | 1013 | struct block_device *bdev = inode->i_bdev; |
1074 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); | 1014 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); |
1075 | ide_drive_t *drive = idkp->drive; | 1015 | ide_drive_t *drive = idkp->drive; |
1076 | int err, (*setfunc)(ide_drive_t *, int); | 1016 | int err; |
1077 | u8 *val; | ||
1078 | |||
1079 | switch (cmd) { | ||
1080 | case HDIO_GET_ADDRESS: val = &drive->addressing; goto read_val; | ||
1081 | case HDIO_GET_MULTCOUNT: val = &drive->mult_count; goto read_val; | ||
1082 | case HDIO_GET_NOWERR: val = &drive->nowerr; goto read_val; | ||
1083 | case HDIO_GET_WCACHE: val = &drive->wcache; goto read_val; | ||
1084 | case HDIO_GET_ACOUSTIC: val = &drive->acoustic; goto read_val; | ||
1085 | case HDIO_SET_ADDRESS: setfunc = set_lba_addressing; goto set_val; | ||
1086 | case HDIO_SET_MULTCOUNT: setfunc = set_multcount; goto set_val; | ||
1087 | case HDIO_SET_NOWERR: setfunc = set_nowerr; goto set_val; | ||
1088 | case HDIO_SET_WCACHE: setfunc = write_cache; goto set_val; | ||
1089 | case HDIO_SET_ACOUSTIC: setfunc = set_acoustic; goto set_val; | ||
1090 | } | ||
1091 | 1017 | ||
1092 | 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; | ||
1093 | 1021 | ||
1094 | read_val: | 1022 | return generic_ide_ioctl(drive, file, bdev, cmd, arg); |
1095 | mutex_lock(&ide_setting_mtx); | ||
1096 | spin_lock_irqsave(&ide_lock, flags); | ||
1097 | err = *val; | ||
1098 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1099 | mutex_unlock(&ide_setting_mtx); | ||
1100 | return err >= 0 ? put_user(err, (long __user *)arg) : err; | ||
1101 | |||
1102 | set_val: | ||
1103 | if (bdev != bdev->bd_contains) | ||
1104 | err = -EINVAL; | ||
1105 | else { | ||
1106 | if (!capable(CAP_SYS_ADMIN)) | ||
1107 | err = -EACCES; | ||
1108 | else { | ||
1109 | mutex_lock(&ide_setting_mtx); | ||
1110 | err = setfunc(drive, arg); | ||
1111 | mutex_unlock(&ide_setting_mtx); | ||
1112 | } | ||
1113 | } | ||
1114 | return err; | ||
1115 | } | 1023 | } |
1116 | 1024 | ||
1117 | static int idedisk_media_changed(struct gendisk *disk) | 1025 | static int idedisk_media_changed(struct gendisk *disk) |
@@ -1155,8 +1063,7 @@ static int ide_disk_probe(ide_drive_t *drive) | |||
1155 | /* strstr("foo", "") is non-NULL */ | 1063 | /* strstr("foo", "") is non-NULL */ |
1156 | if (!strstr("ide-disk", drive->driver_req)) | 1064 | if (!strstr("ide-disk", drive->driver_req)) |
1157 | goto failed; | 1065 | goto failed; |
1158 | if (!drive->present) | 1066 | |
1159 | goto failed; | ||
1160 | if (drive->media != ide_disk) | 1067 | if (drive->media != ide_disk) |
1161 | goto failed; | 1068 | goto failed; |
1162 | 1069 | ||
@@ -1164,15 +1071,12 @@ static int ide_disk_probe(ide_drive_t *drive) | |||
1164 | if (!idkp) | 1071 | if (!idkp) |
1165 | goto failed; | 1072 | goto failed; |
1166 | 1073 | ||
1167 | g = alloc_disk_node(1 << PARTN_BITS, | 1074 | g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); |
1168 | hwif_to_node(drive->hwif)); | ||
1169 | if (!g) | 1075 | if (!g) |
1170 | goto out_free_idkp; | 1076 | goto out_free_idkp; |
1171 | 1077 | ||
1172 | ide_init_disk(g, drive); | 1078 | ide_init_disk(g, drive); |
1173 | 1079 | ||
1174 | ide_proc_register_driver(drive, &idedisk_driver); | ||
1175 | |||
1176 | kref_init(&idkp->kref); | 1080 | kref_init(&idkp->kref); |
1177 | 1081 | ||
1178 | idkp->drive = drive; | 1082 | idkp->drive = drive; |
@@ -1191,9 +1095,11 @@ static int ide_disk_probe(ide_drive_t *drive) | |||
1191 | } else | 1095 | } else |
1192 | drive->attach = 1; | 1096 | drive->attach = 1; |
1193 | 1097 | ||
1194 | g->minors = 1 << PARTN_BITS; | 1098 | g->minors = IDE_DISK_MINORS; |
1195 | g->driverfs_dev = &drive->gendev; | 1099 | g->driverfs_dev = &drive->gendev; |
1196 | 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; | ||
1197 | set_capacity(g, idedisk_capacity(drive)); | 1103 | set_capacity(g, idedisk_capacity(drive)); |
1198 | g->fops = &idedisk_ops; | 1104 | g->fops = &idedisk_ops; |
1199 | add_disk(g); | 1105 | add_disk(g); |