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