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

📄 eata_dma.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 4 页
字号:
	    device->queue_depth = 2;    }#else    /* First we do a sample run go find out what we have */    for(device = devicelist; device != NULL; device = device->next) {        if (device->host == host) {	    devcount++;	    switch(device->type) {	    case TYPE_DISK:	    case TYPE_MOD:	        factor += TYPE_DISK_QUEUE;		break;	    case TYPE_TAPE:	        factor += TYPE_TAPE_QUEUE;		break;	    case TYPE_WORM:	    case TYPE_ROM:	        factor += TYPE_ROM_QUEUE;		break;	    case TYPE_PROCESSOR:	    case TYPE_SCANNER:	    default:	        factor += TYPE_OTHER_QUEUE;		break;	    }	}    }    DBG(DBG_REGISTER, printk(KERN_DEBUG "scsi%d: needed queueslots %d\n", 			     host->host_no, factor));    if(factor == 0)    /* We don't want to get a DIV BY ZERO error */        factor = 1;    factor = (SD(host)->queuesize * 10) / factor;    DBG(DBG_REGISTER, printk(KERN_DEBUG "scsi%d: using factor %dE-1\n", 			     host->host_no, factor));    /* Now that have the factor we can set the individual queuesizes */    for(device = devicelist; device != NULL; device = device->next) {        if(device->host == host) {	    if(SD(device->host)->bustype != IS_ISA){	        switch(device->type) {		case TYPE_DISK:		case TYPE_MOD:		    device->queue_depth = (TYPE_DISK_QUEUE * factor) / 10;		    break;		case TYPE_TAPE:		    device->queue_depth = (TYPE_TAPE_QUEUE * factor) / 10;		    break;		case TYPE_WORM:		case TYPE_ROM:	            device->queue_depth = (TYPE_ROM_QUEUE * factor) / 10;		    break;		case TYPE_PROCESSOR:		case TYPE_SCANNER:		default:		    device->queue_depth = (TYPE_OTHER_QUEUE * factor) / 10;		    break;		}	    } else /* ISA forces us to limit the queue depth because of the 		    * bounce buffer memory overhead. I know this is cruel */	        device->queue_depth = 2; 	    /* 	     * It showed that we need to set an upper limit of commands              * we can allow to  queue for a single device on the bus. 	     * If we get above that limit, the broken midlevel SCSI code 	     * will produce bogus timeouts and aborts en masse. :-(	     */	    if(device->queue_depth > UPPER_DEVICE_QUEUE_LIMIT)		device->queue_depth = UPPER_DEVICE_QUEUE_LIMIT;	    if(device->queue_depth == 0) 		device->queue_depth = 1;	    printk(KERN_INFO "scsi%d: queue depth for target %d on channel %d "		   "set to %d\n", host->host_no, device->id, device->channel,		   device->queue_depth);	}    }#endif}#if CHECK_BLINKint check_blink_state(long base){    ushort loops = 10;    u32 blinkindicator;    u32 state = 0x12345678;    u32 oldstate = 0;    blinkindicator = htonl(0x54504442);    while ((loops--) && (state != oldstate)) {	oldstate = state;	state = inl((uint) base + 1);    }    DBG(DBG_BLINK, printk("Did Blink check. Status: %d\n",	      (state == oldstate) && (state == blinkindicator)));    if ((state == oldstate) && (state == blinkindicator))	return(TRUE);    else	return (FALSE);}#endifchar * get_board_data(u32 base, u32 irq, u32 id){    struct eata_ccb *cp;    struct eata_sp  *sp;    static char *buff;    ulong i;    cp = (struct eata_ccb *) scsi_init_malloc(sizeof(struct eata_ccb),					      GFP_ATOMIC | GFP_DMA);    sp = (struct eata_sp *) scsi_init_malloc(sizeof(struct eata_sp), 					     GFP_ATOMIC | GFP_DMA);    buff = dma_scratch;     memset(cp, 0, sizeof(struct eata_ccb));    memset(sp, 0, sizeof(struct eata_sp));    memset(buff, 0, 256);    cp->DataIn = TRUE;	       cp->Interpret = TRUE;   /* Interpret command */    cp->cp_dispri = TRUE;    cp->cp_identify = TRUE;     cp->cp_datalen = htonl(56);      cp->cp_dataDMA = htonl(virt_to_bus(buff));    cp->cp_statDMA = htonl(virt_to_bus(sp));    cp->cp_viraddr = cp;        cp->cp_id = id;    cp->cp_lun = 0;    cp->cp_cdb[0] = INQUIRY;    cp->cp_cdb[1] = 0;    cp->cp_cdb[2] = 0;    cp->cp_cdb[3] = 0;    cp->cp_cdb[4] = 56;    cp->cp_cdb[5] = 0;    fake_int_base = (struct eata_register *) base;    fake_int_result = FALSE;    fake_int_happened = FALSE;    eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP);        i = jiffies + (3 * HZ);    while (fake_int_happened == FALSE && jiffies <= i) 	barrier();        DBG(DBG_INTR3, printk(KERN_DEBUG "fake_int_result: %#x hbastat %#x "			  "scsistat %#x, buff %p sp %p\n",			  fake_int_result, (u32) (sp->hba_stat /*& 0x7f*/), 			  (u32) sp->scsi_stat, buff, sp));    scsi_init_free((void *)cp, sizeof(struct eata_ccb));    scsi_init_free((void *)sp, sizeof(struct eata_sp));        if ((fake_int_result & HA_SERROR) || jiffies > i){	printk(KERN_WARNING "eata_dma: trying to reset HBA at %x to clear "	       "possible blink state\n", base); 	/* hard reset the HBA  */	inb((u32) (base) + HA_RSTATUS);	eata_send_command(0, base, EATA_CMD_RESET);	DELAY(1);	return (NULL);    } else	return (buff);}int get_conf_PIO(u32 base, struct get_conf *buf){    ulong loop = R_LIMIT;    u16 *p;    if(check_region(base, 9)) 	return (FALSE);         memset(buf, 0, sizeof(struct get_conf));    while (inb(base + HA_RSTATUS) & HA_SBUSY)	if (--loop == 0) 	    return (FALSE);    fake_int_base = (struct eata_register *) base;    fake_int_result = FALSE;    fake_int_happened = FALSE;           DBG(DBG_PIO && DBG_PROBE,	printk("Issuing PIO READ CONFIG to HBA at %#x\n", base));    eata_send_command(0, base, EATA_CMD_PIO_READ_CONFIG);    loop = R_LIMIT;    for (p = (u16 *) buf; 	 (long)p <= ((long)buf + (sizeof(struct get_conf) / 2)); p++) {	while (!(inb(base + HA_RSTATUS) & HA_SDRQ))	    if (--loop == 0)		return (FALSE);	loop = R_LIMIT;	*p = inw(base + HA_RDATA);    }    if (!(inb(base + HA_RSTATUS) & HA_SERROR)) {	    /* Error ? */	if (htonl(EATA_SIGNATURE) == buf->signature) {	    DBG(DBG_PIO&&DBG_PROBE, printk("EATA Controller found at %x "					   "EATA Level: %x\n", (uint) base, 					   (uint) (buf->version)));	    	    while (inb(base + HA_RSTATUS) & HA_SDRQ) 		inw(base + HA_RDATA);	    return (TRUE);	}     } else {	DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer "		  "for HBA at %lx\n", (long)base));    }    return (FALSE);}void print_config(struct get_conf *gc){    printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d DMAS:%d\n",	   (u32) ntohl(gc->len), gc->version,	   gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support,	   gc->DMA_support);    printk("DMAV:%d HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n",	   gc->DMA_valid, gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2],	   gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND);    printk("IRQ:%d IRQT:%d DMAC:%d FORCADR:%d SG_64K:%d SG_UAE:%d MID:%d "	   "MCH:%d MLUN:%d\n",	   gc->IRQ, gc->IRQ_TR, (8 - gc->DMA_channel) & 7, gc->FORCADR, 	   gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN);     printk("RIDQ:%d PCI:%d EISA:%d\n",	   gc->ID_qest, gc->is_PCI, gc->is_EISA);    DBG(DPT_DEBUG, DELAY(14));}short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, 		   u8 bustype){    ulong size = 0;    unchar dma_channel = 0;    char *buff = 0;    unchar bugs = 0;    struct Scsi_Host *sh;    hostdata *hd;    int x;            DBG(DBG_REGISTER, print_config(gc));    if (gc->DMA_support == FALSE) {	printk("The EATA HBA at %#.4x does not support DMA.\n" 	       "Please use the EATA-PIO driver.\n", base);	return (FALSE);    }    if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22) 	gc->MAX_CHAN = 0;    if (reg_IRQ[gc->IRQ] == FALSE) {	/* Interrupt already registered ? */	if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT,			 "eata_dma", NULL)){	    reg_IRQ[gc->IRQ]++;	    if (!gc->IRQ_TR)		reg_IRQL[gc->IRQ] = TRUE;   /* IRQ is edge triggered */	} else {	    printk("Couldn't allocate IRQ %d, Sorry.", gc->IRQ);	    return (FALSE);	}    } else {		/* More than one HBA on this IRQ */	if (reg_IRQL[gc->IRQ] == TRUE) {	    printk("Can't support more than one HBA on this IRQ,\n"		   "  if the IRQ is edge triggered. Sorry.\n");	    return (FALSE);	} else	    reg_IRQ[gc->IRQ]++;    }     /* If DMA is supported but DMA_valid isn't set to indicate that     * the channel number is given we must have pre 2.0 firmware (1.7?)     * which leaves us to guess since the "newer ones" also don't set the      * DMA_valid bit.     */    if (gc->DMA_support && !gc->DMA_valid && gc->DMA_channel) {      printk(KERN_WARNING "eata_dma: If you are using a pre 2.0 firmware "	     "please update it !\n"	     "          You can get new firmware releases from ftp.dpt.com\n");	gc->DMA_channel = (base == 0x1f0 ? 3 /* DMA=5 */ : 2 /* DMA=6 */);	gc->DMA_valid = TRUE;    }    /* if gc->DMA_valid it must be an ISA HBA and we have to register it */    dma_channel = BUSMASTER;    if (gc->DMA_valid) {	if (request_dma(dma_channel = (8 - gc->DMA_channel) & 7, "eata_dma")) {	    printk(KERN_WARNING "Unable to allocate DMA channel %d for ISA HBA"		   " at %#.4x.\n", dma_channel, base);	    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);	}    }    if (dma_channel != BUSMASTER) {	disable_dma(dma_channel);	clear_dma_ff(dma_channel);	set_dma_mode(dma_channel, DMA_MODE_CASCADE);	enable_dma(dma_channel);    }    if (bustype != IS_EISA && bustype != IS_ISA)	buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]);    if (buff == NULL) {	if (bustype == IS_EISA || bustype == IS_ISA) {	    bugs = bugs || BROKEN_INQUIRY;	} else {	    if (gc->DMA_support == FALSE)		printk(KERN_WARNING "HBA at %#.4x doesn't support DMA. "		       "Sorry\n", base);	    else		printk(KERN_WARNING "HBA at %#.4x does not react on INQUIRY. "		       "Sorry.\n", base);	    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);	}    }     if (gc->DMA_support == FALSE && buff != NULL)  	printk(KERN_WARNING "HBA %.12sat %#.4x doesn't set the DMA_support "	       "flag correctly.\n", &buff[16], base);        request_region(base, 9, "eata_dma"); /* We already checked the 					  * availability, so this					  * should not fail.					  */        if(ntohs(gc->queuesiz) == 0) {	gc->queuesiz = ntohs(64);	printk(KERN_WARNING "Warning: Queue size has to be corrected. Assuming"	       " 64 queueslots\n"	       "         This might be a PM2012B with a defective Firmware\n"	       "         Contact DPT support@dpt.com for an upgrade\n");    }    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) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -