Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.23 306 lines 8.6 kB view raw
1/* blz2060.c: Driver for Blizzard 2060 SCSI Controller. 2 * 3 * Copyright (C) 1996 Jesper Skov (jskov@cygnus.co.uk) 4 * 5 * This driver is based on the CyberStorm driver, hence the occasional 6 * reference to CyberStorm. 7 */ 8 9/* TODO: 10 * 11 * 1) Figure out how to make a cleaner merge with the sparc driver with regard 12 * to the caches and the Sparc MMU mapping. 13 * 2) Make as few routines required outside the generic driver. A lot of the 14 * routines in this file used to be inline! 15 */ 16 17#include <linux/module.h> 18 19#include <linux/init.h> 20#include <linux/kernel.h> 21#include <linux/delay.h> 22#include <linux/types.h> 23#include <linux/string.h> 24#include <linux/slab.h> 25#include <linux/blkdev.h> 26#include <linux/proc_fs.h> 27#include <linux/stat.h> 28#include <linux/interrupt.h> 29 30#include "scsi.h" 31#include <scsi/scsi_host.h> 32#include "NCR53C9x.h" 33 34#include <linux/zorro.h> 35#include <asm/irq.h> 36#include <asm/amigaints.h> 37#include <asm/amigahw.h> 38 39#include <asm/pgtable.h> 40 41/* The controller registers can be found in the Z2 config area at these 42 * offsets: 43 */ 44#define BLZ2060_ESP_ADDR 0x1ff00 45#define BLZ2060_DMA_ADDR 0x1ffe0 46 47 48/* The Blizzard 2060 DMA interface 49 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 50 * Only two things can be programmed in the Blizzard DMA: 51 * 1) The data direction is controlled by the status of bit 31 (1 = write) 52 * 2) The source/dest address (word aligned, shifted one right) in bits 30-0 53 * 54 * Figure out interrupt status by reading the ESP status byte. 55 */ 56struct blz2060_dma_registers { 57 volatile unsigned char dma_led_ctrl; /* DMA led control [0x000] */ 58 unsigned char dmapad1[0x0f]; 59 volatile unsigned char dma_addr0; /* DMA address (MSB) [0x010] */ 60 unsigned char dmapad2[0x03]; 61 volatile unsigned char dma_addr1; /* DMA address [0x014] */ 62 unsigned char dmapad3[0x03]; 63 volatile unsigned char dma_addr2; /* DMA address [0x018] */ 64 unsigned char dmapad4[0x03]; 65 volatile unsigned char dma_addr3; /* DMA address (LSB) [0x01c] */ 66}; 67 68#define BLZ2060_DMA_WRITE 0x80000000 69 70/* DMA control bits */ 71#define BLZ2060_DMA_LED 0x02 /* HD led control 1 = off */ 72 73static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); 74static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp); 75static void dma_dump_state(struct NCR_ESP *esp); 76static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length); 77static void dma_init_write(struct NCR_ESP *esp, __u32 addr, int length); 78static void dma_ints_off(struct NCR_ESP *esp); 79static void dma_ints_on(struct NCR_ESP *esp); 80static int dma_irq_p(struct NCR_ESP *esp); 81static void dma_led_off(struct NCR_ESP *esp); 82static void dma_led_on(struct NCR_ESP *esp); 83static int dma_ports_p(struct NCR_ESP *esp); 84static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); 85 86static volatile unsigned char cmd_buffer[16]; 87 /* This is where all commands are put 88 * before they are transferred to the ESP chip 89 * via PIO. 90 */ 91 92/***************************************************************** Detection */ 93int __init blz2060_esp_detect(struct scsi_host_template *tpnt) 94{ 95 struct NCR_ESP *esp; 96 struct zorro_dev *z = NULL; 97 unsigned long address; 98 99 if ((z = zorro_find_device(ZORRO_PROD_PHASE5_BLIZZARD_2060, z))) { 100 unsigned long board = z->resource.start; 101 if (request_mem_region(board+BLZ2060_ESP_ADDR, 102 sizeof(struct ESP_regs), "NCR53C9x")) { 103 esp = esp_allocate(tpnt, (void *)board + BLZ2060_ESP_ADDR, 0); 104 105 /* Do command transfer with programmed I/O */ 106 esp->do_pio_cmds = 1; 107 108 /* Required functions */ 109 esp->dma_bytes_sent = &dma_bytes_sent; 110 esp->dma_can_transfer = &dma_can_transfer; 111 esp->dma_dump_state = &dma_dump_state; 112 esp->dma_init_read = &dma_init_read; 113 esp->dma_init_write = &dma_init_write; 114 esp->dma_ints_off = &dma_ints_off; 115 esp->dma_ints_on = &dma_ints_on; 116 esp->dma_irq_p = &dma_irq_p; 117 esp->dma_ports_p = &dma_ports_p; 118 esp->dma_setup = &dma_setup; 119 120 /* Optional functions */ 121 esp->dma_barrier = 0; 122 esp->dma_drain = 0; 123 esp->dma_invalidate = 0; 124 esp->dma_irq_entry = 0; 125 esp->dma_irq_exit = 0; 126 esp->dma_led_on = &dma_led_on; 127 esp->dma_led_off = &dma_led_off; 128 esp->dma_poll = 0; 129 esp->dma_reset = 0; 130 131 /* SCSI chip speed */ 132 esp->cfreq = 40000000; 133 134 /* The DMA registers on the Blizzard are mapped 135 * relative to the device (i.e. in the same Zorro 136 * I/O block). 137 */ 138 address = (unsigned long)ZTWO_VADDR(board); 139 esp->dregs = (void *)(address + BLZ2060_DMA_ADDR); 140 141 /* ESP register base */ 142 esp->eregs = (struct ESP_regs *)(address + BLZ2060_ESP_ADDR); 143 144 /* Set the command buffer */ 145 esp->esp_command = cmd_buffer; 146 esp->esp_command_dvma = virt_to_bus((void *)cmd_buffer); 147 148 esp->irq = IRQ_AMIGA_PORTS; 149 request_irq(IRQ_AMIGA_PORTS, esp_intr, IRQF_SHARED, 150 "Blizzard 2060 SCSI", esp->ehost); 151 152 /* Figure out our scsi ID on the bus */ 153 esp->scsi_id = 7; 154 155 /* We don't have a differential SCSI-bus. */ 156 esp->diff = 0; 157 158 esp_initialize(esp); 159 160 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, esps_in_use); 161 esps_running = esps_in_use; 162 return esps_in_use; 163 } 164 } 165 return 0; 166} 167 168/************************************************************* DMA Functions */ 169static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) 170{ 171 /* Since the Blizzard DMA is fully dedicated to the ESP chip, 172 * the number of bytes sent (to the ESP chip) equals the number 173 * of bytes in the FIFO - there is no buffering in the DMA controller. 174 * XXXX Do I read this right? It is from host to ESP, right? 175 */ 176 return fifo_count; 177} 178 179static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp) 180{ 181 /* I don't think there's any limit on the Blizzard DMA. So we use what 182 * the ESP chip can handle (24 bit). 183 */ 184 unsigned long sz = sp->SCp.this_residual; 185 if(sz > 0x1000000) 186 sz = 0x1000000; 187 return sz; 188} 189 190static void dma_dump_state(struct NCR_ESP *esp) 191{ 192 ESPLOG(("intreq:<%04x>, intena:<%04x>\n", 193 amiga_custom.intreqr, amiga_custom.intenar)); 194} 195 196static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length) 197{ 198 struct blz2060_dma_registers *dregs = 199 (struct blz2060_dma_registers *) (esp->dregs); 200 201 cache_clear(addr, length); 202 203 addr >>= 1; 204 addr &= ~(BLZ2060_DMA_WRITE); 205 dregs->dma_addr3 = (addr ) & 0xff; 206 dregs->dma_addr2 = (addr >> 8) & 0xff; 207 dregs->dma_addr1 = (addr >> 16) & 0xff; 208 dregs->dma_addr0 = (addr >> 24) & 0xff; 209} 210 211static void dma_init_write(struct NCR_ESP *esp, __u32 addr, int length) 212{ 213 struct blz2060_dma_registers *dregs = 214 (struct blz2060_dma_registers *) (esp->dregs); 215 216 cache_push(addr, length); 217 218 addr >>= 1; 219 addr |= BLZ2060_DMA_WRITE; 220 dregs->dma_addr3 = (addr ) & 0xff; 221 dregs->dma_addr2 = (addr >> 8) & 0xff; 222 dregs->dma_addr1 = (addr >> 16) & 0xff; 223 dregs->dma_addr0 = (addr >> 24) & 0xff; 224} 225 226static void dma_ints_off(struct NCR_ESP *esp) 227{ 228 disable_irq(esp->irq); 229} 230 231static void dma_ints_on(struct NCR_ESP *esp) 232{ 233 enable_irq(esp->irq); 234} 235 236static int dma_irq_p(struct NCR_ESP *esp) 237{ 238 return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); 239} 240 241static void dma_led_off(struct NCR_ESP *esp) 242{ 243 ((struct blz2060_dma_registers *) (esp->dregs))->dma_led_ctrl = 244 BLZ2060_DMA_LED; 245} 246 247static void dma_led_on(struct NCR_ESP *esp) 248{ 249 ((struct blz2060_dma_registers *) (esp->dregs))->dma_led_ctrl = 0; 250} 251 252static int dma_ports_p(struct NCR_ESP *esp) 253{ 254 return ((amiga_custom.intenar) & IF_PORTS); 255} 256 257static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 258{ 259 /* On the Sparc, DMA_ST_WRITE means "move data from device to memory" 260 * so when (write) is true, it actually means READ! 261 */ 262 if(write){ 263 dma_init_read(esp, addr, count); 264 } else { 265 dma_init_write(esp, addr, count); 266 } 267} 268 269#define HOSTS_C 270 271int blz2060_esp_release(struct Scsi_Host *instance) 272{ 273#ifdef MODULE 274 unsigned long address = (unsigned long)((struct NCR_ESP *)instance->hostdata)->edev; 275 276 esp_deallocate((struct NCR_ESP *)instance->hostdata); 277 esp_release(); 278 release_mem_region(address, sizeof(struct ESP_regs)); 279 free_irq(IRQ_AMIGA_PORTS, esp_intr); 280#endif 281 return 1; 282} 283 284 285static struct scsi_host_template driver_template = { 286 .proc_name = "esp-blz2060", 287 .proc_info = esp_proc_info, 288 .name = "Blizzard2060 SCSI", 289 .detect = blz2060_esp_detect, 290 .slave_alloc = esp_slave_alloc, 291 .slave_destroy = esp_slave_destroy, 292 .release = blz2060_esp_release, 293 .queuecommand = esp_queue, 294 .eh_abort_handler = esp_abort, 295 .eh_bus_reset_handler = esp_reset, 296 .can_queue = 7, 297 .this_id = 7, 298 .sg_tablesize = SG_ALL, 299 .cmd_per_lun = 1, 300 .use_clustering = ENABLE_CLUSTERING 301}; 302 303 304#include "scsi_module.c" 305 306MODULE_LICENSE("GPL");