📄 ide-pci.c
字号:
/* * linux/drivers/block/ide-pci.c Version 1.02 December 29, 1997 * * Copyright (c) 1995-1998 Mark Lord * May be copied or modified under the terms of the GNU General Public License *//* * This module provides support for automatic detection and * configuration of all PCI IDE interfaces present in a system. */#include <linux/config.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/timer.h>#include <linux/mm.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/init.h>#include <asm/io.h>#include <asm/irq.h>#include "ide.h"#define DEVID_PIIXa ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0})#define DEVID_PIIXb ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1})#define DEVID_PIIX3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1})#define DEVID_PIIX4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB})#define DEVID_PIIX4E ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1})#define DEVID_PIIX4E2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1})#define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1})#define DEVID_PIIX4U2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1})#define DEVID_PIIX4NX ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX})#define DEVID_PIIX4U3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9})#define DEVID_PIIX4U4 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8})#define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1})#define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246})#define DEVID_RZ1000 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000})#define DEVID_RZ1001 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001})#define DEVID_CMD640 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640})#define DEVID_CMD646 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646})#define DEVID_SIS5513 ((ide_pci_devid_t){PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513})#define DEVID_OPTI621 ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621})#define DEVID_OPTI621V ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558})#define DEVID_OPTI621X ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, 0xd568}) /* from datasheets */#define DEVID_TRM290 ((ide_pci_devid_t){PCI_VENDOR_ID_TEKRAM, PCI_DEVICE_ID_TEKRAM_DC290})#define DEVID_NS87410 ((ide_pci_devid_t){PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410})#define DEVID_NS87415 ((ide_pci_devid_t){PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415})#define DEVID_HT6565 ((ide_pci_devid_t){PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565})#define DEVID_AEC6210 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF})#define DEVID_W82C105 ((ide_pci_devid_t){PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105})#define DEVID_UM8886A ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A})#define DEVID_UM8886BF ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF})#define DEVID_HPT343 ((ide_pci_devid_t){PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343})#define IDE_IGNORE ((void *)-1)#ifdef CONFIG_BLK_DEV_TRM290extern void ide_init_trm290(ide_hwif_t *);#define INIT_TRM290 &ide_init_trm290#else#define INIT_TRM290 IDE_IGNORE#endif#ifdef CONFIG_BLK_DEV_OPTI621extern void ide_init_opti621(ide_hwif_t *);#define INIT_OPTI621 &ide_init_opti621#else#define INIT_OPTI621 NULL#endif#ifdef CONFIG_BLK_DEV_NS87415extern void ide_init_ns87415(ide_hwif_t *);#define INIT_NS87415 &ide_init_ns87415#else#define INIT_NS87415 IDE_IGNORE#endif#ifdef CONFIG_BLK_DEV_CMD646extern void ide_init_cmd646(ide_hwif_t *);#define INIT_CMD646 &ide_init_cmd646#else#ifdef __sparc_v9__#define INIT_CMD646 IDE_IGNORE#else#define INIT_CMD646 NULL#endif#endif#ifdef CONFIG_BLK_DEV_SL82C105extern void ide_init_sl82c105(ide_hwif_t *);#define INIT_W82C105 &ide_init_sl82c105#else#define INIT_W82C105 IDE_IGNORE#endif#ifdef CONFIG_BLK_DEV_RZ1000extern void ide_init_rz1000(ide_hwif_t *);#define INIT_RZ1000 &ide_init_rz1000#else#define INIT_RZ1000 IDE_IGNORE#endif#ifdef CONFIG_BLK_DEV_VIA82C586extern void ide_init_via82c586(ide_hwif_t *);#define INIT_VIA82C586 &ide_init_via82c586#else#define INIT_VIA82C586 NULL#endiftypedef struct ide_pci_enablebit_s { byte reg; /* byte pci reg holding the enable-bit */ byte mask; /* mask to isolate the enable-bit */ byte val; /* value of masked reg when "enabled" */} ide_pci_enablebit_t;typedef struct ide_pci_device_s { ide_pci_devid_t devid; const char *name; void (*init_hwif)(ide_hwif_t *hwif); ide_pci_enablebit_t enablebits[2]; byte bootable; unsigned int extra;} ide_pci_device_t;static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_PIIXa, "PIIX", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIXb, "PIIX", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX3, "PIIX3", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4, "PIIX4", NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_VP_IDE, "VP_IDE", INIT_VIA82C586, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, {DEVID_PDC20246,"PDC20246", NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, {DEVID_RZ1000, "RZ1000", INIT_RZ1000, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_RZ1001, "RZ1001", INIT_RZ1000, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_CMD640, "CMD640", IDE_IGNORE, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_NS87410, "NS87410", NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0 }, {DEVID_SIS5513, "SIS5513", NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, ON_BOARD, 0 }, {DEVID_CMD646, "CMD646", INIT_CMD646, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_HT6565, "HT6565", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_OPTI621, "OPTI621", INIT_OPTI621, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, {DEVID_OPTI621X,"OPTI621X", INIT_OPTI621, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, {DEVID_TRM290, "TRM290", INIT_TRM290, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_NS87415, "NS87415", INIT_NS87415, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AEC6210, "AEC6210", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, {DEVID_W82C105, "W82C105", INIT_W82C105, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, {DEVID_UM8886A, "UM8886A", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_UM8886BF,"UM8886BF", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_HPT343, "HPT343", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 16 }, {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }};/* * This allows offboard ide-pci cards the enable a BIOS, verify interrupt * settings of split-mirror pci-config space, place chipset into init-mode, * and/or preserve an interrupt if the card is not native ide support. */__initfunc(static unsigned int ide_special_settings (struct pci_dev *dev, const char *name)){ switch(dev->device) { case PCI_DEVICE_ID_ARTOP_ATP850UF: case PCI_DEVICE_ID_PROMISE_20246: if (dev->rom_address) { pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->rom_address | PCI_ROM_ADDRESS_ENABLE); printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->rom_address); } if ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID) { unsigned char irq1 = 0, irq2 = 0; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq1); pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */ if (irq1 != irq2) { printk("%s: IRQ1 %d IRQ2 %d\n", name, irq1, irq2); pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq1); /* 0xbc */ } } return dev->irq; case PCI_DEVICE_ID_TTI_HPT343: return dev->irq; default: break; } return 0;}/* * Match a PCI IDE port against an entry in ide_hwifs[], * based on io_base port if possible. */__initfunc(static ide_hwif_t *ide_match_hwif (unsigned long io_base, byte bootable, const char *name)){ int h; ide_hwif_t *hwif; /* * Look for a hwif with matching io_base specified using * parameters to ide_setup(). */ for (h = 0; h < MAX_HWIFS; ++h) { hwif = &ide_hwifs[h]; if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) { if (hwif->chipset == ide_generic) return hwif; /* a perfect match */ } } /* * Look for a hwif with matching io_base default value. * If chipset is "ide_unknown", then claim that hwif slot. * Otherwise, some other chipset has already claimed it.. :( */ for (h = 0; h < MAX_HWIFS; ++h) { hwif = &ide_hwifs[h]; if (hwif->io_ports[IDE_DATA_OFFSET] == io_base) { if (hwif->chipset == ide_unknown) return hwif; /* match */ printk("%s: port 0x%04lx already claimed by %s\n", name, io_base, hwif->name); return NULL; /* already claimed */ } } /* * Okay, there is no hwif matching our io_base, * so we'll just claim an unassigned slot. * Give preference to claiming other slots before claiming ide0/ide1, * just in case there's another interface yet-to-be-scanned * which uses ports 1f0/170 (the ide0/ide1 defaults). * * Unless there is a bootable card that does not use the standard * ports 1f0/170 (the ide0/ide1 defaults). The (bootable) flag.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -