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

📄 mac_esp.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				quick = 0;			} else {				/* q950, 900, 700 */				quick = 1;				writel(0x1d1, 0xf9800024);				esp->dregs = (void *) 0xf9800024;			}		} else { /* chipnum */			quick = 1;			writel(0x1d1, 0xf9800028);			esp->dregs = (void *) 0xf9800028;		} /* chipnum == 0 */		/* use pio for command bytes; pio for message/data: TBI */		esp->do_pio_cmds = 1;		/* Set the command buffer */		esp->esp_command = (volatile unsigned char*) cmd_buffer;		esp->esp_command_dvma = (volatile unsigned char*) cmd_buffer;		/* various functions */		esp->dma_bytes_sent = &dma_bytes_sent;		esp->dma_can_transfer = &dma_can_transfer;		esp->dma_dump_state = &dma_dump_state;		esp->dma_init_read = NULL;		esp->dma_init_write = NULL;		esp->dma_ints_off = &dma_ints_off;		esp->dma_ints_on = &dma_ints_on;		esp->dma_ports_p = &dma_ports_p;		/* Optional functions */		esp->dma_barrier = NULL;		esp->dma_drain = NULL;		esp->dma_invalidate = NULL;		esp->dma_irq_entry = NULL;		esp->dma_irq_exit = NULL;		esp->dma_led_on = NULL;		esp->dma_led_off = NULL;		esp->dma_poll = NULL;		esp->dma_reset = NULL;		/* SCSI chip speed */		/* below esp->cfreq = 40000000; */		if (quick) {			/* 'quick' means there's handshake glue logic like in the 5380 case */			esp->dma_setup = &dma_setup_quick;		} else {			esp->dma_setup = &dma_setup;		}		if (chipnum == 0) {			esp->irq = IRQ_MAC_SCSI;			request_irq(IRQ_MAC_SCSI, esp_intr, 0, "Mac ESP SCSI", esp);#if 0	/* conflicts with IOP ADB */			request_irq(IRQ_MAC_SCSIDRQ, fake_drq, 0, "Mac ESP DRQ", esp);#endif			if (macintosh_config->scsi_type == MAC_SCSI_QUADRA) {				esp->cfreq = 16500000;			} else {				esp->cfreq = 25000000;			}		} else { /* chipnum == 1 */			esp->irq = IRQ_MAC_SCSIDRQ;#if 0	/* conflicts with IOP ADB */			request_irq(IRQ_MAC_SCSIDRQ, esp_intr, 0, "Mac ESP SCSI 2", esp);#endif			esp->cfreq = 25000000;		}		if (quick) {			printk("esp: using quick version\n");		}		printk("esp: addr at 0x%p\n", esp->eregs);		esp->scsi_id = 7;		esp->diff = 0;		esp_initialize(esp);	} /* for chipnum */	if (chipspresent)		printk("\nmac_esp: %d esp controllers found\n", chipspresent);	esp_initialized = chipspresent;	return chipspresent;}/* * I've been wondering what this is supposed to do, for some time. Talking  * to Allen Briggs: These machines have an extra register someplace where the * DRQ pin of the ESP can be monitored. That isn't useful for determining  * anything else (such as reselect interrupt or other magic) though.  * Maybe make the semantics should be changed like  * if (esp->current_SC) *	... check DRQ flag ... * else  *	... disconnected, check pending VIA interrupt ... * * There's a problem with using the dabf flag or mac_irq_pending() here: both * seem to return 1 even though no interrupt is currently pending, resulting * in esp_exec_cmd() holding off the next command, and possibly infinite loops * in esp_intr().  * Short term fix: just use esp_status & ESP_STAT_INTR here, as long as we * use simple PIO. The DRQ status will be important when implementing pseudo * DMA mode (set up ESP transfer count, return, do a batch of bytes in PIO or  * 'hardware handshake' mode upon DRQ). * If you plan on changing this (i.e. to save the esp_status register access in  * favor of a VIA register access or a shadow register for the IFR), make sure * to try a debug version of this first to monitor what registers would be a good * indicator of the ESP interrupt. */static int esp_dafb_dma_irq_p(struct NCR_ESP * esp){	unsigned int ret;	int sreg = esp_read(esp->eregs->esp_status);#ifdef DEBUG_MAC_ESP	printk("mac_esp: esp_dafb_dma_irq_p dafb %d irq %d\n", 		readl(esp->dregs), mac_irq_pending(IRQ_MAC_SCSI));#endif	sreg &= ESP_STAT_INTR;	/*	 * maybe working; this is essentially what's used for iosb_dma_irq_p	 */	if (sreg)		return 1;	else		return 0;	/*	 * didn't work ...	 */#if 0	if (esp->current_SC)		ret = readl(esp->dregs) & 0x200;	else if (esp->disconnected_SC)		ret = 1; /* sreg ?? */	else		ret = mac_irq_pending(IRQ_MAC_SCSI);	return(ret);#endif}/* * See above: testing mac_irq_pending always returned 8 (SCSI IRQ) regardless  * of the actual ESP status. */static int esp_iosb_dma_irq_p(struct NCR_ESP * esp){	int ret  = mac_irq_pending(IRQ_MAC_SCSI) || mac_irq_pending(IRQ_MAC_SCSIDRQ);	int sreg = esp_read(esp->eregs->esp_status);#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma_irq_p drq %d irq %d sreg %x curr %p disc %p\n", 		mac_irq_pending(IRQ_MAC_SCSIDRQ), mac_irq_pending(IRQ_MAC_SCSI), 		sreg, esp->current_SC, esp->disconnected_SC);#endif	sreg &= ESP_STAT_INTR;	if (sreg)		return (sreg);	else		return 0;}/* * This seems to be OK for PIO at least ... usually 0 after PIO. */static int dma_bytes_sent(struct NCR_ESP * esp, int fifo_count){#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma bytes sent = %x\n", fifo_count);#endif	return fifo_count;}/* * dma_can_transfer is used to switch between DMA and PIO, if DMA (pseudo) * is ever implemented. Returning 0 here will use PIO. */static int dma_can_transfer(struct NCR_ESP * esp, Scsi_Cmnd * sp){	unsigned long sz = sp->SCp.this_residual;#if 0	/* no DMA yet; make conditional */	if (sz > 0x10000000) {		sz = 0x10000000;	}	printk("mac_esp: dma can transfer = 0lx%x\n", sz);#else#ifdef DEBUG_MAC_ESP	printk("mac_esp: pio to transfer = %ld\n", sz);#endif	sz = 0;#endif	return sz;}/* * Not yet ... */static void dma_dump_state(struct NCR_ESP * esp){#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma_dump_state: called\n");#endif#if 0	ESPLOG(("esp%d: dma -- cond_reg<%02x>\n",		esp->esp_id, ((struct mac_dma_registers *)		(esp->dregs))->cond_reg));#endif}/* * DMA setup: should be used to set up the ESP transfer count for pseudo * DMA transfers; need a DRQ transfer function to do the actual transfer */static void dma_init_read(struct NCR_ESP * esp, char * vaddress, int length){	printk("mac_esp: dma_init_read\n");}static void dma_init_write(struct NCR_ESP * esp, char * vaddress, int length){	printk("mac_esp: dma_init_write\n");}static void dma_ints_off(struct NCR_ESP * esp){	mac_turnoff_irq(esp->irq);}static void dma_ints_on(struct NCR_ESP * esp){	mac_turnon_irq(esp->irq);}/* * generic dma_irq_p(), unused */static int dma_irq_p(struct NCR_ESP * esp){	int i = esp_read(esp->eregs->esp_status);#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma_irq_p status %d\n", i);#endif	return (i & ESP_STAT_INTR);}static int dma_irq_p_quick(struct NCR_ESP * esp){	/*	 * Copied from iosb_dma_irq_p()	 */	int ret  = mac_irq_pending(IRQ_MAC_SCSI) || mac_irq_pending(IRQ_MAC_SCSIDRQ);	int sreg = esp_read(esp->eregs->esp_status);#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma_irq_p drq %d irq %d sreg %x curr %p disc %p\n", 		mac_irq_pending(IRQ_MAC_SCSIDRQ), mac_irq_pending(IRQ_MAC_SCSI), 		sreg, esp->current_SC, esp->disconnected_SC);#endif	sreg &= ESP_STAT_INTR;	if (sreg)		return (sreg);	else		return 0;}static void dma_led_off(struct NCR_ESP * esp){#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma_led_off: called\n");#endif}static void dma_led_on(struct NCR_ESP * esp){#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma_led_on: called\n");#endif}static int dma_ports_p(struct NCR_ESP * esp){	return 0;}static void dma_setup(struct NCR_ESP * esp, __u32 addr, int count, int write){#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma_setup\n");#endif	if (write) {		dma_init_read(esp, (char *) addr, count);	} else {		dma_init_write(esp, (char *) addr, count);	}}static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int write){#ifdef DEBUG_MAC_ESP	printk("mac_esp: dma_setup_quick\n");#endif}static Scsi_Host_Template driver_template = SCSI_MAC_ESP;#include "scsi_module.c"

⌨️ 快捷键说明

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