1 #include <linux/types.h> 2 #include <linux/mm.h> 3 #include <linux/blkdev.h> 4 #include <linux/init.h> 5 #include <linux/interrupt.h> 6 7 #include <asm/setup.h> 8 #include <asm/page.h> 9 #include <asm/pgtable.h> 10 #include <asm/amigaints.h> 11 #include <asm/amigahw.h> 12 #include <linux/zorro.h> 13 #include <asm/irq.h> 14 #include <linux/spinlock.h> 15 16 #include "scsi.h" 17 #include <scsi/scsi_host.h> 18 #include "wd33c93.h" 19 #include "a2091.h" 20 21 #include<linux/stat.h> 22 23 #define DMA(ptr) ((a2091_scsiregs *)((ptr)->base)) 24 #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) 25 26 static int a2091_release(struct Scsi_Host *instance); 27 28 static irqreturn_t a2091_intr (int irq, void *_instance) 29 { 30 unsigned long flags; 31 unsigned int status; 32 struct Scsi_Host *instance = (struct Scsi_Host *)_instance; 33 34 status = DMA(instance)->ISTR; 35 if (!(status & (ISTR_INT_F|ISTR_INT_P)) || !(status & ISTR_INTS)) 36 return IRQ_NONE; 37 38 spin_lock_irqsave(instance->host_lock, flags); 39 wd33c93_intr(instance); 40 spin_unlock_irqrestore(instance->host_lock, flags); 41 return IRQ_HANDLED; 42 } 43 44 static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 45 { 46 unsigned short cntr = CNTR_PDMD | CNTR_INTEN; 47 unsigned long addr = virt_to_bus(cmd->SCp.ptr); 48 struct Scsi_Host *instance = cmd->device->host; 49 50 /* don't allow DMA if the physical address is bad */ 51 if (addr & A2091_XFER_MASK) 52 { 53 HDATA(instance)->dma_bounce_len = (cmd->SCp.this_residual + 511) 54 & ~0x1ff; 55 HDATA(instance)->dma_bounce_buffer = 56 kmalloc (HDATA(instance)->dma_bounce_len, GFP_KERNEL); 57 58 /* can't allocate memory; use PIO */ 59 if (!HDATA(instance)->dma_bounce_buffer) { 60 HDATA(instance)->dma_bounce_len = 0; 61 return 1; 62 } 63 64 /* get the physical address of the bounce buffer */ 65 addr = virt_to_bus(HDATA(instance)->dma_bounce_buffer); 66 67 /* the bounce buffer may not be in the first 16M of physmem */ 68 if (addr & A2091_XFER_MASK) { 69 /* we could use chipmem... maybe later */ 70 kfree (HDATA(instance)->dma_bounce_buffer); 71 HDATA(instance)->dma_bounce_buffer = NULL; 72 HDATA(instance)->dma_bounce_len = 0; 73 return 1; 74 } 75 76 if (!dir_in) { 77 /* copy to bounce buffer for a write */ 78 memcpy (HDATA(instance)->dma_bounce_buffer, 79 cmd->SCp.ptr, cmd->SCp.this_residual); 80 } 81 } 82 83 /* setup dma direction */ 84 if (!dir_in) 85 cntr |= CNTR_DDIR; 86 87 /* remember direction */ 88 HDATA(cmd->device->host)->dma_dir = dir_in; 89 90 DMA(cmd->device->host)->CNTR = cntr; 91 92 /* setup DMA *physical* address */ 93 DMA(cmd->device->host)->ACR = addr; 94 95 if (dir_in){ 96 /* invalidate any cache */ 97 cache_clear (addr, cmd->SCp.this_residual); 98 }else{ 99 /* push any dirty cache */ 100 cache_push (addr, cmd->SCp.this_residual); 101 } 102 /* start DMA */ 103 DMA(cmd->device->host)->ST_DMA = 1; 104 105 /* return success */ 106 return 0; 107 } 108 109 static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 110 int status) 111 { 112 /* disable SCSI interrupts */ 113 unsigned short cntr = CNTR_PDMD; 114 115 if (!HDATA(instance)->dma_dir) 116 cntr |= CNTR_DDIR; 117 118 /* disable SCSI interrupts */ 119 DMA(instance)->CNTR = cntr; 120 121 /* flush if we were reading */ 122 if (HDATA(instance)->dma_dir) { 123 DMA(instance)->FLUSH = 1; 124 while (!(DMA(instance)->ISTR & ISTR_FE_FLG)) 125 ; 126 } 127 128 /* clear a possible interrupt */ 129 DMA(instance)->CINT = 1; 130 131 /* stop DMA */ 132 DMA(instance)->SP_DMA = 1; 133 134 /* restore the CONTROL bits (minus the direction flag) */ 135 DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN; 136 137 /* copy from a bounce buffer, if necessary */ 138 if (status && HDATA(instance)->dma_bounce_buffer) { 139 if( HDATA(instance)->dma_dir ) 140 memcpy (SCpnt->SCp.ptr, 141 HDATA(instance)->dma_bounce_buffer, 142 SCpnt->SCp.this_residual); 143 kfree (HDATA(instance)->dma_bounce_buffer); 144 HDATA(instance)->dma_bounce_buffer = NULL; 145 HDATA(instance)->dma_bounce_len = 0; 146 } 147 } 148 149 static int __init a2091_detect(struct scsi_host_template *tpnt) 150 { 151 static unsigned char called = 0; 152 struct Scsi_Host *instance; 153 unsigned long address; 154 struct zorro_dev *z = NULL; 155 wd33c93_regs regs; 156 int num_a2091 = 0; 157 158 if (!MACH_IS_AMIGA || called) 159 return 0; 160 called = 1; 161 162 tpnt->proc_name = "A2091"; 163 tpnt->proc_info = &wd33c93_proc_info; 164 165 while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { 166 if (z->id != ZORRO_PROD_CBM_A590_A2091_1 && 167 z->id != ZORRO_PROD_CBM_A590_A2091_2) 168 continue; 169 address = z->resource.start; 170 if (!request_mem_region(address, 256, "wd33c93")) 171 continue; 172 173 instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata)); 174 if (instance == NULL) 175 goto release; 176 instance->base = ZTWO_VADDR(address); 177 instance->irq = IRQ_AMIGA_PORTS; 178 instance->unique_id = z->slotaddr; 179 DMA(instance)->DAWR = DAWR_A2091; 180 regs.SASR = &(DMA(instance)->SASR); 181 regs.SCMD = &(DMA(instance)->SCMD); 182 HDATA(instance)->no_sync = 0xff; 183 HDATA(instance)->fast = 0; 184 HDATA(instance)->dma_mode = CTRL_DMA; 185 wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10); 186 if (request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, "A2091 SCSI", 187 instance)) 188 goto unregister; 189 DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN; 190 num_a2091++; 191 continue; 192 193 unregister: 194 scsi_unregister(instance); 195 wd33c93_release(); 196 release: 197 release_mem_region(address, 256); 198 } 199 200 return num_a2091; 201 } 202 203 static int a2091_bus_reset(struct scsi_cmnd *cmd) 204 { 205 /* FIXME perform bus-specific reset */ 206 207 /* FIXME 2: kill this function, and let midlayer fall back 208 to the same action, calling wd33c93_host_reset() */ 209 210 spin_lock_irq(cmd->device->host->host_lock); 211 wd33c93_host_reset(cmd); 212 spin_unlock_irq(cmd->device->host->host_lock); 213 214 return SUCCESS; 215 } 216 217 #define HOSTS_C 218 219 static struct scsi_host_template driver_template = { 220 .proc_name = "A2901", 221 .name = "Commodore A2091/A590 SCSI", 222 .detect = a2091_detect, 223 .release = a2091_release, 224 .queuecommand = wd33c93_queuecommand, 225 .eh_abort_handler = wd33c93_abort, 226 .eh_bus_reset_handler = a2091_bus_reset, 227 .eh_host_reset_handler = wd33c93_host_reset, 228 .can_queue = CAN_QUEUE, 229 .this_id = 7, 230 .sg_tablesize = SG_ALL, 231 .cmd_per_lun = CMD_PER_LUN, 232 .use_clustering = DISABLE_CLUSTERING 233 }; 234 235 236 #include "scsi_module.c" 237 238 static int a2091_release(struct Scsi_Host *instance) 239 { 240 #ifdef MODULE 241 DMA(instance)->CNTR = 0; 242 release_mem_region(ZTWO_PADDR(instance->base), 256); 243 free_irq(IRQ_AMIGA_PORTS, instance); 244 wd33c93_release(); 245 #endif 246 return 1; 247 } 248 249 MODULE_LICENSE("GPL"); 250