diff options
Diffstat (limited to 'drivers/ide/ide.c')
| -rw-r--r-- | drivers/ide/ide.c | 307 |
1 files changed, 25 insertions, 282 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 973dec799b5c..dae1bd5b8c3e 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -196,8 +196,6 @@ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ | |||
| 196 | 196 | ||
| 197 | EXPORT_SYMBOL(ide_hwifs); | 197 | EXPORT_SYMBOL(ide_hwifs); |
| 198 | 198 | ||
| 199 | static struct list_head ide_drives = LIST_HEAD_INIT(ide_drives); | ||
| 200 | |||
| 201 | /* | 199 | /* |
| 202 | * Do not even *think* about calling this! | 200 | * Do not even *think* about calling this! |
| 203 | */ | 201 | */ |
| @@ -358,54 +356,6 @@ static int ide_system_bus_speed(void) | |||
| 358 | return system_bus_speed; | 356 | return system_bus_speed; |
| 359 | } | 357 | } |
| 360 | 358 | ||
| 361 | /* | ||
| 362 | * drives_lock protects the list of drives, drivers_lock the | ||
| 363 | * list of drivers. Currently nobody takes both at once. | ||
| 364 | */ | ||
| 365 | |||
| 366 | static DEFINE_SPINLOCK(drives_lock); | ||
| 367 | static DEFINE_SPINLOCK(drivers_lock); | ||
| 368 | static LIST_HEAD(drivers); | ||
| 369 | |||
| 370 | /* Iterator for the driver list. */ | ||
| 371 | |||
| 372 | static void *m_start(struct seq_file *m, loff_t *pos) | ||
| 373 | { | ||
| 374 | struct list_head *p; | ||
| 375 | loff_t l = *pos; | ||
| 376 | spin_lock(&drivers_lock); | ||
| 377 | list_for_each(p, &drivers) | ||
| 378 | if (!l--) | ||
| 379 | return list_entry(p, ide_driver_t, drivers); | ||
| 380 | return NULL; | ||
| 381 | } | ||
| 382 | |||
| 383 | static void *m_next(struct seq_file *m, void *v, loff_t *pos) | ||
| 384 | { | ||
| 385 | struct list_head *p = ((ide_driver_t *)v)->drivers.next; | ||
| 386 | (*pos)++; | ||
| 387 | return p==&drivers ? NULL : list_entry(p, ide_driver_t, drivers); | ||
| 388 | } | ||
| 389 | |||
| 390 | static void m_stop(struct seq_file *m, void *v) | ||
| 391 | { | ||
| 392 | spin_unlock(&drivers_lock); | ||
| 393 | } | ||
| 394 | |||
| 395 | static int show_driver(struct seq_file *m, void *v) | ||
| 396 | { | ||
| 397 | ide_driver_t *driver = v; | ||
| 398 | seq_printf(m, "%s version %s\n", driver->name, driver->version); | ||
| 399 | return 0; | ||
| 400 | } | ||
| 401 | |||
| 402 | struct seq_operations ide_drivers_op = { | ||
| 403 | .start = m_start, | ||
| 404 | .next = m_next, | ||
| 405 | .stop = m_stop, | ||
| 406 | .show = show_driver | ||
| 407 | }; | ||
| 408 | |||
| 409 | #ifdef CONFIG_PROC_FS | 359 | #ifdef CONFIG_PROC_FS |
| 410 | struct proc_dir_entry *proc_ide_root; | 360 | struct proc_dir_entry *proc_ide_root; |
| 411 | #endif | 361 | #endif |
| @@ -630,7 +580,7 @@ void ide_unregister(unsigned int index) | |||
| 630 | ide_hwif_t *hwif, *g; | 580 | ide_hwif_t *hwif, *g; |
| 631 | static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */ | 581 | static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */ |
| 632 | ide_hwgroup_t *hwgroup; | 582 | ide_hwgroup_t *hwgroup; |
| 633 | int irq_count = 0, unit, i; | 583 | int irq_count = 0, unit; |
| 634 | 584 | ||
| 635 | BUG_ON(index >= MAX_HWIFS); | 585 | BUG_ON(index >= MAX_HWIFS); |
| 636 | 586 | ||
| @@ -643,23 +593,22 @@ void ide_unregister(unsigned int index) | |||
| 643 | goto abort; | 593 | goto abort; |
| 644 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 594 | for (unit = 0; unit < MAX_DRIVES; ++unit) { |
| 645 | drive = &hwif->drives[unit]; | 595 | drive = &hwif->drives[unit]; |
| 646 | if (!drive->present) | 596 | if (!drive->present) { |
| 597 | if (drive->devfs_name[0] != '\0') { | ||
| 598 | devfs_remove(drive->devfs_name); | ||
| 599 | drive->devfs_name[0] = '\0'; | ||
| 600 | } | ||
| 647 | continue; | 601 | continue; |
| 648 | if (drive->usage || DRIVER(drive)->busy) | 602 | } |
| 649 | goto abort; | 603 | spin_unlock_irq(&ide_lock); |
| 650 | drive->dead = 1; | 604 | device_unregister(&drive->gendev); |
| 605 | down(&drive->gendev_rel_sem); | ||
| 606 | spin_lock_irq(&ide_lock); | ||
| 651 | } | 607 | } |
| 652 | hwif->present = 0; | 608 | hwif->present = 0; |
| 653 | 609 | ||
| 654 | spin_unlock_irq(&ide_lock); | 610 | spin_unlock_irq(&ide_lock); |
| 655 | 611 | ||
| 656 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | ||
| 657 | drive = &hwif->drives[unit]; | ||
| 658 | if (!drive->present) | ||
| 659 | continue; | ||
| 660 | DRIVER(drive)->cleanup(drive); | ||
| 661 | } | ||
| 662 | |||
| 663 | destroy_proc_ide_interface(hwif); | 612 | destroy_proc_ide_interface(hwif); |
| 664 | 613 | ||
| 665 | hwgroup = hwif->hwgroup; | 614 | hwgroup = hwif->hwgroup; |
| @@ -687,44 +636,6 @@ void ide_unregister(unsigned int index) | |||
| 687 | * Remove us from the hwgroup, and free | 636 | * Remove us from the hwgroup, and free |
| 688 | * the hwgroup if we were the only member | 637 | * the hwgroup if we were the only member |
| 689 | */ | 638 | */ |
| 690 | for (i = 0; i < MAX_DRIVES; ++i) { | ||
| 691 | drive = &hwif->drives[i]; | ||
| 692 | if (drive->devfs_name[0] != '\0') { | ||
| 693 | devfs_remove(drive->devfs_name); | ||
| 694 | drive->devfs_name[0] = '\0'; | ||
| 695 | } | ||
| 696 | if (!drive->present) | ||
| 697 | continue; | ||
| 698 | if (drive == drive->next) { | ||
| 699 | /* special case: last drive from hwgroup. */ | ||
| 700 | BUG_ON(hwgroup->drive != drive); | ||
| 701 | hwgroup->drive = NULL; | ||
| 702 | } else { | ||
| 703 | ide_drive_t *walk; | ||
| 704 | |||
| 705 | walk = hwgroup->drive; | ||
| 706 | while (walk->next != drive) | ||
| 707 | walk = walk->next; | ||
| 708 | walk->next = drive->next; | ||
| 709 | if (hwgroup->drive == drive) { | ||
| 710 | hwgroup->drive = drive->next; | ||
| 711 | hwgroup->hwif = HWIF(hwgroup->drive); | ||
| 712 | } | ||
| 713 | } | ||
| 714 | BUG_ON(hwgroup->drive == drive); | ||
| 715 | if (drive->id != NULL) { | ||
| 716 | kfree(drive->id); | ||
| 717 | drive->id = NULL; | ||
| 718 | } | ||
| 719 | drive->present = 0; | ||
| 720 | /* Messed up locking ... */ | ||
| 721 | spin_unlock_irq(&ide_lock); | ||
| 722 | blk_cleanup_queue(drive->queue); | ||
| 723 | device_unregister(&drive->gendev); | ||
| 724 | down(&drive->gendev_rel_sem); | ||
| 725 | spin_lock_irq(&ide_lock); | ||
| 726 | drive->queue = NULL; | ||
| 727 | } | ||
| 728 | if (hwif->next == hwif) { | 639 | if (hwif->next == hwif) { |
| 729 | BUG_ON(hwgroup->hwif != hwif); | 640 | BUG_ON(hwgroup->hwif != hwif); |
| 730 | kfree(hwgroup); | 641 | kfree(hwgroup); |
| @@ -1304,73 +1215,6 @@ int system_bus_clock (void) | |||
| 1304 | 1215 | ||
| 1305 | EXPORT_SYMBOL(system_bus_clock); | 1216 | EXPORT_SYMBOL(system_bus_clock); |
| 1306 | 1217 | ||
| 1307 | /* | ||
| 1308 | * Locking is badly broken here - since way back. That sucker is | ||
| 1309 | * root-only, but that's not an excuse... The real question is what | ||
| 1310 | * exclusion rules do we want here. | ||
| 1311 | */ | ||
| 1312 | int ide_replace_subdriver (ide_drive_t *drive, const char *driver) | ||
| 1313 | { | ||
| 1314 | if (!drive->present || drive->usage || drive->dead) | ||
| 1315 | goto abort; | ||
| 1316 | if (DRIVER(drive)->cleanup(drive)) | ||
| 1317 | goto abort; | ||
| 1318 | strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); | ||
| 1319 | if (ata_attach(drive)) { | ||
| 1320 | spin_lock(&drives_lock); | ||
| 1321 | list_del_init(&drive->list); | ||
| 1322 | spin_unlock(&drives_lock); | ||
| 1323 | drive->driver_req[0] = 0; | ||
| 1324 | ata_attach(drive); | ||
| 1325 | } else { | ||
| 1326 | drive->driver_req[0] = 0; | ||
| 1327 | } | ||
| 1328 | if (drive->driver && !strcmp(drive->driver->name, driver)) | ||
| 1329 | return 0; | ||
| 1330 | abort: | ||
| 1331 | return 1; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | /** | ||
| 1335 | * ata_attach - attach an ATA/ATAPI device | ||
| 1336 | * @drive: drive to attach | ||
| 1337 | * | ||
| 1338 | * Takes a drive that is as yet not assigned to any midlayer IDE | ||
| 1339 | * driver (or is assigned to the default driver) and figures out | ||
| 1340 | * which driver would like to own it. If nobody claims the drive | ||
| 1341 | * then it is automatically attached to the default driver used for | ||
| 1342 | * unclaimed objects. | ||
| 1343 | * | ||
| 1344 | * A return of zero indicates attachment to a driver, of one | ||
| 1345 | * attachment to the default driver. | ||
| 1346 | * | ||
| 1347 | * Takes drivers_lock. | ||
| 1348 | */ | ||
| 1349 | |||
| 1350 | int ata_attach(ide_drive_t *drive) | ||
| 1351 | { | ||
| 1352 | struct list_head *p; | ||
| 1353 | spin_lock(&drivers_lock); | ||
| 1354 | list_for_each(p, &drivers) { | ||
| 1355 | ide_driver_t *driver = list_entry(p, ide_driver_t, drivers); | ||
| 1356 | if (!try_module_get(driver->owner)) | ||
| 1357 | continue; | ||
| 1358 | spin_unlock(&drivers_lock); | ||
| 1359 | if (driver->attach(drive) == 0) { | ||
| 1360 | module_put(driver->owner); | ||
| 1361 | drive->gendev.driver = &driver->gen_driver; | ||
| 1362 | return 0; | ||
| 1363 | } | ||
| 1364 | spin_lock(&drivers_lock); | ||
| 1365 | module_put(driver->owner); | ||
| 1366 | } | ||
| 1367 | drive->gendev.driver = NULL; | ||
| 1368 | spin_unlock(&drivers_lock); | ||
| 1369 | if (ide_register_subdriver(drive, NULL)) | ||
| 1370 | panic("ide: default attach failed"); | ||
| 1371 | return 1; | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | static int generic_ide_suspend(struct device *dev, pm_message_t state) | 1218 | static int generic_ide_suspend(struct device *dev, pm_message_t state) |
| 1375 | { | 1219 | { |
| 1376 | ide_drive_t *drive = dev->driver_data; | 1220 | ide_drive_t *drive = dev->driver_data; |
| @@ -2013,27 +1857,11 @@ static void __init probe_for_hwifs (void) | |||
| 2013 | #endif | 1857 | #endif |
| 2014 | } | 1858 | } |
| 2015 | 1859 | ||
| 2016 | int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) | 1860 | void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) |
| 2017 | { | 1861 | { |
| 2018 | unsigned long flags; | ||
| 2019 | |||
| 2020 | spin_lock_irqsave(&ide_lock, flags); | ||
| 2021 | if (!drive->present || drive->driver != NULL || | ||
| 2022 | drive->usage || drive->dead) { | ||
| 2023 | spin_unlock_irqrestore(&ide_lock, flags); | ||
| 2024 | return 1; | ||
| 2025 | } | ||
| 2026 | drive->driver = driver; | ||
| 2027 | spin_unlock_irqrestore(&ide_lock, flags); | ||
| 2028 | spin_lock(&drives_lock); | ||
| 2029 | list_add_tail(&drive->list, driver ? &driver->drives : &ide_drives); | ||
| 2030 | spin_unlock(&drives_lock); | ||
| 2031 | // printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name); | ||
| 2032 | #ifdef CONFIG_PROC_FS | 1862 | #ifdef CONFIG_PROC_FS |
| 2033 | if (driver) | 1863 | ide_add_proc_entries(drive->proc, driver->proc, drive); |
| 2034 | ide_add_proc_entries(drive->proc, driver->proc, drive); | ||
| 2035 | #endif | 1864 | #endif |
| 2036 | return 0; | ||
| 2037 | } | 1865 | } |
| 2038 | 1866 | ||
| 2039 | EXPORT_SYMBOL(ide_register_subdriver); | 1867 | EXPORT_SYMBOL(ide_register_subdriver); |
| @@ -2041,136 +1869,51 @@ EXPORT_SYMBOL(ide_register_subdriver); | |||
| 2041 | /** | 1869 | /** |
| 2042 | * ide_unregister_subdriver - disconnect drive from driver | 1870 | * ide_unregister_subdriver - disconnect drive from driver |
| 2043 | * @drive: drive to unplug | 1871 | * @drive: drive to unplug |
| 1872 | * @driver: driver | ||
| 2044 | * | 1873 | * |
| 2045 | * Disconnect a drive from the driver it was attached to and then | 1874 | * Disconnect a drive from the driver it was attached to and then |
| 2046 | * clean up the various proc files and other objects attached to it. | 1875 | * clean up the various proc files and other objects attached to it. |
| 2047 | * | 1876 | * |
| 2048 | * Takes ide_setting_sem, ide_lock and drives_lock. | 1877 | * Takes ide_setting_sem and ide_lock. |
| 2049 | * Caller must hold none of the locks. | 1878 | * Caller must hold none of the locks. |
| 2050 | * | ||
| 2051 | * No locking versus subdriver unload because we are moving to the | ||
| 2052 | * default driver anyway. Wants double checking. | ||
| 2053 | */ | 1879 | */ |
| 2054 | 1880 | ||
| 2055 | int ide_unregister_subdriver (ide_drive_t *drive) | 1881 | void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) |
| 2056 | { | 1882 | { |
| 2057 | unsigned long flags; | 1883 | unsigned long flags; |
| 2058 | 1884 | ||
| 2059 | down(&ide_setting_sem); | 1885 | down(&ide_setting_sem); |
| 2060 | spin_lock_irqsave(&ide_lock, flags); | 1886 | spin_lock_irqsave(&ide_lock, flags); |
| 2061 | if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) { | ||
| 2062 | spin_unlock_irqrestore(&ide_lock, flags); | ||
| 2063 | up(&ide_setting_sem); | ||
| 2064 | return 1; | ||
| 2065 | } | ||
| 2066 | #ifdef CONFIG_PROC_FS | 1887 | #ifdef CONFIG_PROC_FS |
| 2067 | ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc); | 1888 | ide_remove_proc_entries(drive->proc, driver->proc); |
| 2068 | #endif | 1889 | #endif |
| 2069 | auto_remove_settings(drive); | 1890 | auto_remove_settings(drive); |
| 2070 | drive->driver = NULL; | ||
| 2071 | spin_unlock_irqrestore(&ide_lock, flags); | 1891 | spin_unlock_irqrestore(&ide_lock, flags); |
| 2072 | up(&ide_setting_sem); | 1892 | up(&ide_setting_sem); |
| 2073 | spin_lock(&drives_lock); | ||
| 2074 | list_del_init(&drive->list); | ||
| 2075 | spin_unlock(&drives_lock); | ||
| 2076 | /* drive will be added to &ide_drives in ata_attach() */ | ||
| 2077 | return 0; | ||
| 2078 | } | 1893 | } |
| 2079 | 1894 | ||
| 2080 | EXPORT_SYMBOL(ide_unregister_subdriver); | 1895 | EXPORT_SYMBOL(ide_unregister_subdriver); |
| 2081 | 1896 | ||
| 2082 | static int ide_drive_remove(struct device * dev) | ||
| 2083 | { | ||
| 2084 | ide_drive_t * drive = container_of(dev,ide_drive_t,gendev); | ||
| 2085 | DRIVER(drive)->cleanup(drive); | ||
| 2086 | return 0; | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | /** | ||
| 2090 | * ide_register_driver - register IDE device driver | ||
| 2091 | * @driver: the IDE device driver | ||
| 2092 | * | ||
| 2093 | * Register a new device driver and then scan the devices | ||
| 2094 | * on the IDE bus in case any should be attached to the | ||
| 2095 | * driver we have just registered. If so attach them. | ||
| 2096 | * | ||
| 2097 | * Takes drivers_lock and drives_lock. | ||
| 2098 | */ | ||
| 2099 | |||
| 2100 | int ide_register_driver(ide_driver_t *driver) | ||
| 2101 | { | ||
| 2102 | struct list_head list; | ||
| 2103 | struct list_head *list_loop; | ||
| 2104 | struct list_head *tmp_storage; | ||
| 2105 | |||
| 2106 | spin_lock(&drivers_lock); | ||
| 2107 | list_add(&driver->drivers, &drivers); | ||
| 2108 | spin_unlock(&drivers_lock); | ||
| 2109 | |||
| 2110 | INIT_LIST_HEAD(&list); | ||
| 2111 | spin_lock(&drives_lock); | ||
| 2112 | list_splice_init(&ide_drives, &list); | ||
| 2113 | spin_unlock(&drives_lock); | ||
| 2114 | |||
| 2115 | list_for_each_safe(list_loop, tmp_storage, &list) { | ||
| 2116 | ide_drive_t *drive = container_of(list_loop, ide_drive_t, list); | ||
| 2117 | list_del_init(&drive->list); | ||
| 2118 | if (drive->present) | ||
| 2119 | ata_attach(drive); | ||
| 2120 | } | ||
| 2121 | driver->gen_driver.name = (char *) driver->name; | ||
| 2122 | driver->gen_driver.bus = &ide_bus_type; | ||
| 2123 | driver->gen_driver.remove = ide_drive_remove; | ||
| 2124 | return driver_register(&driver->gen_driver); | ||
| 2125 | } | ||
| 2126 | |||
| 2127 | EXPORT_SYMBOL(ide_register_driver); | ||
| 2128 | |||
| 2129 | /** | ||
| 2130 | * ide_unregister_driver - unregister IDE device driver | ||
| 2131 | * @driver: the IDE device driver | ||
| 2132 | * | ||
| 2133 | * Called when a driver module is being unloaded. We reattach any | ||
| 2134 | * devices to whatever driver claims them next (typically the default | ||
| 2135 | * driver). | ||
| 2136 | * | ||
| 2137 | * Takes drivers_lock and called functions will take ide_setting_sem. | ||
| 2138 | */ | ||
| 2139 | |||
| 2140 | void ide_unregister_driver(ide_driver_t *driver) | ||
| 2141 | { | ||
| 2142 | ide_drive_t *drive; | ||
| 2143 | |||
| 2144 | spin_lock(&drivers_lock); | ||
| 2145 | list_del(&driver->drivers); | ||
| 2146 | spin_unlock(&drivers_lock); | ||
| 2147 | |||
| 2148 | driver_unregister(&driver->gen_driver); | ||
| 2149 | |||
| 2150 | while(!list_empty(&driver->drives)) { | ||
| 2151 | drive = list_entry(driver->drives.next, ide_drive_t, list); | ||
| 2152 | if (driver->cleanup(drive)) { | ||
| 2153 | printk(KERN_ERR "%s: cleanup_module() called while still busy\n", drive->name); | ||
| 2154 | BUG(); | ||
| 2155 | } | ||
| 2156 | ata_attach(drive); | ||
| 2157 | } | ||
| 2158 | } | ||
| 2159 | |||
| 2160 | EXPORT_SYMBOL(ide_unregister_driver); | ||
| 2161 | |||
| 2162 | /* | 1897 | /* |
| 2163 | * Probe module | 1898 | * Probe module |
| 2164 | */ | 1899 | */ |
| 2165 | 1900 | ||
| 2166 | EXPORT_SYMBOL(ide_lock); | 1901 | EXPORT_SYMBOL(ide_lock); |
| 2167 | 1902 | ||
| 1903 | static int ide_bus_match(struct device *dev, struct device_driver *drv) | ||
| 1904 | { | ||
| 1905 | return 1; | ||
| 1906 | } | ||
| 1907 | |||
| 2168 | struct bus_type ide_bus_type = { | 1908 | struct bus_type ide_bus_type = { |
| 2169 | .name = "ide", | 1909 | .name = "ide", |
| 1910 | .match = ide_bus_match, | ||
| 2170 | .suspend = generic_ide_suspend, | 1911 | .suspend = generic_ide_suspend, |
| 2171 | .resume = generic_ide_resume, | 1912 | .resume = generic_ide_resume, |
| 2172 | }; | 1913 | }; |
| 2173 | 1914 | ||
| 1915 | EXPORT_SYMBOL_GPL(ide_bus_type); | ||
| 1916 | |||
| 2174 | /* | 1917 | /* |
| 2175 | * This is gets invoked once during initialization, to set *everything* up | 1918 | * This is gets invoked once during initialization, to set *everything* up |
| 2176 | */ | 1919 | */ |
