1 /* 2 * jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture) 3 * 4 * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de) 5 * 6 * jazz_esp is based on David S. Miller's ESP driver and cyber_esp 7 */ 8 9 #include <linux/init.h> 10 #include <linux/kernel.h> 11 #include <linux/delay.h> 12 #include <linux/types.h> 13 #include <linux/string.h> 14 #include <linux/slab.h> 15 #include <linux/blkdev.h> 16 #include <linux/proc_fs.h> 17 #include <linux/stat.h> 18 19 #include "scsi.h" 20 #include <scsi/scsi_host.h> 21 #include "NCR53C9x.h" 22 23 #include <asm/irq.h> 24 #include <asm/jazz.h> 25 #include <asm/jazzdma.h> 26 #include <asm/dma.h> 27 28 #include <asm/pgtable.h> 29 30 static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); 31 static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp); 32 static void dma_dump_state(struct NCR_ESP *esp); 33 static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); 34 static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); 35 static void dma_ints_off(struct NCR_ESP *esp); 36 static void dma_ints_on(struct NCR_ESP *esp); 37 static int dma_irq_p(struct NCR_ESP *esp); 38 static int dma_ports_p(struct NCR_ESP *esp); 39 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); 40 static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp); 41 static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp); 42 static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp); 43 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp); 44 static void dma_advance_sg (struct scsi_cmnd *sp); 45 static void dma_led_off(struct NCR_ESP *); 46 static void dma_led_on(struct NCR_ESP *); 47 48 49 static volatile unsigned char cmd_buffer[16]; 50 /* This is where all commands are put 51 * before they are trasfered to the ESP chip 52 * via PIO. 53 */ 54 55 static int jazz_esp_release(struct Scsi_Host *shost) 56 { 57 if (shost->irq) 58 free_irq(shost->irq, NULL); 59 if (shost->dma_channel != 0xff) 60 free_dma(shost->dma_channel); 61 if (shost->io_port && shost->n_io_port) 62 release_region(shost->io_port, shost->n_io_port); 63 scsi_unregister(shost); 64 return 0; 65 } 66 67 /***************************************************************** Detection */ 68 static int jazz_esp_detect(struct scsi_host_template *tpnt) 69 { 70 struct NCR_ESP *esp; 71 struct ConfigDev *esp_dev; 72 73 /* 74 * first assumption it is there:-) 75 */ 76 if (1) { 77 esp_dev = NULL; 78 esp = esp_allocate(tpnt, (void *) esp_dev); 79 80 /* Do command transfer with programmed I/O */ 81 esp->do_pio_cmds = 1; 82 83 /* Required functions */ 84 esp->dma_bytes_sent = &dma_bytes_sent; 85 esp->dma_can_transfer = &dma_can_transfer; 86 esp->dma_dump_state = &dma_dump_state; 87 esp->dma_init_read = &dma_init_read; 88 esp->dma_init_write = &dma_init_write; 89 esp->dma_ints_off = &dma_ints_off; 90 esp->dma_ints_on = &dma_ints_on; 91 esp->dma_irq_p = &dma_irq_p; 92 esp->dma_ports_p = &dma_ports_p; 93 esp->dma_setup = &dma_setup; 94 95 /* Optional functions */ 96 esp->dma_barrier = NULL; 97 esp->dma_drain = NULL; 98 esp->dma_invalidate = NULL; 99 esp->dma_irq_entry = NULL; 100 esp->dma_irq_exit = NULL; 101 esp->dma_poll = NULL; 102 esp->dma_reset = NULL; 103 esp->dma_led_off = &dma_led_off; 104 esp->dma_led_on = &dma_led_on; 105 106 /* virtual DMA functions */ 107 esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; 108 esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; 109 esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one; 110 esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl; 111 esp->dma_advance_sg = &dma_advance_sg; 112 113 114 /* SCSI chip speed */ 115 esp->cfreq = 40000000; 116 117 /* 118 * we don't give the address of DMA channel, but the number 119 * of DMA channel, so we can use the jazz DMA functions 120 * 121 */ 122 esp->dregs = (void *) JAZZ_SCSI_DMA; 123 124 /* ESP register base */ 125 esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE); 126 127 /* Set the command buffer */ 128 esp->esp_command = (volatile unsigned char *)cmd_buffer; 129 130 /* get virtual dma address for command buffer */ 131 esp->esp_command_dvma = vdma_alloc(CPHYSADDR(cmd_buffer), sizeof (cmd_buffer)); 132 133 esp->irq = JAZZ_SCSI_IRQ; 134 request_irq(JAZZ_SCSI_IRQ, esp_intr, IRQF_DISABLED, "JAZZ SCSI", 135 esp->ehost); 136 137 /* 138 * FIXME, look if the scsi id is available from NVRAM 139 */ 140 esp->scsi_id = 7; 141 142 /* Check for differential SCSI-bus */ 143 /* What is this stuff? */ 144 esp->diff = 0; 145 146 esp_initialize(esp); 147 148 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); 149 esps_running = esps_in_use; 150 return esps_in_use; 151 } 152 return 0; 153 } 154 155 /************************************************************* DMA Functions */ 156 static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) 157 { 158 return fifo_count; 159 } 160 161 static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp) 162 { 163 /* 164 * maximum DMA size is 1MB 165 */ 166 unsigned long sz = sp->SCp.this_residual; 167 if(sz > 0x100000) 168 sz = 0x100000; 169 return sz; 170 } 171 172 static void dma_dump_state(struct NCR_ESP *esp) 173 { 174 175 ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n", 176 esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_residue((int)esp->dregs))); 177 } 178 179 static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) 180 { 181 dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length); 182 vdma_disable ((int)esp->dregs); 183 vdma_set_mode ((int)esp->dregs, DMA_MODE_READ); 184 vdma_set_addr ((int)esp->dregs, vaddress); 185 vdma_set_count ((int)esp->dregs, length); 186 vdma_enable ((int)esp->dregs); 187 } 188 189 static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) 190 { 191 dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length); 192 vdma_disable ((int)esp->dregs); 193 vdma_set_mode ((int)esp->dregs, DMA_MODE_WRITE); 194 vdma_set_addr ((int)esp->dregs, vaddress); 195 vdma_set_count ((int)esp->dregs, length); 196 vdma_enable ((int)esp->dregs); 197 } 198 199 static void dma_ints_off(struct NCR_ESP *esp) 200 { 201 disable_irq(esp->irq); 202 } 203 204 static void dma_ints_on(struct NCR_ESP *esp) 205 { 206 enable_irq(esp->irq); 207 } 208 209 static int dma_irq_p(struct NCR_ESP *esp) 210 { 211 return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); 212 } 213 214 static int dma_ports_p(struct NCR_ESP *esp) 215 { 216 int enable = vdma_get_enable((int)esp->dregs); 217 218 return (enable & R4030_CHNL_ENABLE); 219 } 220 221 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 222 { 223 /* 224 * On the Sparc, DMA_ST_WRITE means "move data from device to memory" 225 * so when (write) is true, it actually means READ! 226 */ 227 if(write){ 228 dma_init_read(esp, addr, count); 229 } else { 230 dma_init_write(esp, addr, count); 231 } 232 } 233 234 static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp) 235 { 236 sp->SCp.have_data_in = vdma_alloc(CPHYSADDR(sp->SCp.buffer), sp->SCp.this_residual); 237 sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in); 238 } 239 240 static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) 241 { 242 int sz = sp->SCp.buffers_residual; 243 struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer; 244 245 while (sz >= 0) { 246 sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length); 247 sz--; 248 } 249 sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address); 250 } 251 252 static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp) 253 { 254 vdma_free(sp->SCp.have_data_in); 255 } 256 257 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) 258 { 259 int sz = sp->use_sg - 1; 260 struct scatterlist *sg = (struct scatterlist *)sp->request_buffer; 261 262 while(sz >= 0) { 263 vdma_free(sg[sz].dma_address); 264 sz--; 265 } 266 } 267 268 static void dma_advance_sg (struct scsi_cmnd *sp) 269 { 270 sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address); 271 } 272 273 #define JAZZ_HDC_LED 0xe000d100 /* FIXME, find correct address */ 274 275 static void dma_led_off(struct NCR_ESP *esp) 276 { 277 #if 0 278 *(unsigned char *)JAZZ_HDC_LED = 0; 279 #endif 280 } 281 282 static void dma_led_on(struct NCR_ESP *esp) 283 { 284 #if 0 285 *(unsigned char *)JAZZ_HDC_LED = 1; 286 #endif 287 } 288 289 static struct scsi_host_template driver_template = { 290 .proc_name = "jazz_esp", 291 .proc_info = esp_proc_info, 292 .name = "ESP 100/100a/200", 293 .detect = jazz_esp_detect, 294 .slave_alloc = esp_slave_alloc, 295 .slave_destroy = esp_slave_destroy, 296 .release = jazz_esp_release, 297 .info = esp_info, 298 .queuecommand = esp_queue, 299 .eh_abort_handler = esp_abort, 300 .eh_bus_reset_handler = esp_reset, 301 .can_queue = 7, 302 .this_id = 7, 303 .sg_tablesize = SG_ALL, 304 .cmd_per_lun = 1, 305 .use_clustering = DISABLE_CLUSTERING, 306 }; 307 #include "scsi_module.c" 308