?? mac_esp.c
字號:
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 + -