1cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller/* sun_esp.c: ESP front-end for Sparc SBUS systems. 2cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * 3334ae614772b1147435dce9be3911f9040dff0d9David S. Miller * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net) 4cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller */ 5cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 6cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include <linux/kernel.h> 7cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include <linux/types.h> 86025dfe5b2598056cd763a2b10ca7e7faffb2e16David S. Miller#include <linux/delay.h> 9cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include <linux/module.h> 1027ac792ca0b0a1e7e65f20342260650516c95864Andrea Righi#include <linux/mm.h> 11cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include <linux/init.h> 12738f2b7b813913e651f39387d007dd961755dee2David S. Miller#include <linux/dma-mapping.h> 1305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller#include <linux/of.h> 1405bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller#include <linux/of_device.h> 155a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h> 16cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 17cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include <asm/irq.h> 18cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include <asm/io.h> 19cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include <asm/dma.h> 20cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 21cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include <scsi/scsi_host.h> 22cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 23cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#include "esp_scsi.h" 24cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 25cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#define DRV_MODULE_NAME "sun_esp" 26cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#define PFX DRV_MODULE_NAME ": " 2705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller#define DRV_VERSION "1.100" 2805bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller#define DRV_MODULE_RELDATE "August 27, 2008" 29cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 30cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#define dma_read32(REG) \ 31cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_readl(esp->dma_regs + (REG)) 32cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller#define dma_write32(VAL, REG) \ 33cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_writel((VAL), esp->dma_regs + (REG)) 34cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 35334ae614772b1147435dce9be3911f9040dff0d9David S. Miller/* DVMA chip revisions */ 36334ae614772b1147435dce9be3911f9040dff0d9David S. Millerenum dvma_rev { 37334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dvmarev0, 38334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dvmaesc1, 39334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dvmarev1, 40334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dvmarev2, 41334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dvmarev3, 42334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dvmarevplus, 43334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dvmahme 44334ae614772b1147435dce9be3911f9040dff0d9David S. Miller}; 45cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 46334ae614772b1147435dce9be3911f9040dff0d9David S. Millerstatic int __devinit esp_sbus_setup_dma(struct esp *esp, 472dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *dma_of) 48334ae614772b1147435dce9be3911f9040dff0d9David S. Miller{ 49334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dma = dma_of; 50cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 51334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dma_regs = of_ioremap(&dma_of->resource[0], 0, 52334ae614772b1147435dce9be3911f9040dff0d9David S. Miller resource_size(&dma_of->resource[0]), 53334ae614772b1147435dce9be3911f9040dff0d9David S. Miller "espdma"); 54334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (!esp->dma_regs) 55334ae614772b1147435dce9be3911f9040dff0d9David S. Miller return -ENOMEM; 56cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 57334ae614772b1147435dce9be3911f9040dff0d9David S. Miller switch (dma_read32(DMA_CSR) & DMA_DEVICE_ID) { 58334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERS0: 59334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmarev0; 60334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 61334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_ESCV1: 62334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmaesc1; 63334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 64334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERS1: 65334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmarev1; 66334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 67334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERS2: 68334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmarev2; 69334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 70334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERHME: 71334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmahme; 72334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 73334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERSPLUS: 74334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmarevplus; 75334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 76cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 77cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 78cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 79cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 80cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 81cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 82cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int __devinit esp_sbus_map_regs(struct esp *esp, int hme) 83cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 842dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 85cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct resource *res; 86cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 87cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* On HME, two reg sets exist, first is DVMA, 88cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * second is ESP registers. 89cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller */ 90cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (hme) 9105bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller res = &op->resource[1]; 92cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else 9305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller res = &op->resource[0]; 94cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 9505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller esp->regs = of_ioremap(res, 0, SBUS_ESP_REG_SIZE, "ESP"); 96cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!esp->regs) 97cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return -ENOMEM; 98cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 99cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 100cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 101cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 102cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int __devinit esp_sbus_map_command_block(struct esp *esp) 103cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 1042dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 105cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 10605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller esp->command_block = dma_alloc_coherent(&op->dev, 16, 107738f2b7b813913e651f39387d007dd961755dee2David S. Miller &esp->command_block_dma, 108738f2b7b813913e651f39387d007dd961755dee2David S. Miller GFP_ATOMIC); 109cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!esp->command_block) 110cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return -ENOMEM; 111cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 112cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 113cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 114cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int __devinit esp_sbus_register_irq(struct esp *esp) 115cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 116cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct Scsi_Host *host = esp->host; 1172dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 118cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1191636f8ac2b08410df4766449f7c86b912443cd99Grant Likely host->irq = op->archdata.irqs[0]; 120cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp); 121cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 122cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1232dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic void __devinit esp_get_scsi_id(struct esp *esp, struct platform_device *espdma) 124cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 1252dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 12605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller struct device_node *dp; 127cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 12861c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dp = op->dev.of_node; 129cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->scsi_id = of_getintprop_default(dp, "initiator-id", 0xff); 130cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (esp->scsi_id != 0xff) 131cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto done; 132cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 133cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->scsi_id = of_getintprop_default(dp, "scsi-initiator-id", 0xff); 134cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (esp->scsi_id != 0xff) 135cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto done; 136cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 13761c7a080a5a061c976988fd4b844dfb468dda255Grant Likely esp->scsi_id = of_getintprop_default(espdma->dev.of_node, 138cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller "scsi-initiator-id", 7); 139cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 140cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerdone: 141cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->host->this_id = esp->scsi_id; 142cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->scsi_id_mask = (1 << esp->scsi_id); 143cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 144cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 145cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void __devinit esp_get_differential(struct esp *esp) 146cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 1472dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 14805bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller struct device_node *dp; 149cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 15061c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dp = op->dev.of_node; 151cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (of_find_property(dp, "differential", NULL)) 152cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->flags |= ESP_FLAG_DIFFERENTIAL; 153cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else 154cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->flags &= ~ESP_FLAG_DIFFERENTIAL; 155cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 156cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 157cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void __devinit esp_get_clock_params(struct esp *esp) 158cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 1592dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 16005bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller struct device_node *bus_dp, *dp; 161cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int fmhz; 162cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 16361c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dp = op->dev.of_node; 16405bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller bus_dp = dp->parent; 165cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 166cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller fmhz = of_getintprop_default(dp, "clock-frequency", 0); 167cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (fmhz == 0) 16805bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller fmhz = of_getintprop_default(bus_dp, "clock-frequency", 0); 169cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 170cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->cfreq = fmhz; 171cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 172cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1732dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic void __devinit esp_get_bursts(struct esp *esp, struct platform_device *dma_of) 174cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 17561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely struct device_node *dma_dp = dma_of->dev.of_node; 1762dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 177334ae614772b1147435dce9be3911f9040dff0d9David S. Miller struct device_node *dp; 178334ae614772b1147435dce9be3911f9040dff0d9David S. Miller u8 bursts, val; 179cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 18061c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dp = op->dev.of_node; 181cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller bursts = of_getintprop_default(dp, "burst-sizes", 0xff); 182334ae614772b1147435dce9be3911f9040dff0d9David S. Miller val = of_getintprop_default(dma_dp, "burst-sizes", 0xff); 183334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (val != 0xff) 184334ae614772b1147435dce9be3911f9040dff0d9David S. Miller bursts &= val; 185cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 18605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller val = of_getintprop_default(dma_dp->parent, "burst-sizes", 0xff); 18705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller if (val != 0xff) 18805bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller bursts &= val; 189cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 190cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (bursts == 0xff || 191cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller (bursts & DMA_BURST16) == 0 || 192cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller (bursts & DMA_BURST32) == 0) 193cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller bursts = (DMA_BURST32 - 1); 194cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 195cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->bursts = bursts; 196cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 197cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1982dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic void __devinit esp_sbus_get_props(struct esp *esp, struct platform_device *espdma) 199cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 20005bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller esp_get_scsi_id(esp, espdma); 201cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp_get_differential(esp); 202cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp_get_clock_params(esp); 203cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp_get_bursts(esp, espdma); 204cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 205cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 206cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_write8(struct esp *esp, u8 val, unsigned long reg) 207cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 208cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_writeb(val, esp->regs + (reg * 4UL)); 209cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 210cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 211cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic u8 sbus_esp_read8(struct esp *esp, unsigned long reg) 212cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 213cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return sbus_readb(esp->regs + (reg * 4UL)); 214cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 215cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 216cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic dma_addr_t sbus_esp_map_single(struct esp *esp, void *buf, 217cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller size_t sz, int dir) 218cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 2192dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 2207a715f46012f3552294154978aed59cba9804928David S. Miller 22105bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller return dma_map_single(&op->dev, buf, sz, dir); 222cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 223cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 224cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int sbus_esp_map_sg(struct esp *esp, struct scatterlist *sg, 225cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int num_sg, int dir) 226cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 2272dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 2287a715f46012f3552294154978aed59cba9804928David S. Miller 22905bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller return dma_map_sg(&op->dev, sg, num_sg, dir); 230cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 231cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 232cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_unmap_single(struct esp *esp, dma_addr_t addr, 233cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller size_t sz, int dir) 234cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 2352dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 2367a715f46012f3552294154978aed59cba9804928David S. Miller 23705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dma_unmap_single(&op->dev, addr, sz, dir); 238cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 239cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 240cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, 241cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int num_sg, int dir) 242cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 2432dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 2447a715f46012f3552294154978aed59cba9804928David S. Miller 24505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dma_unmap_sg(&op->dev, sg, num_sg, dir); 246cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 247cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 248cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int sbus_esp_irq_pending(struct esp *esp) 249cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 250cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (dma_read32(DMA_CSR) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)) 251cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 1; 252cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 253cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 254cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 255cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_reset_dma(struct esp *esp) 256cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 257cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int can_do_burst16, can_do_burst32, can_do_burst64; 258cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int can_do_sbus64, lim; 2592dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op; 260cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 val; 261cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 262cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_burst16 = (esp->bursts & DMA_BURST16) != 0; 263cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_burst32 = (esp->bursts & DMA_BURST32) != 0; 264cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_burst64 = 0; 265cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_sbus64 = 0; 26605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller op = esp->dev; 26763237eeb5ac92d618a0a6055f4b1f65c5d14682bDavid S. Miller if (sbus_can_dma_64bit()) 268cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_sbus64 = 1; 26963237eeb5ac92d618a0a6055f4b1f65c5d14682bDavid S. Miller if (sbus_can_burst64()) 270cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_burst64 = (esp->bursts & DMA_BURST64) != 0; 271cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 272cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* Put the DVMA into a known state. */ 273334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev != dvmahme) { 274cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 275cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val | DMA_RST_SCSI, DMA_CSR); 276cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val & ~DMA_RST_SCSI, DMA_CSR); 277cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 278334ae614772b1147435dce9be3911f9040dff0d9David S. Miller switch (esp->dmarev) { 279cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller case dvmahme: 280cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(DMA_RESET_FAS366, DMA_CSR); 281cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(DMA_RST_SCSI, DMA_CSR); 282cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 283cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr = (DMA_PARITY_OFF | DMA_2CLKS | 284cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller DMA_SCSI_DISAB | DMA_INT_ENAB); 285cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 286cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr &= ~(DMA_ENABLE | DMA_ST_WRITE | 287cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller DMA_BRST_SZ); 288cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 289cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (can_do_burst64) 290cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr |= DMA_BRST64; 291cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else if (can_do_burst32) 292cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr |= DMA_BRST32; 293cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 294cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (can_do_sbus64) { 295cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr |= DMA_SCSI_SBUS64; 29605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller sbus_set_sbus64(&op->dev, esp->bursts); 297cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 298cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 299cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller lim = 1000; 300cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller while (dma_read32(DMA_CSR) & DMA_PEND_READ) { 301cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (--lim == 0) { 302cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller printk(KERN_ALERT PFX "esp%d: DMA_PEND_READ " 303cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller "will not clear!\n", 304cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->host->unique_id); 305cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 306cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 307cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller udelay(1); 308cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 309cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 310cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(0, DMA_CSR); 311cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(esp->prev_hme_dmacsr, DMA_CSR); 312cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 313cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(0, DMA_ADDR); 314cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 315cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 316cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller case dvmarev2: 317cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (esp->rev != ESP100) { 318cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 319cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val | DMA_3CLKS, DMA_CSR); 320cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 321cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 322cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 323cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller case dvmarev3: 324cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 325cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~DMA_3CLKS; 326cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_2CLKS; 327cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (can_do_burst32) { 328cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~DMA_BRST_SZ; 329cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_BRST32; 330cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 331cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val, DMA_CSR); 332cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 333cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 334cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller case dvmaesc1: 335cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 336cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_ADD_ENABLE; 337cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~DMA_BCNT_ENAB; 338cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!can_do_burst32 && can_do_burst16) { 339cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_ESC_BURST; 340cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } else { 341cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~(DMA_ESC_BURST); 342cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 343cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val, DMA_CSR); 344cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 345cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 346cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller default: 347cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 348cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 349cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 350cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* Enable interrupts. */ 351cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 352cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val | DMA_INT_ENAB, DMA_CSR); 353cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 354cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 355cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_dma_drain(struct esp *esp) 356cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 357cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 csr; 358cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int lim; 359cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 360334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev == dvmahme) 361cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return; 362cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 363cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr = dma_read32(DMA_CSR); 364cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!(csr & DMA_FIFO_ISDRAIN)) 365cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return; 366cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 367334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev != dvmarev3 && esp->dmarev != dvmaesc1) 368cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR); 369cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 370cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller lim = 1000; 371cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller while (dma_read32(DMA_CSR) & DMA_FIFO_ISDRAIN) { 372cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (--lim == 0) { 373cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller printk(KERN_ALERT PFX "esp%d: DMA will not drain!\n", 374cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->host->unique_id); 375cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 376cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 377cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller udelay(1); 378cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 379cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 380cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 381cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_dma_invalidate(struct esp *esp) 382cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 383334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev == dvmahme) { 384cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(DMA_RST_SCSI, DMA_CSR); 385cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 386cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr | 387cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller (DMA_PARITY_OFF | DMA_2CLKS | 388cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller DMA_SCSI_DISAB | DMA_INT_ENAB)) & 389cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller ~(DMA_ST_WRITE | DMA_ENABLE)); 390cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 391cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(0, DMA_CSR); 392cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(esp->prev_hme_dmacsr, DMA_CSR); 393cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 394cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* This is necessary to avoid having the SCSI channel 395cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * engine lock up on us. 396cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller */ 397cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(0, DMA_ADDR); 398cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } else { 399cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 val; 400cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int lim; 401cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 402cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller lim = 1000; 403cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller while ((val = dma_read32(DMA_CSR)) & DMA_PEND_READ) { 404cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (--lim == 0) { 405cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller printk(KERN_ALERT PFX "esp%d: DMA will not " 406cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller "invalidate!\n", esp->host->unique_id); 407cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 408cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 409cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller udelay(1); 410cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 411cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 412cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~(DMA_ENABLE | DMA_ST_WRITE | DMA_BCNT_ENAB); 413cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_FIFO_INV; 414cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val, DMA_CSR); 415cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~DMA_FIFO_INV; 416cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val, DMA_CSR); 417cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 418cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 419cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 420cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, 421cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 dma_count, int write, u8 cmd) 422cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 423cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 csr; 424cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 425cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller BUG_ON(!(cmd & ESP_CMD_DMA)); 426cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 427cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); 428cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); 429cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (esp->rev == FASHME) { 430cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_esp_write8(esp, (esp_count >> 16) & 0xff, FAS_RLO); 431cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_esp_write8(esp, 0, FAS_RHI); 432cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 433cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_esp_cmd(esp, cmd); 434cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 435cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr = esp->prev_hme_dmacsr; 436cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr |= DMA_SCSI_DISAB | DMA_ENABLE; 437cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (write) 438cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr |= DMA_ST_WRITE; 439cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else 440cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr &= ~DMA_ST_WRITE; 441cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr = csr; 442cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 443cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(dma_count, DMA_COUNT); 444cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(addr, DMA_ADDR); 445cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(csr, DMA_CSR); 446cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } else { 447cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr = dma_read32(DMA_CSR); 448cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr |= DMA_ENABLE; 449cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (write) 450cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr |= DMA_ST_WRITE; 451cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else 452cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr &= ~DMA_ST_WRITE; 453cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(csr, DMA_CSR); 454334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev == dvmaesc1) { 455cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 end = PAGE_ALIGN(addr + dma_count + 16U); 456cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(end - addr, DMA_COUNT); 457cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 458cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(addr, DMA_ADDR); 459cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 460cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_esp_cmd(esp, cmd); 461cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 462cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 463cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 464cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 465cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int sbus_esp_dma_error(struct esp *esp) 466cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 467cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 csr = dma_read32(DMA_CSR); 468cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 469cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (csr & DMA_HNDL_ERROR) 470cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 1; 471cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 472cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 473cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 474cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 475cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic const struct esp_driver_ops sbus_esp_ops = { 476cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .esp_write8 = sbus_esp_write8, 477cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .esp_read8 = sbus_esp_read8, 478cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .map_single = sbus_esp_map_single, 479cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .map_sg = sbus_esp_map_sg, 480cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .unmap_single = sbus_esp_unmap_single, 481cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .unmap_sg = sbus_esp_unmap_sg, 482cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .irq_pending = sbus_esp_irq_pending, 483cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .reset_dma = sbus_esp_reset_dma, 484cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .dma_drain = sbus_esp_dma_drain, 485cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .dma_invalidate = sbus_esp_dma_invalidate, 486cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .send_dma_cmd = sbus_esp_send_dma_cmd, 487cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .dma_error = sbus_esp_dma_error, 488cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller}; 489cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 4902dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devinit esp_sbus_probe_one(struct platform_device *op, 4912dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *espdma, 492cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int hme) 493cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 494cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct scsi_host_template *tpnt = &scsi_esp_template; 495cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct Scsi_Host *host; 496cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct esp *esp; 497cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int err; 498cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 499cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller host = scsi_host_alloc(tpnt, sizeof(struct esp)); 500cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 501cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller err = -ENOMEM; 502cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!host) 503cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail; 504cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 505cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller host->max_id = (hme ? 16 : 8); 5062b14ec787869707843a14164a3ba91930a076031Christoph Hellwig esp = shost_priv(host); 507cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 508cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->host = host; 50905bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller esp->dev = op; 510cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->ops = &sbus_esp_ops; 511cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 512cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (hme) 513cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->flags |= ESP_FLAG_WIDE_CAPABLE; 514cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 515334ae614772b1147435dce9be3911f9040dff0d9David S. Miller err = esp_sbus_setup_dma(esp, espdma); 516cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err < 0) 517cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_unlink; 518cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 519cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller err = esp_sbus_map_regs(esp, hme); 520cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err < 0) 521cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_unlink; 522cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 523cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller err = esp_sbus_map_command_block(esp); 524cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err < 0) 525cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_unmap_regs; 526cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 527cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller err = esp_sbus_register_irq(esp); 528cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err < 0) 529cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_unmap_command_block; 530cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 531cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp_sbus_get_props(esp, espdma); 532cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 533cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* Before we try to touch the ESP chip, ESC1 dma can 534cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * come up with the reset bit set, so make sure that 535cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * is clear first. 536cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller */ 537334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev == dvmaesc1) { 538cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 val = dma_read32(DMA_CSR); 539cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 540cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val & ~DMA_RST_SCSI, DMA_CSR); 541cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 542cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 54305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dev_set_drvdata(&op->dev, esp); 544cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 54505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller err = scsi_esp_register(esp, &op->dev); 546cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err) 547cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_free_irq; 548cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 549cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 550cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 551cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail_free_irq: 552cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller free_irq(host->irq, esp); 553cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail_unmap_command_block: 55405bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dma_free_coherent(&op->dev, 16, 555738f2b7b813913e651f39387d007dd961755dee2David S. Miller esp->command_block, 556738f2b7b813913e651f39387d007dd961755dee2David S. Miller esp->command_block_dma); 557cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail_unmap_regs: 55805bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller of_iounmap(&op->resource[(hme ? 1 : 0)], esp->regs, SBUS_ESP_REG_SIZE); 559cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail_unlink: 560cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_host_put(host); 561cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail: 562cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return err; 563cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 564cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 5654ebb24f707187196937607c60810d42f7112d7aaGrant Likelystatic int __devinit esp_sbus_probe(struct platform_device *op) 566cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 567334ae614772b1147435dce9be3911f9040dff0d9David S. Miller struct device_node *dma_node = NULL; 56861c7a080a5a061c976988fd4b844dfb468dda255Grant Likely struct device_node *dp = op->dev.of_node; 5692dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *dma_of = NULL; 570cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int hme = 0; 571cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 572cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (dp->parent && 573cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller (!strcmp(dp->parent->name, "espdma") || 574cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller !strcmp(dp->parent->name, "dma"))) 575334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dma_node = dp->parent; 576cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else if (!strcmp(dp->name, "SUNW,fas")) { 57761c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dma_node = op->dev.of_node; 578cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller hme = 1; 579cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 580334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (dma_node) 581334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dma_of = of_find_device_by_node(dma_node); 582334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (!dma_of) 583334ae614772b1147435dce9be3911f9040dff0d9David S. Miller return -ENODEV; 584cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 58505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller return esp_sbus_probe_one(op, dma_of, hme); 586cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 587cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 5882dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devexit esp_sbus_remove(struct platform_device *op) 589cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 59005bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller struct esp *esp = dev_get_drvdata(&op->dev); 5912dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *dma_of = esp->dma; 592cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller unsigned int irq = esp->host->irq; 59305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller bool is_hme; 594cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 val; 595cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 596cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_esp_unregister(esp); 597cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 598cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* Disable interrupts. */ 599cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 600cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val & ~DMA_INT_ENAB, DMA_CSR); 601cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 602cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller free_irq(irq, esp); 60305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller 60405bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller is_hme = (esp->dmarev == dvmahme); 60505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller 60605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dma_free_coherent(&op->dev, 16, 607738f2b7b813913e651f39387d007dd961755dee2David S. Miller esp->command_block, 608738f2b7b813913e651f39387d007dd961755dee2David S. Miller esp->command_block_dma); 60905bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller of_iounmap(&op->resource[(is_hme ? 1 : 0)], esp->regs, 61005bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller SBUS_ESP_REG_SIZE); 611334ae614772b1147435dce9be3911f9040dff0d9David S. Miller of_iounmap(&dma_of->resource[0], esp->dma_regs, 612334ae614772b1147435dce9be3911f9040dff0d9David S. Miller resource_size(&dma_of->resource[0])); 613cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 614cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_host_put(esp->host); 615cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 61605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dev_set_drvdata(&op->dev, NULL); 61705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller 618cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 619cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 620cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 621fd098316ef533e8441576f020ead4beab93154ceDavid S. Millerstatic const struct of_device_id esp_match[] = { 622cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller { 623cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .name = "SUNW,esp", 624cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller }, 625cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller { 626cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .name = "SUNW,fas", 627cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller }, 628cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller { 629cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .name = "esp", 630cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller }, 631cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller {}, 632cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller}; 633cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_DEVICE_TABLE(of, esp_match); 634cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 6354ebb24f707187196937607c60810d42f7112d7aaGrant Likelystatic struct platform_driver esp_sbus_driver = { 6364018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .driver = { 6374018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .name = "esp", 6384018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .owner = THIS_MODULE, 6394018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .of_match_table = esp_match, 6404018294b53d1dae026880e45f174c1cc63b5d435Grant Likely }, 641cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .probe = esp_sbus_probe, 642cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .remove = __devexit_p(esp_sbus_remove), 643cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller}; 644cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 645cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int __init sunesp_init(void) 646cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 6474ebb24f707187196937607c60810d42f7112d7aaGrant Likely return platform_driver_register(&esp_sbus_driver); 648cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 649cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 650cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void __exit sunesp_exit(void) 651cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 6524ebb24f707187196937607c60810d42f7112d7aaGrant Likely platform_driver_unregister(&esp_sbus_driver); 653cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 654cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 655cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_DESCRIPTION("Sun ESP SCSI driver"); 656cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); 657cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_LICENSE("GPL"); 658cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_VERSION(DRV_VERSION); 659cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 660cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millermodule_init(sunesp_init); 661cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millermodule_exit(sunesp_exit); 662