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

📄 eata_dma.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    }    size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long)) 			       * ntohs(gc->queuesiz));    DBG(DBG_REGISTER, printk("scsi_register size: %ld\n", size));    sh = scsi_register(tpnt, size);        if(sh != NULL) {        hd = SD(sh);		   	memset(hd->reads, 0, sizeof(u32) * 26); 		sh->select_queue_depths = eata_select_queue_depths;		hd->bustype = bustype;	/*	 * If we are using a ISA board, we can't use extended SG,	 * because we would need excessive amounts of memory for	 * bounce buffers.	 */	if (gc->SG_64K==TRUE && ntohs(gc->SGsiz)==64 && hd->bustype!=IS_ISA){	    sh->sg_tablesize = SG_SIZE_BIG;	} else {	    sh->sg_tablesize = ntohs(gc->SGsiz);	    if (sh->sg_tablesize > SG_SIZE || sh->sg_tablesize == 0) {	        if (sh->sg_tablesize == 0)		    printk(KERN_WARNING "Warning: SG size had to be fixed.\n"			   "This might be a PM2012 with a defective Firmware"			   "\nContact DPT support@dpt.com for an upgrade\n");		sh->sg_tablesize = SG_SIZE;	    }	}	hd->sgsize = sh->sg_tablesize;    }    if(sh != NULL) {        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 = 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;        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    struct pci_dev *dev = NULL;     u32 base, x;    u8 pal1, pal2, pal3;    while ((dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) {	    DBG(DBG_PROBE && DBG_PCI, 		printk("eata_dma: find_PCI, HBA at %s\n", dev->name));	    if (pci_enable_device(dev))	    	continue;	    pci_set_master(dev);	    base = pci_resource_flags(dev, 0);	    if (base & IORESOURCE_MEM) {		printk("eata_dma: invalid base address of device %s\n", dev->name);		continue;	    }	    base = pci_resource_start(dev, 0);            /* 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;		} #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	    }	}#endif /* #ifndef CONFIG_PCI */}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_name = "eata_dma";    status = kmalloc(512, GFP_ATOMIC | GFP_DMA);    dma_scratch = kmalloc(1024, GFP_ATOMIC | GFP_DMA);    if(status == NULL || dma_scratch == NULL) {	printk("eata_dma: can't allocate enough memory to probe for hosts !\n");	if(status)		kfree(status);	if(dma_scratch)		kfree(dma_scratch);	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 *)(do_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 {	kfree((void *)status);    }    kfree((void *)dma_scratch - 4);    DBG(DPT_DEBUG, DELAY(12));    return(registered_HBAs);}/* Eventually this will go into an include file, but this will be later */static Scsi_Host_Template driver_template = EATA_DMA;#include "scsi_module.c"/* * 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 + -