1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) 7 * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) 8 * Copyright (C) 2001 Florian Lohoff (flo@rfc822.org) 9 * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) 10 * 11 * (In all truth, Jed Schimmel wrote all this code.) 12 */ 13 #include <linux/init.h> 14 #include <linux/interrupt.h> 15 #include <linux/types.h> 16 #include <linux/mm.h> 17 #include <linux/blkdev.h> 18 #include <linux/version.h> 19 #include <linux/delay.h> 20 #include <linux/dma-mapping.h> 21 #include <linux/spinlock.h> 22 23 #include <asm/page.h> 24 #include <asm/pgtable.h> 25 #include <asm/sgialib.h> 26 #include <asm/sgi/sgi.h> 27 #include <asm/sgi/mc.h> 28 #include <asm/sgi/hpc3.h> 29 #include <asm/sgi/ip22.h> 30 #include <asm/irq.h> 31 #include <asm/io.h> 32 33 #include "scsi.h" 34 #include <scsi/scsi_host.h> 35 #include "wd33c93.h" 36 37 #include <linux/stat.h> 38 39 #if 0 40 #define DPRINTK(args...) printk(args) 41 #else 42 #define DPRINTK(args...) 43 #endif 44 45 #define HDATA(ptr) ((struct ip22_hostdata *)((ptr)->hostdata)) 46 47 struct ip22_hostdata { 48 struct WD33C93_hostdata wh; 49 struct hpc_data { 50 dma_addr_t dma; 51 void * cpu; 52 } hd; 53 }; 54 55 struct hpc_chunk { 56 struct hpc_dma_desc desc; 57 u32 _padding; /* align to quadword boundary */ 58 }; 59 60 struct Scsi_Host *sgiwd93_host; 61 struct Scsi_Host *sgiwd93_host1; 62 63 /* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */ 64 static inline void write_wd33c93_count(const wd33c93_regs regs, 65 unsigned long value) 66 { 67 *regs.SASR = WD_TRANSFER_COUNT_MSB; 68 mb(); 69 *regs.SCMD = ((value >> 16) & 0xff); 70 *regs.SCMD = ((value >> 8) & 0xff); 71 *regs.SCMD = ((value >> 0) & 0xff); 72 mb(); 73 } 74 75 static inline unsigned long read_wd33c93_count(const wd33c93_regs regs) 76 { 77 unsigned long value; 78 79 *regs.SASR = WD_TRANSFER_COUNT_MSB; 80 mb(); 81 value = ((*regs.SCMD & 0xff) << 16); 82 value |= ((*regs.SCMD & 0xff) << 8); 83 value |= ((*regs.SCMD & 0xff) << 0); 84 mb(); 85 return value; 86 } 87 88 static irqreturn_t sgiwd93_intr(int irq, void *dev_id, struct pt_regs *regs) 89 { 90 struct Scsi_Host * host = (struct Scsi_Host *) dev_id; 91 unsigned long flags; 92 93 spin_lock_irqsave(host->host_lock, flags); 94 wd33c93_intr(host); 95 spin_unlock_irqrestore(host->host_lock, flags); 96 97 return IRQ_HANDLED; 98 } 99 100 static inline 101 void fill_hpc_entries(struct hpc_chunk *hcp, Scsi_Cmnd *cmd, int datainp) 102 { 103 unsigned long len = cmd->SCp.this_residual; 104 void *addr = cmd->SCp.ptr; 105 dma_addr_t physaddr; 106 unsigned long count; 107 108 physaddr = dma_map_single(NULL, addr, len, cmd->sc_data_direction); 109 cmd->SCp.dma_handle = physaddr; 110 111 while (len) { 112 /* 113 * even cntinfo could be up to 16383, without 114 * magic only 8192 works correctly 115 */ 116 count = len > 8192 ? 8192 : len; 117 hcp->desc.pbuf = physaddr; 118 hcp->desc.cntinfo = count; 119 hcp++; 120 len -= count; 121 physaddr += count; 122 } 123 124 /* 125 * To make sure, if we trip an HPC bug, that we transfer every single 126 * byte, we tag on an extra zero length dma descriptor at the end of 127 * the chain. 128 */ 129 hcp->desc.pbuf = 0; 130 hcp->desc.cntinfo = HPCDMA_EOX; 131 } 132 133 static int dma_setup(Scsi_Cmnd *cmd, int datainp) 134 { 135 struct ip22_hostdata *hdata = HDATA(cmd->device->host); 136 struct hpc3_scsiregs *hregs = 137 (struct hpc3_scsiregs *) cmd->device->host->base; 138 struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; 139 140 DPRINTK("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); 141 142 hdata->wh.dma_dir = datainp; 143 144 /* 145 * wd33c93 shouldn't pass us bogus dma_setups, but it does:-( The 146 * other wd33c93 drivers deal with it the same way (which isn't that 147 * obvious). IMHO a better fix would be, not to do these dma setups 148 * in the first place. 149 */ 150 if (cmd->SCp.ptr == NULL || cmd->SCp.this_residual == 0) 151 return 1; 152 153 fill_hpc_entries(hcp, cmd, datainp); 154 155 DPRINTK(" HPCGO\n"); 156 157 /* Start up the HPC. */ 158 hregs->ndptr = hdata->hd.dma; 159 if (datainp) 160 hregs->ctrl = HPC3_SCTRL_ACTIVE; 161 else 162 hregs->ctrl = HPC3_SCTRL_ACTIVE | HPC3_SCTRL_DIR; 163 164 return 0; 165 } 166 167 static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, 168 int status) 169 { 170 struct ip22_hostdata *hdata = HDATA(instance); 171 struct hpc3_scsiregs *hregs; 172 173 if (!SCpnt) 174 return; 175 176 hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; 177 178 DPRINTK("dma_stop: status<%d> ", status); 179 180 /* First stop the HPC and flush it's FIFO. */ 181 if (hdata->wh.dma_dir) { 182 hregs->ctrl |= HPC3_SCTRL_FLUSH; 183 while (hregs->ctrl & HPC3_SCTRL_ACTIVE) 184 barrier(); 185 } 186 hregs->ctrl = 0; 187 dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, 188 SCpnt->sc_data_direction); 189 190 DPRINTK("\n"); 191 } 192 193 void sgiwd93_reset(unsigned long base) 194 { 195 struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) base; 196 197 hregs->ctrl = HPC3_SCTRL_CRESET; 198 udelay(50); 199 hregs->ctrl = 0; 200 } 201 202 static inline void init_hpc_chain(struct hpc_data *hd) 203 { 204 struct hpc_chunk *hcp = (struct hpc_chunk *) hd->cpu; 205 struct hpc_chunk *dma = (struct hpc_chunk *) hd->dma; 206 unsigned long start, end; 207 208 start = (unsigned long) hcp; 209 end = start + PAGE_SIZE; 210 while (start < end) { 211 hcp->desc.pnext = (u32) (dma + 1); 212 hcp->desc.cntinfo = HPCDMA_EOX; 213 hcp++; dma++; 214 start += sizeof(struct hpc_chunk); 215 }; 216 hcp--; 217 hcp->desc.pnext = hd->dma; 218 } 219 220 static struct Scsi_Host * __init sgiwd93_setup_scsi( 221 Scsi_Host_Template *SGIblows, int unit, int irq, 222 struct hpc3_scsiregs *hregs, unsigned char *wdregs) 223 { 224 struct ip22_hostdata *hdata; 225 struct Scsi_Host *host; 226 wd33c93_regs regs; 227 228 host = scsi_register(SGIblows, sizeof(struct ip22_hostdata)); 229 if (!host) 230 return NULL; 231 232 host->base = (unsigned long) hregs; 233 host->irq = irq; 234 235 hdata = HDATA(host); 236 hdata->hd.cpu = dma_alloc_coherent(NULL, PAGE_SIZE, &hdata->hd.dma, 237 GFP_KERNEL); 238 if (!hdata->hd.cpu) { 239 printk(KERN_WARNING "sgiwd93: Could not allocate memory for " 240 "host %d buffer.\n", unit); 241 goto out_unregister; 242 } 243 init_hpc_chain(&hdata->hd); 244 245 regs.SASR = wdregs + 3; 246 regs.SCMD = wdregs + 7; 247 248 wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_16_20); 249 250 hdata->wh.no_sync = 0; 251 252 if (request_irq(irq, sgiwd93_intr, 0, "SGI WD93", (void *) host)) { 253 printk(KERN_WARNING "sgiwd93: Could not register irq %d " 254 "for host %d.\n", irq, unit); 255 goto out_free; 256 } 257 return host; 258 259 out_free: 260 dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); 261 wd33c93_release(); 262 263 out_unregister: 264 scsi_unregister(host); 265 266 return NULL; 267 } 268 269 int __init sgiwd93_detect(Scsi_Host_Template *SGIblows) 270 { 271 int found = 0; 272 273 SGIblows->proc_name = "SGIWD93"; 274 sgiwd93_host = sgiwd93_setup_scsi(SGIblows, 0, SGI_WD93_0_IRQ, 275 &hpc3c0->scsi_chan0, 276 (unsigned char *)hpc3c0->scsi0_ext); 277 if (sgiwd93_host) 278 found++; 279 280 /* Set up second controller on the Indigo2 */ 281 if (ip22_is_fullhouse()) { 282 sgiwd93_host1 = sgiwd93_setup_scsi(SGIblows, 1, SGI_WD93_1_IRQ, 283 &hpc3c0->scsi_chan1, 284 (unsigned char *)hpc3c0->scsi1_ext); 285 if (sgiwd93_host1) 286 found++; 287 } 288 289 return found; 290 } 291 292 int sgiwd93_release(struct Scsi_Host *instance) 293 { 294 struct ip22_hostdata *hdata = HDATA(instance); 295 int irq = 0; 296 297 if (sgiwd93_host && sgiwd93_host == instance) 298 irq = SGI_WD93_0_IRQ; 299 else if (sgiwd93_host1 && sgiwd93_host1 == instance) 300 irq = SGI_WD93_1_IRQ; 301 302 free_irq(irq, sgiwd93_intr); 303 dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); 304 wd33c93_release(); 305 306 return 1; 307 } 308 309 static int sgiwd93_bus_reset(Scsi_Cmnd *cmd) 310 { 311 /* FIXME perform bus-specific reset */ 312 313 /* FIXME 2: kill this function, and let midlayer fallback 314 to the same result, calling wd33c93_host_reset() */ 315 316 spin_lock_irq(cmd->device->host->host_lock); 317 wd33c93_host_reset(cmd); 318 spin_unlock_irq(cmd->device->host->host_lock); 319 320 return SUCCESS; 321 } 322 323 /* 324 * Kludge alert - the SCSI code calls the abort and reset method with int 325 * arguments not with pointers. So this is going to blow up beautyfully 326 * on 64-bit systems with memory outside the compat address spaces. 327 */ 328 static Scsi_Host_Template driver_template = { 329 .proc_name = "SGIWD93", 330 .name = "SGI WD93", 331 .detect = sgiwd93_detect, 332 .release = sgiwd93_release, 333 .queuecommand = wd33c93_queuecommand, 334 .eh_abort_handler = wd33c93_abort, 335 .eh_bus_reset_handler = sgiwd93_bus_reset, 336 .eh_host_reset_handler = wd33c93_host_reset, 337 .can_queue = 16, 338 .this_id = 7, 339 .sg_tablesize = SG_ALL, 340 .cmd_per_lun = 8, 341 .use_clustering = DISABLE_CLUSTERING, 342 }; 343 #include "scsi_module.c" 344