📄 ide.c
字号:
case 3: /* cyl,head,sect */ drive->media = ide_disk; drive->cyl = drive->bios_cyl = vals[0]; drive->head = drive->bios_head = vals[1]; drive->sect = drive->bios_sect = vals[2]; drive->present = 1; drive->forced_geom = 1; hwif->noprobe = 0; goto done; default: goto bad_option; } } if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e') goto bad_option; /* * Look for bus speed option: "idebus=" */ if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') { if (match_parm(&s[6], NULL, vals, 1) != 1) goto bad_option; if (vals[0] >= 20 && vals[0] <= 66) { idebus_parameter = vals[0]; } else printk(" -- BAD BUS SPEED! Expected value from 20 to 66"); goto done; } /* * Look for interface options: "idex=" */ if (s[3] >= '0' && s[3] <= max_hwif) { /* * Be VERY CAREFUL changing this: note hardcoded indexes below * (-8, -9, -10) are reserved to ease the hardcoding. */ static const char *ide_words[] = { "noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66", "minus8", "minus9", "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL }; hw = s[3] - '0'; hwif = &ide_hwifs[hw]; i = match_parm(&s[4], ide_words, vals, 3); /* * Cryptic check to ensure chipset not already set for hwif. * Note: we can't depend on hwif->chipset here. */ if ((i >= -18 && i <= -11) || (i > 0 && i <= 3)) { /* chipset already specified */ if (is_chipset_set[hw]) goto bad_option; if (i > -18 && i <= -11) { /* these drivers are for "ide0=" only */ if (hw != 0) goto bad_hwif; /* chipset already specified for 2nd port */ if (is_chipset_set[hw+1]) goto bad_option; } is_chipset_set[hw] = 1; printk("\n"); } switch (i) {#ifdef CONFIG_BLK_DEV_PDC4030 case -18: /* "dc4030" */ probe_pdc4030 = 1; goto done;#endif#ifdef CONFIG_BLK_DEV_ALI14XX case -17: /* "ali14xx" */ probe_ali14xx = 1; goto done;#endif#ifdef CONFIG_BLK_DEV_UMC8672 case -16: /* "umc8672" */ probe_umc8672 = 1; goto done;#endif#ifdef CONFIG_BLK_DEV_DTC2278 case -15: /* "dtc2278" */ probe_dtc2278 = 1; goto done;#endif#ifdef CONFIG_BLK_DEV_CMD640 case -14: /* "cmd640_vlb" */ { extern int cmd640_vlb; /* flag for cmd640.c */ cmd640_vlb = 1; goto done; }#endif#ifdef CONFIG_BLK_DEV_HT6560B case -13: /* "ht6560b" */ probe_ht6560b = 1; goto done;#endif#ifdef CONFIG_BLK_DEV_QD65XX case -12: /* "qd65xx" */ probe_qd65xx = 1; goto done;#endif#ifdef CONFIG_BLK_DEV_4DRIVES case -11: /* "four" drives on one set of ports */ { ide_hwif_t *mate = &ide_hwifs[hw^1]; mate->drives[0].select.all ^= 0x20; mate->drives[1].select.all ^= 0x20; hwif->chipset = mate->chipset = ide_4drives; mate->irq = hwif->irq; memcpy(mate->io_ports, hwif->io_ports, sizeof(hwif->io_ports)); goto do_serialize; }#endif /* CONFIG_BLK_DEV_4DRIVES */ case -10: /* minus10 */ case -9: /* minus9 */ case -8: /* minus8 */ goto bad_option; case -7: /* ata66 */#ifdef CONFIG_BLK_DEV_IDEPCI hwif->udma_four = 1; goto done;#else goto bad_hwif;#endif case -6: /* dma */ hwif->autodma = 1; goto done; case -5: /* "reset" */ hwif->reset = 1; goto done; case -4: /* "noautotune" */ hwif->drives[0].autotune = IDE_TUNE_NOAUTO; hwif->drives[1].autotune = IDE_TUNE_NOAUTO; goto done; case -3: /* "autotune" */ hwif->drives[0].autotune = IDE_TUNE_AUTO; hwif->drives[1].autotune = IDE_TUNE_AUTO; goto done; case -2: /* "serialize" */ do_serialize: hwif->mate = &ide_hwifs[hw^1]; hwif->mate->mate = hwif; hwif->serialized = hwif->mate->serialized = 1; goto done; case -1: /* "noprobe" */ hwif->noprobe = 1; goto done; case 1: /* base */ vals[1] = vals[0] + 0x206; /* default ctl */ case 2: /* base,ctl */ vals[2] = 0; /* default irq = probe for it */ case 3: /* base,ctl,irq */ hwif->hw.irq = vals[2]; ide_init_hwif_ports(&hwif->hw, (unsigned long) vals[0], (unsigned long) vals[1], &hwif->irq); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->irq = vals[2]; hwif->noprobe = 0; hwif->chipset = ide_forced; goto done; case 0: goto bad_option; default: printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n"); return 1; } }bad_option: printk(" -- BAD OPTION\n"); return 1;bad_hwif: printk("-- NOT SUPPORTED ON ide%d", hw);done: printk("\n"); return 1;}extern void pnpide_init(void);extern void h8300_ide_init(void);/* * probe_for_hwifs() finds/initializes "known" IDE interfaces */static void __init probe_for_hwifs (void){#ifdef CONFIG_BLK_DEV_IDEPCI ide_scan_pcibus(ide_scan_direction);#endif /* CONFIG_BLK_DEV_IDEPCI */#ifdef CONFIG_ETRAX_IDE { extern void init_e100_ide(void); init_e100_ide(); }#endif /* CONFIG_ETRAX_IDE */#ifdef CONFIG_BLK_DEV_CMD640 { extern void ide_probe_for_cmd640x(void); ide_probe_for_cmd640x(); }#endif /* CONFIG_BLK_DEV_CMD640 */#ifdef CONFIG_BLK_DEV_PDC4030 { extern int pdc4030_init(void); if (probe_pdc4030) (void)pdc4030_init(); }#endif /* CONFIG_BLK_DEV_PDC4030 */#ifdef CONFIG_BLK_DEV_IDE_PMAC { extern void pmac_ide_probe(void); pmac_ide_probe(); }#endif /* CONFIG_BLK_DEV_IDE_PMAC */#ifdef CONFIG_BLK_DEV_GAYLE { extern void gayle_init(void); gayle_init(); }#endif /* CONFIG_BLK_DEV_GAYLE */#ifdef CONFIG_BLK_DEV_FALCON_IDE { extern void falconide_init(void); falconide_init(); }#endif /* CONFIG_BLK_DEV_FALCON_IDE */#ifdef CONFIG_BLK_DEV_MAC_IDE { extern void macide_init(void); macide_init(); }#endif /* CONFIG_BLK_DEV_MAC_IDE */#ifdef CONFIG_BLK_DEV_Q40IDE { extern void q40ide_init(void); q40ide_init(); }#endif /* CONFIG_BLK_DEV_Q40IDE */#ifdef CONFIG_BLK_DEV_BUDDHA { extern void buddha_init(void); buddha_init(); }#endif /* CONFIG_BLK_DEV_BUDDHA */#ifdef CONFIG_BLK_DEV_IDEPNP pnpide_init();#endif#ifdef CONFIG_H8300 h8300_ide_init();#endif}/* * Actually unregister the subdriver. Called with the * request lock dropped. */ static int default_cleanup (ide_drive_t *drive){ return ide_unregister_subdriver(drive);}static ide_startstop_t default_do_request (ide_drive_t *drive, struct request *rq, sector_t block){ ide_end_request(drive, 0, 0); return ide_stopped;}static int default_end_request (ide_drive_t *drive, int uptodate, int nr_sects){ return ide_end_request(drive, uptodate, nr_sects);}static u8 default_sense (ide_drive_t *drive, const char *msg, u8 stat){ return ide_dump_status(drive, msg, stat);}static ide_startstop_t default_error (ide_drive_t *drive, const char *msg, u8 stat){ return ide_error(drive, msg, stat);}static void default_pre_reset (ide_drive_t *drive){}static sector_t default_capacity (ide_drive_t *drive){ return 0x7fffffff;}static ide_startstop_t default_special (ide_drive_t *drive){ special_t *s = &drive->special; s->all = 0; drive->mult_req = 0; return ide_stopped;}static int default_attach (ide_drive_t *drive){ printk(KERN_ERR "%s: does not support hotswap of device class !\n", drive->name); return 0;}static ide_startstop_t default_abort (ide_drive_t *drive, const char *msg){ return ide_abort(drive, msg);}static ide_startstop_t default_start_power_step(ide_drive_t *drive, struct request *rq){ rq->pm->pm_step = ide_pm_state_completed; return ide_stopped;}static void setup_driver_defaults (ide_driver_t *d){ if (d->cleanup == NULL) d->cleanup = default_cleanup; if (d->do_request == NULL) d->do_request = default_do_request; if (d->end_request == NULL) d->end_request = default_end_request; if (d->sense == NULL) d->sense = default_sense; if (d->error == NULL) d->error = default_error; if (d->abort == NULL) d->abort = default_abort; if (d->pre_reset == NULL) d->pre_reset = default_pre_reset; if (d->capacity == NULL) d->capacity = default_capacity; if (d->special == NULL) d->special = default_special; if (d->attach == NULL) d->attach = default_attach; if (d->start_power_step == NULL) d->start_power_step = default_start_power_step;}int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver){ unsigned long flags; BUG_ON(!drive->driver); spin_lock_irqsave(&ide_lock, flags); if (!drive->present || drive->driver != &idedefault_driver || drive->usage || drive->dead) { spin_unlock_irqrestore(&ide_lock, flags); return 1; } drive->driver = driver; spin_unlock_irqrestore(&ide_lock, flags); spin_lock(&drives_lock); list_add_tail(&drive->list, &driver->drives); spin_unlock(&drives_lock);// printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name); if ((drive->autotune == IDE_TUNE_DEFAULT) || (drive->autotune == IDE_TUNE_AUTO)) { /* DMA timings and setup moved to ide-probe.c */ drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap); drive->nice1 = 1; } drive->suspend_reset = 0;#ifdef CONFIG_PROC_FS if (drive->driver != &idedefault_driver) { ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive); ide_add_proc_entries(drive->proc, driver->proc, drive); }#endif return 0;}EXPORT_SYMBOL(ide_register_subdriver);/** * ide_unregister_subdriver - disconnect drive from driver * @drive: drive to unplug * * Disconnect a drive from the driver it was attached to and then * clean up the various proc files and other objects attached to it. * * Takes ide_setting_sem, ide_lock and drives_lock. * Caller must hold none of the locks. * * No locking versus subdriver unload because we are moving to the * default driver anyway. Wants double checking. */int ide_unregister_subdriver (ide_drive_t *drive){ unsigned long flags; down(&ide_setting_sem); spin_lock_irqsave(&ide_lock, flags); if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) { spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); return 1; }#ifdef CONFIG_PROC_FS ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc); ide_remove_proc_entries(drive->proc, generic_subdriver_entries);#endif auto_remove_settings(drive); drive->driver = &idedefault_driver; spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); spin_lock(&drives_lock); list_del_init(&drive->list); spin_unlock(&drives_lock); /* drive will be added to &idedefault_driver->drives in ata_attach() */ return 0;}EXPORT_SYMBOL(ide_unregister_subdriver);static int ide_drive_remove(struct device * dev){ ide_drive_t * drive = container_of(dev,ide_drive_t,gendev); DRIVER(drive)->cleanup(drive); return 0;}/** * ide_register_driver - register IDE device driver * @driver: the IDE device driver * * Register a new device driver and then scan the devices * on the IDE bus in case any should be attached to the * driver we have just registered. If so attach them. * * Takes drivers_lock and drives_lock. */int ide_register_driver(ide_driver_t *driver){ struct list_head list; struct list_head *list_loop; struct list_head *tmp_storage; setup_driver_defaults(driver); spin_lock(&drivers_lock); list_add(&driver->drivers, &drivers); spin_unlock(&drivers_lock); INIT_LIST_HEAD(&list); spin_lock(&drives_lock); list_splice_init(&idedefault_driver.drives, &list); spin_unlock(&drives_lock); list_for_each_safe(list_loop, tmp_storage, &list) { ide_drive_t *drive = container_of(list_loop, ide_drive_t, list); list_del_init(&drive->list); if (drive->present) ata_attach(drive); } driver->gen_driver.name = (char *) driver->name; driver->gen_driver.bus = &ide_bus_type; driver->gen_driver.remove = ide_drive_remove; return driver_register(&driver->gen_driver);}EXPORT_SYMBOL(ide_register_driver);/** * ide_unregister_driver - unregister IDE device driver * @driver: the IDE device driver * * Called when a driver module is being unloaded. We reattach any * devices to whatever dri
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -