diff options
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r-- | drivers/ide/ide.c | 77 |
1 files changed, 44 insertions, 33 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index ab9ca2b5b66c..ac6136001615 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -499,6 +499,8 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | |||
499 | /** | 499 | /** |
500 | * ide_unregister - free an IDE interface | 500 | * ide_unregister - free an IDE interface |
501 | * @index: index of interface (will change soon to a pointer) | 501 | * @index: index of interface (will change soon to a pointer) |
502 | * @init_default: init default hwif flag | ||
503 | * @restore: restore hwif flag | ||
502 | * | 504 | * |
503 | * Perform the final unregister of an IDE interface. At the moment | 505 | * Perform the final unregister of an IDE interface. At the moment |
504 | * we don't refcount interfaces so this will also get split up. | 506 | * we don't refcount interfaces so this will also get split up. |
@@ -518,7 +520,7 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | |||
518 | * This is raving bonkers. | 520 | * This is raving bonkers. |
519 | */ | 521 | */ |
520 | 522 | ||
521 | void ide_unregister(unsigned int index) | 523 | void ide_unregister(unsigned int index, int init_default, int restore) |
522 | { | 524 | { |
523 | ide_drive_t *drive; | 525 | ide_drive_t *drive; |
524 | ide_hwif_t *hwif, *g; | 526 | ide_hwif_t *hwif, *g; |
@@ -602,9 +604,12 @@ void ide_unregister(unsigned int index) | |||
602 | 604 | ||
603 | /* restore hwif data to pristine status */ | 605 | /* restore hwif data to pristine status */ |
604 | ide_init_port_data(hwif, index); | 606 | ide_init_port_data(hwif, index); |
605 | init_hwif_default(hwif, index); | ||
606 | 607 | ||
607 | ide_hwif_restore(hwif, &tmp_hwif); | 608 | if (init_default) |
609 | init_hwif_default(hwif, index); | ||
610 | |||
611 | if (restore) | ||
612 | ide_hwif_restore(hwif, &tmp_hwif); | ||
608 | 613 | ||
609 | abort: | 614 | abort: |
610 | spin_unlock_irq(&ide_lock); | 615 | spin_unlock_irq(&ide_lock); |
@@ -678,6 +683,31 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | |||
678 | } | 683 | } |
679 | EXPORT_SYMBOL_GPL(ide_init_port_hw); | 684 | EXPORT_SYMBOL_GPL(ide_init_port_hw); |
680 | 685 | ||
686 | ide_hwif_t *ide_deprecated_find_port(unsigned long base) | ||
687 | { | ||
688 | ide_hwif_t *hwif; | ||
689 | int i; | ||
690 | |||
691 | for (i = 0; i < MAX_HWIFS; i++) { | ||
692 | hwif = &ide_hwifs[i]; | ||
693 | if (hwif->io_ports[IDE_DATA_OFFSET] == base) | ||
694 | goto found; | ||
695 | } | ||
696 | |||
697 | for (i = 0; i < MAX_HWIFS; i++) { | ||
698 | hwif = &ide_hwifs[i]; | ||
699 | if (hwif->hold) | ||
700 | continue; | ||
701 | if (!hwif->present && hwif->mate == NULL) | ||
702 | goto found; | ||
703 | } | ||
704 | |||
705 | hwif = NULL; | ||
706 | found: | ||
707 | return hwif; | ||
708 | } | ||
709 | EXPORT_SYMBOL_GPL(ide_deprecated_find_port); | ||
710 | |||
681 | /** | 711 | /** |
682 | * ide_register_hw - register IDE interface | 712 | * ide_register_hw - register IDE interface |
683 | * @hw: hardware registers | 713 | * @hw: hardware registers |
@@ -697,38 +727,26 @@ int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *), | |||
697 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 727 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
698 | 728 | ||
699 | do { | 729 | do { |
700 | for (index = 0; index < MAX_HWIFS; ++index) { | 730 | hwif = ide_deprecated_find_port(hw->io_ports[IDE_DATA_OFFSET]); |
701 | hwif = &ide_hwifs[index]; | 731 | index = hwif->index; |
702 | if (hwif->io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET]) | 732 | if (hwif) |
703 | goto found; | 733 | goto found; |
704 | } | ||
705 | for (index = 0; index < MAX_HWIFS; ++index) { | ||
706 | hwif = &ide_hwifs[index]; | ||
707 | if (hwif->hold) | ||
708 | continue; | ||
709 | if (!hwif->present && hwif->mate == NULL) | ||
710 | goto found; | ||
711 | } | ||
712 | for (index = 0; index < MAX_HWIFS; index++) | 734 | for (index = 0; index < MAX_HWIFS; index++) |
713 | ide_unregister(index); | 735 | ide_unregister(index, 1, 1); |
714 | } while (retry--); | 736 | } while (retry--); |
715 | return -1; | 737 | return -1; |
716 | found: | 738 | found: |
717 | if (hwif->present) | 739 | if (hwif->present) |
718 | ide_unregister(index); | 740 | ide_unregister(index, 0, 1); |
719 | else if (!hwif->hold) { | 741 | else if (!hwif->hold) |
720 | ide_init_port_data(hwif, index); | 742 | ide_init_port_data(hwif, index); |
721 | init_hwif_default(hwif, index); | ||
722 | } | ||
723 | if (hwif->present) | ||
724 | return -1; | ||
725 | 743 | ||
726 | ide_init_port_hw(hwif, hw); | 744 | ide_init_port_hw(hwif, hw); |
727 | hwif->quirkproc = quirkproc; | 745 | hwif->quirkproc = quirkproc; |
728 | 746 | ||
729 | idx[0] = index; | 747 | idx[0] = index; |
730 | 748 | ||
731 | ide_device_add(idx); | 749 | ide_device_add(idx, NULL); |
732 | 750 | ||
733 | if (hwifp) | 751 | if (hwifp) |
734 | *hwifp = hwif; | 752 | *hwifp = hwif; |
@@ -791,10 +809,6 @@ int set_io_32bit(ide_drive_t *drive, int arg) | |||
791 | return -EBUSY; | 809 | return -EBUSY; |
792 | 810 | ||
793 | drive->io_32bit = arg; | 811 | drive->io_32bit = arg; |
794 | #ifdef CONFIG_BLK_DEV_DTC2278 | ||
795 | if (HWIF(drive)->chipset == ide_dtc2278) | ||
796 | HWIF(drive)->drives[!drive->select.b.unit].io_32bit = arg; | ||
797 | #endif /* CONFIG_BLK_DEV_DTC2278 */ | ||
798 | 812 | ||
799 | spin_unlock_irq(&ide_lock); | 813 | spin_unlock_irq(&ide_lock); |
800 | 814 | ||
@@ -1021,11 +1035,8 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
1021 | case HDIO_GET_NICE: | 1035 | case HDIO_GET_NICE: |
1022 | return put_user(drive->dsc_overlap << IDE_NICE_DSC_OVERLAP | | 1036 | return put_user(drive->dsc_overlap << IDE_NICE_DSC_OVERLAP | |
1023 | drive->atapi_overlap << IDE_NICE_ATAPI_OVERLAP | | 1037 | drive->atapi_overlap << IDE_NICE_ATAPI_OVERLAP | |
1024 | drive->nice0 << IDE_NICE_0 | | 1038 | drive->nice1 << IDE_NICE_1, |
1025 | drive->nice1 << IDE_NICE_1 | | ||
1026 | drive->nice2 << IDE_NICE_2, | ||
1027 | (long __user *) arg); | 1039 | (long __user *) arg); |
1028 | |||
1029 | #ifdef CONFIG_IDE_TASK_IOCTL | 1040 | #ifdef CONFIG_IDE_TASK_IOCTL |
1030 | case HDIO_DRIVE_TASKFILE: | 1041 | case HDIO_DRIVE_TASKFILE: |
1031 | if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) | 1042 | if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) |
@@ -1066,7 +1077,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
1066 | case HDIO_UNREGISTER_HWIF: | 1077 | case HDIO_UNREGISTER_HWIF: |
1067 | if (!capable(CAP_SYS_RAWIO)) return -EACCES; | 1078 | if (!capable(CAP_SYS_RAWIO)) return -EACCES; |
1068 | /* (arg > MAX_HWIFS) checked in function */ | 1079 | /* (arg > MAX_HWIFS) checked in function */ |
1069 | ide_unregister(arg); | 1080 | ide_unregister(arg, 1, 1); |
1070 | return 0; | 1081 | return 0; |
1071 | case HDIO_SET_NICE: | 1082 | case HDIO_SET_NICE: |
1072 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; | 1083 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; |
@@ -1711,7 +1722,7 @@ void __exit cleanup_module (void) | |||
1711 | int index; | 1722 | int index; |
1712 | 1723 | ||
1713 | for (index = 0; index < MAX_HWIFS; ++index) | 1724 | for (index = 0; index < MAX_HWIFS; ++index) |
1714 | ide_unregister(index); | 1725 | ide_unregister(index, 0, 0); |
1715 | 1726 | ||
1716 | proc_ide_destroy(); | 1727 | proc_ide_destroy(); |
1717 | 1728 | ||