📄 eata_dma.c
字号:
sh->can_queue = hd->queuesize = ntohs(gc->queuesiz); sh->cmd_per_lun = 0; } if(sh == NULL) { DBG(DBG_REGISTER, printk(KERN_NOTICE "eata_dma: couldn't register HBA" " at%x \n", base)); scsi_unregister(sh); if (gc->DMA_valid) free_dma(dma_channel); reg_IRQ[gc->IRQ]--; if (reg_IRQ[gc->IRQ] == 0) free_irq(gc->IRQ, NULL); if (gc->IRQ_TR == FALSE) reg_IRQL[gc->IRQ] = FALSE; return (FALSE); } hd->broken_INQUIRY = (bugs & BROKEN_INQUIRY); if(hd->broken_INQUIRY == TRUE) { strcpy(hd->vendor, "DPT"); strcpy(hd->name, "??????????"); strcpy(hd->revision, "???.?"); hd->firmware_revision = 0; } else { strncpy(hd->vendor, &buff[8], 8); hd->vendor[8] = 0; strncpy(hd->name, &buff[16], 17); hd->name[17] = 0; hd->revision[0] = buff[32]; hd->revision[1] = buff[33]; hd->revision[2] = buff[34]; hd->revision[3] = '.'; hd->revision[4] = buff[35]; hd->revision[5] = 0; hd->firmware_revision = (buff[32] << 24) + (buff[33] << 16) + (buff[34] << 8) + buff[35]; } if (hd->firmware_revision >= (('0'<<24) + ('7'<<16) + ('G'<< 8) + '0')) hd->immediate_support = 1; else hd->immediate_support = 0; switch (ntohl(gc->len)) { case 0x1c: hd->EATA_revision = 'a'; break; case 0x1e: hd->EATA_revision = 'b'; break; case 0x22: hd->EATA_revision = 'c'; break; case 0x24: hd->EATA_revision = 'z'; default: hd->EATA_revision = '?'; } if(ntohl(gc->len) >= 0x22) { sh->max_id = gc->MAX_ID + 1; sh->max_lun = gc->MAX_LUN + 1; } else { sh->max_id = 8; sh->max_lun = 8; } hd->HBA_number = sh->host_no; hd->channel = gc->MAX_CHAN; sh->max_channel = gc->MAX_CHAN; sh->unique_id = base; sh->base = (char *) base; sh->io_port = base; sh->n_io_port = 9; sh->irq = gc->IRQ; sh->dma_channel = dma_channel; /* FIXME: * SCSI midlevel code should support different HBA ids on every channel */ sh->this_id = gc->scsi_id[3]; if (gc->SECOND) hd->primary = FALSE; else hd->primary = TRUE; sh->wish_block = FALSE; if (hd->bustype != IS_ISA) { sh->unchecked_isa_dma = FALSE; } else { sh->unchecked_isa_dma = TRUE; /* We're doing ISA DMA */ } for(x = 0; x <= 11; x++){ /* Initialize min. latency */ hd->writes_lat[x][1] = 0xffffffff; hd->reads_lat[x][1] = 0xffffffff; } hd->all_lat[1] = 0xffffffff; hd->next = NULL; /* build a linked list of all HBAs */ hd->prev = last_HBA; if(hd->prev != NULL) SD(hd->prev)->next = sh; last_HBA = sh; if (first_HBA == NULL) first_HBA = sh; registered_HBAs++; return (TRUE);}void find_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt){ u32 base; int i; #if CHECKPAL u8 pal1, pal2, pal3;#endif for (i = 0; i < MAXEISA; i++) { if (EISAbases[i] == TRUE) { /* Still a possibility ? */ base = 0x1c88 + (i * 0x1000);#if CHECKPAL pal1 = inb((u16)base - 8); pal2 = inb((u16)base - 7); pal3 = inb((u16)base - 6); if (((pal1 == DPT_ID1) && (pal2 == DPT_ID2)) || ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) && (pal3 == NEC_ID3))|| ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) && (pal3 == ATT_ID3))){ DBG(DBG_PROBE, printk("EISA EATA id tags found: %x %x %x \n", (int)pal1, (int)pal2, (int)pal3));#endif if (get_conf_PIO(base, buf) == TRUE) { if (buf->IRQ) { DBG(DBG_EISA, printk("Registering EISA HBA\n")); register_HBA(base, buf, tpnt, IS_EISA); } else printk("eata_dma: No valid IRQ. HBA removed from list\n"); }#if CHECK_BLINK else { if (check_blink_state(base)) printk("HBA is in BLINK state. Consult your HBAs " "Manual to correct this.\n"); } #endif /* Nothing found here so we take it from the list */ EISAbases[i] = 0; #if CHECKPAL } #endif } } return; }void find_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt){ int i; for (i = 0; i < MAXISA; i++) { if (ISAbases[i]) { if (get_conf_PIO(ISAbases[i],buf) == TRUE){ DBG(DBG_ISA, printk("Registering ISA HBA\n")); register_HBA(ISAbases[i], buf, tpnt, IS_ISA); } #if CHECK_BLINK else { if (check_blink_state(ISAbases[i])) printk("HBA is in BLINK state. Consult your HBAs " "Manual to correct this.\n"); }#endif ISAbases[i] = 0; } } return;}void find_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt){#ifndef CONFIG_PCI printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");#else u8 pci_bus, pci_device_fn; static s16 pci_index = 0; /* Device index to PCI BIOS calls */ u32 base = 0; u16 com_adr; u16 rev_device; u32 error, i, x; u8 pal1, pal2, pal3; if (pcibios_present()) { for (i = 0; i <= MAXPCI; ++i, ++pci_index) { if (pcibios_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, pci_index, &pci_bus, &pci_device_fn)) break; DBG(DBG_PROBE && DBG_PCI, printk("eata_dma: find_PCI, HBA at bus %d, device %d," " function %d, index %d\n", (s32)pci_bus, (s32)((pci_device_fn & 0xf8) >> 3), (s32)(pci_device_fn & 7), pci_index)); if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn, PCI_CLASS_DEVICE, &rev_device))) { if (rev_device == PCI_CLASS_STORAGE_SCSI) { if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn, PCI_COMMAND, (u16 *) & com_adr))) { if (!((com_adr & PCI_COMMAND_IO) && (com_adr & PCI_COMMAND_MASTER))) { printk("eata_dma: find_PCI, HBA has IO or" " BUSMASTER mode disabled\n"); continue; } } else printk("eata_dma: find_PCI, error %x while reading " "PCI_COMMAND\n", error); } else printk("eata_dma: find_PCI, DEVICECLASSID %x didn't match\n", rev_device); } else { printk("eata_dma: find_PCI, error %x while reading " "PCI_CLASS_BASE\n", error); continue; } if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_0, (int *) &base))){ /* Check if the address is valid */ if (base & 0x01) { base &= 0xfffffffe; /* EISA tag there ? */ pal1 = inb(base); pal2 = inb(base + 1); pal3 = inb(base + 2); if (((pal1 == DPT_ID1) && (pal2 == DPT_ID2)) || ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) && (pal3 == NEC_ID3)) || ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) && (pal3 == ATT_ID3))) base += 0x08; else base += 0x10; /* Now, THIS is the real address */ if (base != 0x1f8) { /* We didn't find it in the primary search */ if (get_conf_PIO(base, buf) == TRUE) { /* OK. We made it till here, so we can go now * and register it. We only have to check and * eventually remove it from the EISA and ISA list */ DBG(DBG_PCI, printk("Registering PCI HBA\n")); register_HBA(base, buf, tpnt, IS_PCI); if (base < 0x1000) { for (x = 0; x < MAXISA; ++x) { if (ISAbases[x] == base) { ISAbases[x] = 0; break; } } } else if ((base & 0x0fff) == 0x0c88) EISAbases[(base >> 12) & 0x0f] = 0; continue; /* break; */ } #if CHECK_BLINK else if (check_blink_state(base) == TRUE) { printk("eata_dma: HBA is in BLINK state.\n" "Consult your HBAs manual to correct this.\n"); }#endif } } } else { printk("eata_dma: error %x while reading " "PCI_BASE_ADDRESS_0\n", error); } } } else { printk("eata_dma: No BIOS32 extensions present. This driver release " "still depends on it.\n" " Skipping scan for PCI HBAs. \n"); }#endif /* #ifndef CONFIG_PCI */ return;}int eata_detect(Scsi_Host_Template * tpnt){ struct Scsi_Host *HBA_ptr; struct get_conf gc; int i; DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, printk("Using lots of delays to let you read the debugging output\n")); tpnt->proc_dir = &proc_scsi_eata_dma; status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA); dma_scratch = scsi_init_malloc(1024, GFP_ATOMIC | GFP_DMA); if(status == NULL || dma_scratch == NULL) { printk("eata_dma: can't allocate enough memory to probe for hosts !\n"); return(0); } dma_scratch += 4; find_PCI(&gc, tpnt); find_EISA(&gc, tpnt); find_ISA(&gc, tpnt); for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */ if (reg_IRQ[i] >= 1){ /* exchange the interrupt handler which */ free_irq(i, NULL); /* we used for probing with the real one */ request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT|SA_SHIRQ, "eata_dma", NULL); } } HBA_ptr = first_HBA; if (registered_HBAs != 0) { printk("EATA (Extended Attachment) driver version: %d.%d%s" "\ndeveloped in co-operation with DPT\n" "(c) 1993-96 Michael Neuffer, mike@i-Connect.Net\n", VER_MAJOR, VER_MINOR, VER_SUB); printk("Registered HBAs:"); printk("\nHBA no. Boardtype Revis EATA Bus BaseIO IRQ" " DMA Ch ID Pr QS S/G IS\n"); for (i = 1; i <= registered_HBAs; i++) { printk("scsi%-2d: %.12s v%s 2.0%c %s %#.4x %2d", HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')? "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ", (u32) HBA_ptr->base, HBA_ptr->irq); if(HBA_ptr->dma_channel != BUSMASTER) printk(" %2x ", HBA_ptr->dma_channel); else printk(" %s", "BMST"); printk(" %d %d %c %3d %3d %c\n", SD(HBA_ptr)->channel+1, HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N', HBA_ptr->can_queue, HBA_ptr->sg_tablesize, (SD(HBA_ptr)->immediate_support == TRUE)?'Y':'N'); HBA_ptr = SD(HBA_ptr)->next; } } else { scsi_init_free((void *)status, 512); } scsi_init_free((void *)dma_scratch - 4, 1024); DBG(DPT_DEBUG, DELAY(12)); return(registered_HBAs);}#ifdef MODULE/* Eventually this will go into an include file, but this will be later */Scsi_Host_Template driver_template = EATA_DMA;#include "scsi_module.c"#endif/* * Overrides for Emacs so that we almost follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only. This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * tab-width: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -