📄 ide.c
字号:
* "hdx=noremap" : do not remap 0->1 even though EZD was detected * "hdx=autotune" : driver will attempt to tune interface speed * to the fastest PIO mode supported, * if possible for this drive only. * Not fully supported by all chipset types, * and quite likely to cause trouble with * older/odd IDE drives. * * "hdx=slow" : insert a huge pause after each access to the data * port. Should be used only as a last resort. * * "hdx=swapdata" : when the drive is a disk, byte swap all data * "hdx=bswap" : same as above.......... * "hdxlun=xx" : set the drive last logical unit. * "hdx=flash" : allows for more than one ata_flash disk to be * registered. In most cases, only one device * will be present. * "hdx=scsi" : the return of the ide-scsi flag, this is useful for * allowwing ide-floppy, ide-tape, and ide-cdrom|writers * to use ide-scsi emulation on a device specific option. * "idebus=xx" : inform IDE driver of VESA/PCI bus speed in MHz, * where "xx" is between 20 and 66 inclusive, * used when tuning chipset PIO modes. * For PCI bus, 25 is correct for a P75 system, * 30 is correct for P90,P120,P180 systems, * and 33 is used for P100,P133,P166 systems. * If in doubt, use idebus=33 for PCI. * As for VLB, it is safest to not specify it. * * "idex=noprobe" : do not attempt to access/use this interface * "idex=base" : probe for an interface at the addr specified, * where "base" is usually 0x1f0 or 0x170 * and "ctl" is assumed to be "base"+0x206 * "idex=base,ctl" : specify both base and ctl * "idex=base,ctl,irq" : specify base, ctl, and irq number * "idex=autotune" : driver will attempt to tune interface speed * to the fastest PIO mode supported, * for all drives on this interface. * Not fully supported by all chipset types, * and quite likely to cause trouble with * older/odd IDE drives. * "idex=noautotune" : driver will NOT attempt to tune interface speed * This is the default for most chipsets, * except the cmd640. * "idex=serialize" : do not overlap operations on idex and ide(x^1) * "idex=four" : four drives on idex and ide(x^1) share same ports * "idex=reset" : reset interface before first use * "idex=dma" : enable DMA by default on both drives if possible * "idex=ata66" : informs the interface that it has an 80c cable * for chipsets that are ATA-66 capable, but * the ablity to bit test for detection is * currently unknown. * "ide=reverse" : Formerly called to pci sub-system, but now local. * * The following are valid ONLY on ide0, (except dc4030) * and the defaults for the base,ctl ports must not be altered. * * "ide0=dtc2278" : probe/support DTC2278 interface * "ide0=ht6560b" : probe/support HT6560B interface * "ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip * (not for PCI -- automatically detected) * "ide0=qd65xx" : probe/support qd65xx interface * "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439, M1443, M1445) * "ide0=umc8672" : probe/support umc8672 chipsets * "idex=dc4030" : probe/support Promise DC4030VL interface * "ide=doubler" : probe/support IDE doublers on Amiga */int __init ide_setup (char *s){ int i, vals[3]; ide_hwif_t *hwif; ide_drive_t *drive; unsigned int hw, unit; const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1); const char max_hwif = '0' + (MAX_HWIFS - 1); if (strncmp(s,"hd",2) == 0 && s[2] == '=') /* hd= is for hd.c */ return 0; /* driver and not us */ if (strncmp(s,"ide",3) && strncmp(s,"idebus",6) && strncmp(s,"hd",2)) /* hdx= & hdxlun= */ return 0; printk(KERN_INFO "ide_setup: %s", s); init_ide_data ();#ifdef CONFIG_BLK_DEV_IDEDOUBLER if (!strcmp(s, "ide=doubler")) { extern int ide_doubler; printk(" : Enabled support for IDE doublers\n"); ide_doubler = 1; return 1; }#endif /* CONFIG_BLK_DEV_IDEDOUBLER */ if (!strcmp(s, "ide=nodma")) { printk(" : Prevented DMA\n"); noautodma = 1; return 1; }#ifdef CONFIG_BLK_DEV_IDEPCI if (!strcmp(s, "ide=reverse")) { ide_scan_direction = 1; printk(" : Enabled support for IDE inverse scan order.\n"); return 1; }#endif /* CONFIG_BLK_DEV_IDEPCI */ /* * Look for drive options: "hdx=" */ if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom", "serialize", "autotune", "noautotune", "slow", "swapdata", "bswap", "flash", "remap", "noremap", "scsi", NULL}; unit = s[2] - 'a'; hw = unit / MAX_DRIVES; unit = unit % MAX_DRIVES; hwif = &ide_hwifs[hw]; drive = &hwif->drives[unit]; if (strncmp(s + 4, "ide-", 4) == 0) { strncpy(drive->driver_req, s + 4, 9); goto done; } /* * Look for last lun option: "hdxlun=" */ if (s[3] == 'l' && s[4] == 'u' && s[5] == 'n') { if (match_parm(&s[6], NULL, vals, 1) != 1) goto bad_option; if (vals[0] >= 0 && vals[0] <= 7) { drive->last_lun = vals[0]; drive->forced_lun = 1; } else printk(" -- BAD LAST LUN! Expected value from 0 to 7"); goto done; } switch (match_parm(&s[3], hd_words, vals, 3)) { case -1: /* "none" */ drive->nobios = 1; /* drop into "noprobe" */ case -2: /* "noprobe" */ drive->noprobe = 1; goto done; case -3: /* "nowerr" */ drive->bad_wstat = BAD_R_STAT; hwif->noprobe = 0; goto done; case -4: /* "cdrom" */ drive->present = 1; drive->media = ide_cdrom; hwif->noprobe = 0; goto done; case -5: /* "serialize" */ printk(" -- USE \"ide%d=serialize\" INSTEAD", hw); goto do_serialize; case -6: /* "autotune" */ drive->autotune = 1; goto done; case -7: /* "noautotune" */ drive->autotune = 2; goto done; case -8: /* "slow" */ drive->slow = 1; goto done; case -9: /* "swapdata" or "bswap" */ case -10: drive->bswap = 1; goto done; case -11: /* "flash" */ drive->ata_flash = 1; goto done; case -12: /* "remap" */ drive->remap_0_to_1 = 1; goto done; case -13: /* "noremap" */ drive->remap_0_to_1 = 2; goto done; case -14: /* "scsi" */ drive->scsi = 1; goto done; 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 for future idex calls to ease the hardcoding. */ 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: */ if (i > 0 || i <= -11) { /* is parameter a chipset name? */ if (hwif->chipset != ide_unknown) goto bad_option; /* chipset already specified */ if (i <= -11 && i != -18 && hw != 0) goto bad_hwif; /* chipset drivers are for "ide0=" only */ if (i <= -11 && i != -18 && ide_hwifs[hw+1].chipset != ide_unknown) goto bad_option; /* chipset for 2nd port already specified */ printk("\n"); } switch (i) {#ifdef CONFIG_BLK_DEV_PDC4030 case -18: /* "dc4030" */ { extern void init_pdc4030(void); init_pdc4030(); goto done; }#endif /* CONFIG_BLK_DEV_PDC4030 */#ifdef CONFIG_BLK_DEV_ALI14XX case -17: /* "ali14xx" */ { extern void init_ali14xx (void); init_ali14xx(); goto done; }#endif /* CONFIG_BLK_DEV_ALI14XX */#ifdef CONFIG_BLK_DEV_UMC8672 case -16: /* "umc8672" */ { extern void init_umc8672 (void); init_umc8672(); goto done; }#endif /* CONFIG_BLK_DEV_UMC8672 */#ifdef CONFIG_BLK_DEV_DTC2278 case -15: /* "dtc2278" */ { extern void init_dtc2278 (void); init_dtc2278(); goto done; }#endif /* CONFIG_BLK_DEV_DTC2278 */#ifdef CONFIG_BLK_DEV_CMD640 case -14: /* "cmd640_vlb" */ { extern int cmd640_vlb; /* flag for cmd640.c */ cmd640_vlb = 1; goto done; }#endif /* CONFIG_BLK_DEV_CMD640 */#ifdef CONFIG_BLK_DEV_HT6560B case -13: /* "ht6560b" */ { extern void init_ht6560b (void); init_ht6560b(); goto done; }#endif /* CONFIG_BLK_DEV_HT6560B */#if CONFIG_BLK_DEV_QD65XX case -12: /* "qd65xx" */ { extern void init_qd65xx (void); init_qd65xx(); goto done; }#endif /* CONFIG_BLK_DEV_QD65XX */#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 /* !CONFIG_BLK_DEV_IDEPCI */ hwif->udma_four = 0; goto bad_hwif;#endif /* CONFIG_BLK_DEV_IDEPCI */ case -6: /* dma */ hwif->autodma = 1; goto done; case -5: /* "reset" */ hwif->reset = 1; goto done; case -4: /* "noautotune" */ hwif->drives[0].autotune = 2; hwif->drives[1].autotune = 2; goto done; case -3: /* "autotune" */ hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; 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, (ide_ioreg_t) vals[0], (ide_ioreg_t) 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_generic; 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;}/* * probe_for_hwifs() finds/initializes "known" IDE interfaces */static void __init probe_for_hwifs (void){#ifdef CONFIG_BLK_DEV_IDEPCI if (pci_present()) { 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 ide_probe_for_pdc4030(void); (void) ide_probe_for_pdc4030(); }#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_IDE_SIBYTE { extern void sibyte_ide_probe(void); sibyte_ide_probe(); }#endif /* CONFIG_BLK_DEV_IDE_SIBYTE */#ifdef CONFIG_BLK_DEV_IDE_ICSIDE { extern void icside_init(void); icside_init(); }#endif /* CONFIG_BLK_DEV_IDE_ICSIDE */#ifdef CONFIG_BLK_DEV_IDE_RAPIDE { extern void rapide_init(void); rapide_init(); }#endif /* CONFIG_BLK_DEV_IDE_RAPIDE */#ifdef CONFIG_BLK_DEV_IDE_RISCSTATION { extern void rside_init(void); rside_init(); }#endif /* CONFIG_BLK_DEV_IDE_RISCSTATION */#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_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -