📄 gdth.c
字号:
} else {#if LINUX_VERSION_CODE >= 0x020168 mdelay(milliseconds);#else int i; for (i = 0; i < milliseconds; ++i) udelay(1000);#endif }}static void gdth_eval_mapping(ulong32 size, int *cyls, int *heads, int *secs){ *cyls = size /HEADS/SECS; if (*cyls <= MAXCYLS) { *heads = HEADS; *secs = SECS; } else { /* too high for 64*32 */ *cyls = size /MEDHEADS/MEDSECS; if (*cyls <= MAXCYLS) { *heads = MEDHEADS; *secs = MEDSECS; } else { /* too high for 127*63 */ *cyls = size /BIGHEADS/BIGSECS; *heads = BIGHEADS; *secs = BIGSECS; } }}/* controller search and initialization functions */GDTH_INITFUNC(static int, gdth_search_eisa(ushort eisa_adr)){ ulong32 id; TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr)); id = inl(eisa_adr+ID0REG); if (id == GDT3A_ID || id == GDT3B_ID) { /* GDT3000A or GDT3000B */ if ((inb(eisa_adr+EISAREG) & 8) == 0) return 0; /* not EISA configured */ return 1; } if (id == GDT3_ID) /* GDT3000 */ return 1; return 0; }GDTH_INITFUNC(static int, gdth_search_isa(ulong32 bios_adr)){ void *addr; ulong32 id; TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr)); if ((addr = gdth_mmap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) { id = gdth_readl(addr); gdth_munmap(addr); if (id == GDT2_ID) /* GDT2000 */ return 1; } return 0;}GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr)){ ushort device, cnt; TRACE(("gdth_search_pci()\n")); cnt = 0; for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device) gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device); for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP; device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device) gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device); gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, PCI_DEVICE_ID_VORTEX_GDTNEWRX); gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SRC); return cnt;}#if LINUX_VERSION_CODE >= 0x20363/* Vortex only makes RAID controllers. * We do not really want to specify all 550 ids here, so wildcard match. */static struct pci_device_id gdthtable[] = { {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID }, {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID }, {0}};MODULE_DEVICE_TABLE(pci,gdthtable);#endifGDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, ushort vendor, ushort device)){ ulong base0, base1, base2;#if LINUX_VERSION_CODE >= 0x2015C struct pci_dev *pdev;#else int error; ushort idx;#endif TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n", *cnt, vendor, device));#if LINUX_VERSION_CODE >= 0x20363 pdev = NULL; while ((pdev = pci_find_device(vendor, device, pdev)) != NULL) { if (pci_enable_device(pdev)) continue; if (*cnt >= MAXHA) return; /* GDT PCI controller found, resources are already in pdev */ pcistr[*cnt].pdev = pdev; pcistr[*cnt].vendor_id = vendor; pcistr[*cnt].device_id = device; pcistr[*cnt].subdevice_id = pdev->subsystem_device; pcistr[*cnt].bus = pdev->bus->number; pcistr[*cnt].device_fn = pdev->devfn; pcistr[*cnt].irq = pdev->irq; base0 = pci_resource_flags(pdev, 0); base1 = pci_resource_flags(pdev, 1); base2 = pci_resource_flags(pdev, 2); if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ if (!(base0 & IORESOURCE_MEM)) continue; pcistr[*cnt].dpmem = pci_resource_start(pdev, 0); } else { /* GDT6110, GDT6120, .. */ if (!(base0 & IORESOURCE_MEM) || !(base2 & IORESOURCE_MEM) || !(base1 & IORESOURCE_IO)) continue; pcistr[*cnt].dpmem = pci_resource_start(pdev, 2); pcistr[*cnt].io_mm = pci_resource_start(pdev, 0); pcistr[*cnt].io = pci_resource_start(pdev, 1); } TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), pcistr[*cnt].irq, pcistr[*cnt].dpmem)); (*cnt)++; } #elif LINUX_VERSION_CODE >= 0x2015C pdev = NULL; while ((pdev = pci_find_device(vendor, device, pdev)) != NULL) { if (*cnt >= MAXHA) return; /* GDT PCI controller found, resources are already in pdev */ pcistr[*cnt].pdev = pdev; pcistr[*cnt].vendor_id = vendor; pcistr[*cnt].device_id = device; pcistr[*cnt].bus = pdev->bus->number; pcistr[*cnt].device_fn = pdev->devfn; pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn, PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id); pcistr[*cnt].irq = pdev->irq; base0 = pdev->base_address[0]; base1 = pdev->base_address[1]; base2 = pdev->base_address[2]; if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ if ((base0 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) continue; pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK; } else { /* GDT6110, GDT6120, .. */ if ((base0 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY || (base2 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY || (base1 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) continue; pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK; pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK; pcistr[*cnt].io = base1 & PCI_BASE_ADDRESS_IO_MASK; } TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), pcistr[*cnt].irq, pcistr[*cnt].dpmem)); (*cnt)++; } #else idx = 0; while (!pcibios_find_device(vendor, device, idx++, &pcistr[*cnt].bus,&pcistr[*cnt].device_fn)) { if (*cnt >= MAXHA) return; /* GDT PCI ctr. found, now read resources from config space */#if LINUX_VERSION_CODE >= 0x010300#define GDTH_BASEP (int *)#else#define GDTH_BASEP#endif if ((error = pcibios_read_config_dword(pcistr[*cnt].bus, pcistr[*cnt].device_fn, PCI_BASE_ADDRESS_0, GDTH_BASEP&base0)) || (error = pcibios_read_config_dword(pcistr[*cnt].bus, pcistr[*cnt].device_fn, PCI_BASE_ADDRESS_1, GDTH_BASEP&base1)) || (error = pcibios_read_config_dword(pcistr[*cnt].bus, pcistr[*cnt].device_fn, PCI_BASE_ADDRESS_2, GDTH_BASEP&base2)) || (error = pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn, PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id)) || (error = pcibios_read_config_byte(pcistr[*cnt].bus, pcistr[*cnt].device_fn, PCI_INTERRUPT_LINE, &pcistr[*cnt].irq))) { printk("GDT-PCI: error %d reading configuration space", error); continue; } pcistr[*cnt].vendor_id = vendor; pcistr[*cnt].device_id = device; if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ if ((base0 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) continue; pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK; } else { /* GDT6110, GDT6120, .. */ if ((base0 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY || (base2 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY || (base1 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO) continue; pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK; pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK; pcistr[*cnt].io = base1 & PCI_BASE_ADDRESS_IO_MASK; } TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), pcistr[*cnt].irq, pcistr[*cnt].dpmem)); (*cnt)++; }#endif} GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt)){ gdth_pci_str temp; int i, changed; TRACE(("gdth_sort_pci() cnt %d\n",cnt)); if (cnt == 0) return; do { changed = FALSE; for (i = 0; i < cnt-1; ++i) { if (!reverse_scan) { if ((pcistr[i].bus > pcistr[i+1].bus) || (pcistr[i].bus == pcistr[i+1].bus && PCI_SLOT(pcistr[i].device_fn) > PCI_SLOT(pcistr[i+1].device_fn))) { temp = pcistr[i]; pcistr[i] = pcistr[i+1]; pcistr[i+1] = temp; changed = TRUE; } } else { if ((pcistr[i].bus < pcistr[i+1].bus) || (pcistr[i].bus == pcistr[i+1].bus && PCI_SLOT(pcistr[i].device_fn) < PCI_SLOT(pcistr[i+1].device_fn))) { temp = pcistr[i]; pcistr[i] = pcistr[i+1]; pcistr[i+1] = temp; changed = TRUE; } } } } while (changed);}GDTH_INITFUNC(static int, gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)){ ulong32 retries,id; unchar prot_ver,eisacf,i,irq_found; TRACE(("gdth_init_eisa() adr. %x\n",eisa_adr)); /* disable board interrupts, deinitialize services */ outb(0xff,eisa_adr+EDOORREG); outb(0x00,eisa_adr+EDENABREG); outb(0x00,eisa_adr+EINTENABREG); outb(0xff,eisa_adr+LDOORREG); retries = INIT_RETRIES; gdth_delay(20); while (inb(eisa_adr+EDOORREG) != 0xff) { if (--retries == 0) { printk("GDT-EISA: Initialization error (DEINIT failed)\n"); return 0; } gdth_delay(1); TRACE2(("wait for DEINIT: retries=%d\n",retries)); } prot_ver = inb(eisa_adr+MAILBOXREG); outb(0xff,eisa_adr+EDOORREG); if (prot_ver != PROTOCOL_VERSION) { printk("GDT-EISA: Illegal protocol version\n"); return 0; } ha->bmic = eisa_adr; ha->brd_phys = (ulong32)eisa_adr >> 12; outl(0,eisa_adr+MAILBOXREG); outl(0,eisa_adr+MAILBOXREG+4); outl(0,eisa_adr+MAILBOXREG+8); outl(0,eisa_adr+MAILBOXREG+12); /* detect IRQ */ if ((id = inl(eisa_adr+ID0REG)) == GDT3_ID) { ha->oem_id = OEM_ID_ICP; ha->type = GDT_EISA; ha->stype = id; outl(1,eisa_adr+MAILBOXREG+8); outb(0xfe,eisa_adr+LDOORREG); retries = INIT_RETRIES; gdth_delay(20); while (inb(eisa_adr+EDOORREG) != 0xfe) { if (--retries == 0) { printk("GDT-EISA: Initialization error (get IRQ failed)\n"); return 0; } gdth_delay(1); } ha->irq = inb(eisa_adr+MAILBOXREG); outb(0xff,eisa_adr+EDOORREG); TRACE2(("GDT3000/3020: IRQ=%d\n",ha->irq)); /* check the result */ if (ha->irq == 0) { TRACE2(("Unknown IRQ, use IRQ table from cmd line !\n")); for (i = 0, irq_found = FALSE; i < MAXHA && irq[i] != 0xff; ++i) { if (irq[i]==10 || irq[i]==11 || irq[i]==12 || irq[i]==14) { irq_found = TRUE; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -