⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eata_dma.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 4 页
字号:
        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 + -