diff options
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r-- | drivers/ide/ide.c | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 961e6c897286..674a65c1a130 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -168,7 +168,6 @@ static void init_hwif_default(ide_hwif_t *hwif, unsigned int index) | |||
168 | 168 | ||
169 | ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq); | 169 | ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq); |
170 | 170 | ||
171 | memcpy(&hwif->hw, &hw, sizeof(hw)); | ||
172 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports)); | 171 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports)); |
173 | 172 | ||
174 | hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; | 173 | hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; |
@@ -214,7 +213,7 @@ static void __init init_ide_data (void) | |||
214 | init_hwif_data(hwif, index); | 213 | init_hwif_data(hwif, index); |
215 | init_hwif_default(hwif, index); | 214 | init_hwif_default(hwif, index); |
216 | #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI) | 215 | #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI) |
217 | hwif->irq = hwif->hw.irq = | 216 | hwif->irq = |
218 | ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]); | 217 | ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]); |
219 | #endif | 218 | #endif |
220 | } | 219 | } |
@@ -265,6 +264,30 @@ static int ide_system_bus_speed(void) | |||
265 | return system_bus_speed; | 264 | return system_bus_speed; |
266 | } | 265 | } |
267 | 266 | ||
267 | ide_hwif_t * ide_find_port(unsigned long base) | ||
268 | { | ||
269 | ide_hwif_t *hwif; | ||
270 | int i; | ||
271 | |||
272 | for (i = 0; i < MAX_HWIFS; i++) { | ||
273 | hwif = &ide_hwifs[i]; | ||
274 | if (hwif->io_ports[IDE_DATA_OFFSET] == base) | ||
275 | goto found; | ||
276 | } | ||
277 | |||
278 | for (i = 0; i < MAX_HWIFS; i++) { | ||
279 | hwif = &ide_hwifs[i]; | ||
280 | if (hwif->io_ports[IDE_DATA_OFFSET] == 0) | ||
281 | goto found; | ||
282 | } | ||
283 | |||
284 | hwif = NULL; | ||
285 | found: | ||
286 | return hwif; | ||
287 | } | ||
288 | |||
289 | EXPORT_SYMBOL_GPL(ide_find_port); | ||
290 | |||
268 | static struct resource* hwif_request_region(ide_hwif_t *hwif, | 291 | static struct resource* hwif_request_region(ide_hwif_t *hwif, |
269 | unsigned long addr, int num) | 292 | unsigned long addr, int num) |
270 | { | 293 | { |
@@ -391,6 +414,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
391 | hwif->cds = tmp_hwif->cds; | 414 | hwif->cds = tmp_hwif->cds; |
392 | #endif | 415 | #endif |
393 | 416 | ||
417 | hwif->fixup = tmp_hwif->fixup; | ||
418 | |||
394 | hwif->set_pio_mode = tmp_hwif->set_pio_mode; | 419 | hwif->set_pio_mode = tmp_hwif->set_pio_mode; |
395 | hwif->set_dma_mode = tmp_hwif->set_dma_mode; | 420 | hwif->set_dma_mode = tmp_hwif->set_dma_mode; |
396 | hwif->mdma_filter = tmp_hwif->mdma_filter; | 421 | hwif->mdma_filter = tmp_hwif->mdma_filter; |
@@ -652,7 +677,6 @@ void ide_setup_ports ( hw_regs_t *hw, | |||
652 | } | 677 | } |
653 | } | 678 | } |
654 | hw->irq = irq; | 679 | hw->irq = irq; |
655 | hw->dma = NO_DMA; | ||
656 | hw->ack_intr = ack_intr; | 680 | hw->ack_intr = ack_intr; |
657 | /* | 681 | /* |
658 | * hw->iops = iops; | 682 | * hw->iops = iops; |
@@ -660,11 +684,11 @@ void ide_setup_ports ( hw_regs_t *hw, | |||
660 | } | 684 | } |
661 | 685 | ||
662 | /** | 686 | /** |
663 | * ide_register_hw_with_fixup - register IDE interface | 687 | * ide_register_hw - register IDE interface |
664 | * @hw: hardware registers | 688 | * @hw: hardware registers |
689 | * @fixup: fixup function | ||
665 | * @initializing: set while initializing built-in drivers | 690 | * @initializing: set while initializing built-in drivers |
666 | * @hwifp: pointer to returned hwif | 691 | * @hwifp: pointer to returned hwif |
667 | * @fixup: fixup function | ||
668 | * | 692 | * |
669 | * Register an IDE interface, specifying exactly the registers etc. | 693 | * Register an IDE interface, specifying exactly the registers etc. |
670 | * Set init=1 iff calling before probes have taken place. | 694 | * Set init=1 iff calling before probes have taken place. |
@@ -672,9 +696,8 @@ void ide_setup_ports ( hw_regs_t *hw, | |||
672 | * Returns -1 on error. | 696 | * Returns -1 on error. |
673 | */ | 697 | */ |
674 | 698 | ||
675 | int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing, | 699 | int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *), |
676 | ide_hwif_t **hwifp, | 700 | int initializing, ide_hwif_t **hwifp) |
677 | void(*fixup)(ide_hwif_t *hwif)) | ||
678 | { | 701 | { |
679 | int index, retry = 1; | 702 | int index, retry = 1; |
680 | ide_hwif_t *hwif; | 703 | ide_hwif_t *hwif; |
@@ -682,7 +705,7 @@ int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing, | |||
682 | do { | 705 | do { |
683 | for (index = 0; index < MAX_HWIFS; ++index) { | 706 | for (index = 0; index < MAX_HWIFS; ++index) { |
684 | hwif = &ide_hwifs[index]; | 707 | hwif = &ide_hwifs[index]; |
685 | if (hwif->hw.io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET]) | 708 | if (hwif->io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET]) |
686 | goto found; | 709 | goto found; |
687 | } | 710 | } |
688 | for (index = 0; index < MAX_HWIFS; ++index) { | 711 | for (index = 0; index < MAX_HWIFS; ++index) { |
@@ -690,7 +713,7 @@ int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing, | |||
690 | if (hwif->hold) | 713 | if (hwif->hold) |
691 | continue; | 714 | continue; |
692 | if ((!hwif->present && !hwif->mate && !initializing) || | 715 | if ((!hwif->present && !hwif->mate && !initializing) || |
693 | (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing)) | 716 | (!hwif->io_ports[IDE_DATA_OFFSET] && initializing)) |
694 | goto found; | 717 | goto found; |
695 | } | 718 | } |
696 | for (index = 0; index < MAX_HWIFS; index++) | 719 | for (index = 0; index < MAX_HWIFS; index++) |
@@ -706,16 +729,18 @@ found: | |||
706 | } | 729 | } |
707 | if (hwif->present) | 730 | if (hwif->present) |
708 | return -1; | 731 | return -1; |
709 | memcpy(&hwif->hw, hw, sizeof(*hw)); | 732 | memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); |
710 | memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); | ||
711 | hwif->irq = hw->irq; | 733 | hwif->irq = hw->irq; |
712 | hwif->noprobe = 0; | 734 | hwif->noprobe = 0; |
735 | hwif->fixup = fixup; | ||
713 | hwif->chipset = hw->chipset; | 736 | hwif->chipset = hw->chipset; |
714 | hwif->gendev.parent = hw->dev; | 737 | hwif->gendev.parent = hw->dev; |
738 | hwif->ack_intr = hw->ack_intr; | ||
739 | |||
740 | if (initializing == 0) { | ||
741 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | ||
715 | 742 | ||
716 | if (!initializing) { | 743 | ide_device_add(idx); |
717 | probe_hwif_init_with_fixup(hwif, fixup); | ||
718 | ide_proc_register_port(hwif); | ||
719 | } | 744 | } |
720 | 745 | ||
721 | if (hwifp) | 746 | if (hwifp) |
@@ -724,13 +749,6 @@ found: | |||
724 | return (initializing || hwif->present) ? index : -1; | 749 | return (initializing || hwif->present) ? index : -1; |
725 | } | 750 | } |
726 | 751 | ||
727 | EXPORT_SYMBOL(ide_register_hw_with_fixup); | ||
728 | |||
729 | int ide_register_hw(hw_regs_t *hw, int initializing, ide_hwif_t **hwifp) | ||
730 | { | ||
731 | return ide_register_hw_with_fixup(hw, initializing, hwifp, NULL); | ||
732 | } | ||
733 | |||
734 | EXPORT_SYMBOL(ide_register_hw); | 752 | EXPORT_SYMBOL(ide_register_hw); |
735 | 753 | ||
736 | /* | 754 | /* |
@@ -1046,7 +1064,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
1046 | ide_init_hwif_ports(&hw, (unsigned long) args[0], | 1064 | ide_init_hwif_ports(&hw, (unsigned long) args[0], |
1047 | (unsigned long) args[1], NULL); | 1065 | (unsigned long) args[1], NULL); |
1048 | hw.irq = args[2]; | 1066 | hw.irq = args[2]; |
1049 | if (ide_register_hw(&hw, 0, NULL) == -1) | 1067 | if (ide_register_hw(&hw, NULL, 0, NULL) == -1) |
1050 | return -EIO; | 1068 | return -EIO; |
1051 | return 0; | 1069 | return 0; |
1052 | } | 1070 | } |
@@ -1397,6 +1415,9 @@ static int __init ide_setup(char *s) | |||
1397 | "reset", "minus6", "ata66", "minus8", "minus9", | 1415 | "reset", "minus6", "ata66", "minus8", "minus9", |
1398 | "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb", | 1416 | "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb", |
1399 | "dtc2278", "umc8672", "ali14xx", NULL }; | 1417 | "dtc2278", "umc8672", "ali14xx", NULL }; |
1418 | |||
1419 | hw_regs_t hwregs; | ||
1420 | |||
1400 | hw = s[3] - '0'; | 1421 | hw = s[3] - '0'; |
1401 | hwif = &ide_hwifs[hw]; | 1422 | hwif = &ide_hwifs[hw]; |
1402 | i = match_parm(&s[4], ide_words, vals, 3); | 1423 | i = match_parm(&s[4], ide_words, vals, 3); |
@@ -1506,9 +1527,9 @@ static int __init ide_setup(char *s) | |||
1506 | case 2: /* base,ctl */ | 1527 | case 2: /* base,ctl */ |
1507 | vals[2] = 0; /* default irq = probe for it */ | 1528 | vals[2] = 0; /* default irq = probe for it */ |
1508 | case 3: /* base,ctl,irq */ | 1529 | case 3: /* base,ctl,irq */ |
1509 | hwif->hw.irq = vals[2]; | 1530 | memset(&hwregs, 0, sizeof(hwregs)); |
1510 | ide_init_hwif_ports(&hwif->hw, (unsigned long) vals[0], (unsigned long) vals[1], &hwif->irq); | 1531 | ide_init_hwif_ports(&hwregs, vals[0], vals[1], &hwif->irq); |
1511 | memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); | 1532 | memcpy(hwif->io_ports, hwregs.io_ports, sizeof(hwif->io_ports)); |
1512 | hwif->irq = vals[2]; | 1533 | hwif->irq = vals[2]; |
1513 | hwif->noprobe = 0; | 1534 | hwif->noprobe = 0; |
1514 | hwif->chipset = ide_forced; | 1535 | hwif->chipset = ide_forced; |