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 466f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_sbus_setup_dma(struct esp *esp, struct platform_device *dma_of) 47334ae614772b1147435dce9be3911f9040dff0d9David S. Miller{ 48334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dma = dma_of; 49cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 50334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dma_regs = of_ioremap(&dma_of->resource[0], 0, 51334ae614772b1147435dce9be3911f9040dff0d9David S. Miller resource_size(&dma_of->resource[0]), 52334ae614772b1147435dce9be3911f9040dff0d9David S. Miller "espdma"); 53334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (!esp->dma_regs) 54334ae614772b1147435dce9be3911f9040dff0d9David S. Miller return -ENOMEM; 55cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 56334ae614772b1147435dce9be3911f9040dff0d9David S. Miller switch (dma_read32(DMA_CSR) & DMA_DEVICE_ID) { 57334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERS0: 58334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmarev0; 59334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 60334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_ESCV1: 61334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmaesc1; 62334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 63334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERS1: 64334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmarev1; 65334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 66334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERS2: 67334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmarev2; 68334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 69334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERHME: 70334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmahme; 71334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 72334ae614772b1147435dce9be3911f9040dff0d9David S. Miller case DMA_VERSPLUS: 73334ae614772b1147435dce9be3911f9040dff0d9David S. Miller esp->dmarev = dvmarevplus; 74334ae614772b1147435dce9be3911f9040dff0d9David S. Miller break; 75cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 76cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 77cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 78cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 79cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 80cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 816f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_sbus_map_regs(struct esp *esp, int hme) 82cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 832dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 84cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct resource *res; 85cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 86cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* On HME, two reg sets exist, first is DVMA, 87cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * second is ESP registers. 88cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller */ 89cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (hme) 9005bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller res = &op->resource[1]; 91cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else 9205bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller res = &op->resource[0]; 93cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 9405bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller esp->regs = of_ioremap(res, 0, SBUS_ESP_REG_SIZE, "ESP"); 95cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!esp->regs) 96cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return -ENOMEM; 97cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 98cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 99cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 100cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1016f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_sbus_map_command_block(struct esp *esp) 102cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 1032dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 104cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 10505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller esp->command_block = dma_alloc_coherent(&op->dev, 16, 106738f2b7b813913e651f39387d007dd961755dee2David S. Miller &esp->command_block_dma, 107738f2b7b813913e651f39387d007dd961755dee2David S. Miller GFP_ATOMIC); 108cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!esp->command_block) 109cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return -ENOMEM; 110cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 111cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 112cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1136f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_sbus_register_irq(struct esp *esp) 114cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 115cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct Scsi_Host *host = esp->host; 1162dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 117cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1181636f8ac2b08410df4766449f7c86b912443cd99Grant Likely host->irq = op->archdata.irqs[0]; 119cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp); 120cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 121cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1226f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic void esp_get_scsi_id(struct esp *esp, struct platform_device *espdma) 123cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 1242dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 12505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller struct device_node *dp; 126cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 12761c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dp = op->dev.of_node; 128cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->scsi_id = of_getintprop_default(dp, "initiator-id", 0xff); 129cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (esp->scsi_id != 0xff) 130cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto done; 131cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 132cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->scsi_id = of_getintprop_default(dp, "scsi-initiator-id", 0xff); 133cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (esp->scsi_id != 0xff) 134cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto done; 135cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 13661c7a080a5a061c976988fd4b844dfb468dda255Grant Likely esp->scsi_id = of_getintprop_default(espdma->dev.of_node, 137cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller "scsi-initiator-id", 7); 138cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 139cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerdone: 140cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->host->this_id = esp->scsi_id; 141cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->scsi_id_mask = (1 << esp->scsi_id); 142cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 143cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1446f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic void esp_get_differential(struct esp *esp) 145cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 1462dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 14705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller struct device_node *dp; 148cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 14961c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dp = op->dev.of_node; 150cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (of_find_property(dp, "differential", NULL)) 151cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->flags |= ESP_FLAG_DIFFERENTIAL; 152cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else 153cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->flags &= ~ESP_FLAG_DIFFERENTIAL; 154cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 155cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1566f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic void esp_get_clock_params(struct esp *esp) 157cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 1582dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 15905bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller struct device_node *bus_dp, *dp; 160cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int fmhz; 161cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 16261c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dp = op->dev.of_node; 16305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller bus_dp = dp->parent; 164cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 165cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller fmhz = of_getintprop_default(dp, "clock-frequency", 0); 166cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (fmhz == 0) 16705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller fmhz = of_getintprop_default(bus_dp, "clock-frequency", 0); 168cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 169cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->cfreq = fmhz; 170cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 171cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1726f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic void esp_get_bursts(struct esp *esp, struct platform_device *dma_of) 173cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 17461c7a080a5a061c976988fd4b844dfb468dda255Grant Likely struct device_node *dma_dp = dma_of->dev.of_node; 1752dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 176334ae614772b1147435dce9be3911f9040dff0d9David S. Miller struct device_node *dp; 177334ae614772b1147435dce9be3911f9040dff0d9David S. Miller u8 bursts, val; 178cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 17961c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dp = op->dev.of_node; 180cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller bursts = of_getintprop_default(dp, "burst-sizes", 0xff); 181334ae614772b1147435dce9be3911f9040dff0d9David S. Miller val = of_getintprop_default(dma_dp, "burst-sizes", 0xff); 182334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (val != 0xff) 183334ae614772b1147435dce9be3911f9040dff0d9David S. Miller bursts &= val; 184cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 18505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller val = of_getintprop_default(dma_dp->parent, "burst-sizes", 0xff); 18605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller if (val != 0xff) 18705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller bursts &= val; 188cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 189cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (bursts == 0xff || 190cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller (bursts & DMA_BURST16) == 0 || 191cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller (bursts & DMA_BURST32) == 0) 192cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller bursts = (DMA_BURST32 - 1); 193cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 194cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->bursts = bursts; 195cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 196cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 1976f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic void esp_sbus_get_props(struct esp *esp, struct platform_device *espdma) 198cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 19905bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller esp_get_scsi_id(esp, espdma); 200cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp_get_differential(esp); 201cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp_get_clock_params(esp); 202cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp_get_bursts(esp, espdma); 203cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 204cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 205cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_write8(struct esp *esp, u8 val, unsigned long reg) 206cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 207cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_writeb(val, esp->regs + (reg * 4UL)); 208cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 209cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 210cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic u8 sbus_esp_read8(struct esp *esp, unsigned long reg) 211cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 212cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return sbus_readb(esp->regs + (reg * 4UL)); 213cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 214cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 215cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic dma_addr_t sbus_esp_map_single(struct esp *esp, void *buf, 216cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller size_t sz, int dir) 217cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 2182dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 2197a715f46012f3552294154978aed59cba9804928David S. Miller 22005bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller return dma_map_single(&op->dev, buf, sz, dir); 221cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 222cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 223cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int sbus_esp_map_sg(struct esp *esp, struct scatterlist *sg, 224cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int num_sg, int dir) 225cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 2262dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 2277a715f46012f3552294154978aed59cba9804928David S. Miller 22805bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller return dma_map_sg(&op->dev, sg, num_sg, dir); 229cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 230cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 231cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_unmap_single(struct esp *esp, dma_addr_t addr, 232cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller size_t sz, int dir) 233cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 2342dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 2357a715f46012f3552294154978aed59cba9804928David S. Miller 23605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dma_unmap_single(&op->dev, addr, sz, dir); 237cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 238cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 239cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_unmap_sg(struct esp *esp, struct scatterlist *sg, 240cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int num_sg, int dir) 241cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 2422dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op = esp->dev; 2437a715f46012f3552294154978aed59cba9804928David S. Miller 24405bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dma_unmap_sg(&op->dev, sg, num_sg, dir); 245cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 246cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 247cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int sbus_esp_irq_pending(struct esp *esp) 248cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 249cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (dma_read32(DMA_CSR) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)) 250cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 1; 251cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 252cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 253cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 254cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_reset_dma(struct esp *esp) 255cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 256cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int can_do_burst16, can_do_burst32, can_do_burst64; 257cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int can_do_sbus64, lim; 2582dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *op; 259cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 val; 260cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 261cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_burst16 = (esp->bursts & DMA_BURST16) != 0; 262cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_burst32 = (esp->bursts & DMA_BURST32) != 0; 263cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_burst64 = 0; 264cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_sbus64 = 0; 26505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller op = esp->dev; 26663237eeb5ac92d618a0a6055f4b1f65c5d14682bDavid S. Miller if (sbus_can_dma_64bit()) 267cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_sbus64 = 1; 26863237eeb5ac92d618a0a6055f4b1f65c5d14682bDavid S. Miller if (sbus_can_burst64()) 269cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller can_do_burst64 = (esp->bursts & DMA_BURST64) != 0; 270cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 271cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* Put the DVMA into a known state. */ 272334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev != dvmahme) { 273cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 274cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val | DMA_RST_SCSI, DMA_CSR); 275cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val & ~DMA_RST_SCSI, DMA_CSR); 276cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 277334ae614772b1147435dce9be3911f9040dff0d9David S. Miller switch (esp->dmarev) { 278cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller case dvmahme: 279cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(DMA_RESET_FAS366, DMA_CSR); 280cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(DMA_RST_SCSI, DMA_CSR); 281cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 282cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr = (DMA_PARITY_OFF | DMA_2CLKS | 283cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller DMA_SCSI_DISAB | DMA_INT_ENAB); 284cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 285cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr &= ~(DMA_ENABLE | DMA_ST_WRITE | 286cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller DMA_BRST_SZ); 287cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 288cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (can_do_burst64) 289cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr |= DMA_BRST64; 290cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else if (can_do_burst32) 291cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr |= DMA_BRST32; 292cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 293cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (can_do_sbus64) { 294cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr |= DMA_SCSI_SBUS64; 29505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller sbus_set_sbus64(&op->dev, esp->bursts); 296cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 297cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 298cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller lim = 1000; 299cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller while (dma_read32(DMA_CSR) & DMA_PEND_READ) { 300cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (--lim == 0) { 301cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller printk(KERN_ALERT PFX "esp%d: DMA_PEND_READ " 302cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller "will not clear!\n", 303cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->host->unique_id); 304cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 305cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 306cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller udelay(1); 307cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 308cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 309cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(0, DMA_CSR); 310cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(esp->prev_hme_dmacsr, DMA_CSR); 311cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 312cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(0, DMA_ADDR); 313cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 314cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 315cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller case dvmarev2: 316cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (esp->rev != ESP100) { 317cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 318cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val | DMA_3CLKS, DMA_CSR); 319cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 320cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 321cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 322cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller case dvmarev3: 323cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 324cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~DMA_3CLKS; 325cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_2CLKS; 326cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (can_do_burst32) { 327cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~DMA_BRST_SZ; 328cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_BRST32; 329cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 330cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val, DMA_CSR); 331cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 332cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 333cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller case dvmaesc1: 334cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 335cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_ADD_ENABLE; 336cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~DMA_BCNT_ENAB; 337cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!can_do_burst32 && can_do_burst16) { 338cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_ESC_BURST; 339cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } else { 340cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~(DMA_ESC_BURST); 341cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 342cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val, DMA_CSR); 343cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 344cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 345cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller default: 346cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 347cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 348cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 349cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* Enable interrupts. */ 350cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 351cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val | DMA_INT_ENAB, DMA_CSR); 352cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 353cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 354cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_dma_drain(struct esp *esp) 355cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 356cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 csr; 357cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int lim; 358cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 359334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev == dvmahme) 360cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return; 361cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 362cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr = dma_read32(DMA_CSR); 363cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!(csr & DMA_FIFO_ISDRAIN)) 364cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return; 365cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 366334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev != dvmarev3 && esp->dmarev != dvmaesc1) 367cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR); 368cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 369cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller lim = 1000; 370cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller while (dma_read32(DMA_CSR) & DMA_FIFO_ISDRAIN) { 371cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (--lim == 0) { 372cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller printk(KERN_ALERT PFX "esp%d: DMA will not drain!\n", 373cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->host->unique_id); 374cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 375cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 376cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller udelay(1); 377cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 378cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 379cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 380cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_dma_invalidate(struct esp *esp) 381cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 382334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev == dvmahme) { 383cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(DMA_RST_SCSI, DMA_CSR); 384cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 385cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr = ((esp->prev_hme_dmacsr | 386cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller (DMA_PARITY_OFF | DMA_2CLKS | 387cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller DMA_SCSI_DISAB | DMA_INT_ENAB)) & 388cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller ~(DMA_ST_WRITE | DMA_ENABLE)); 389cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 390cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(0, DMA_CSR); 391cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(esp->prev_hme_dmacsr, DMA_CSR); 392cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 393cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* This is necessary to avoid having the SCSI channel 394cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * engine lock up on us. 395cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller */ 396cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(0, DMA_ADDR); 397cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } else { 398cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 val; 399cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int lim; 400cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 401cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller lim = 1000; 402cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller while ((val = dma_read32(DMA_CSR)) & DMA_PEND_READ) { 403cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (--lim == 0) { 404cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller printk(KERN_ALERT PFX "esp%d: DMA will not " 405cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller "invalidate!\n", esp->host->unique_id); 406cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller break; 407cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 408cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller udelay(1); 409cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 410cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 411cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~(DMA_ENABLE | DMA_ST_WRITE | DMA_BCNT_ENAB); 412cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val |= DMA_FIFO_INV; 413cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val, DMA_CSR); 414cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val &= ~DMA_FIFO_INV; 415cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val, DMA_CSR); 416cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 417cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 418cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 419cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void sbus_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, 420cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 dma_count, int write, u8 cmd) 421cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 422cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 csr; 423cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 424cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller BUG_ON(!(cmd & ESP_CMD_DMA)); 425cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 426cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); 427cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); 428cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (esp->rev == FASHME) { 429cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_esp_write8(esp, (esp_count >> 16) & 0xff, FAS_RLO); 430cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller sbus_esp_write8(esp, 0, FAS_RHI); 431cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 432cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_esp_cmd(esp, cmd); 433cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 434cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr = esp->prev_hme_dmacsr; 435cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr |= DMA_SCSI_DISAB | DMA_ENABLE; 436cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (write) 437cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr |= DMA_ST_WRITE; 438cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else 439cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr &= ~DMA_ST_WRITE; 440cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->prev_hme_dmacsr = csr; 441cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 442cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(dma_count, DMA_COUNT); 443cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(addr, DMA_ADDR); 444cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(csr, DMA_CSR); 445cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } else { 446cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr = dma_read32(DMA_CSR); 447cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr |= DMA_ENABLE; 448cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (write) 449cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr |= DMA_ST_WRITE; 450cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else 451cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller csr &= ~DMA_ST_WRITE; 452cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(csr, DMA_CSR); 453334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev == dvmaesc1) { 454cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 end = PAGE_ALIGN(addr + dma_count + 16U); 455cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(end - addr, DMA_COUNT); 456cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 457cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(addr, DMA_ADDR); 458cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 459cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_esp_cmd(esp, cmd); 460cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 461cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 462cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 463cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 464cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int sbus_esp_dma_error(struct esp *esp) 465cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 466cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 csr = dma_read32(DMA_CSR); 467cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 468cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (csr & DMA_HNDL_ERROR) 469cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 1; 470cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 471cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 472cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 473cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 474cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic const struct esp_driver_ops sbus_esp_ops = { 475cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .esp_write8 = sbus_esp_write8, 476cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .esp_read8 = sbus_esp_read8, 477cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .map_single = sbus_esp_map_single, 478cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .map_sg = sbus_esp_map_sg, 479cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .unmap_single = sbus_esp_unmap_single, 480cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .unmap_sg = sbus_esp_unmap_sg, 481cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .irq_pending = sbus_esp_irq_pending, 482cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .reset_dma = sbus_esp_reset_dma, 483cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .dma_drain = sbus_esp_dma_drain, 484cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .dma_invalidate = sbus_esp_dma_invalidate, 485cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .send_dma_cmd = sbus_esp_send_dma_cmd, 486cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .dma_error = sbus_esp_dma_error, 487cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller}; 488cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 4896f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_sbus_probe_one(struct platform_device *op, 4906f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartman struct platform_device *espdma, int hme) 491cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 492cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct scsi_host_template *tpnt = &scsi_esp_template; 493cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct Scsi_Host *host; 494cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller struct esp *esp; 495cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int err; 496cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 497cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller host = scsi_host_alloc(tpnt, sizeof(struct esp)); 498cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 499cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller err = -ENOMEM; 500cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (!host) 501cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail; 502cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 503cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller host->max_id = (hme ? 16 : 8); 5042b14ec787869707843a14164a3ba91930a076031Christoph Hellwig esp = shost_priv(host); 505cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 506cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->host = host; 50705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller esp->dev = op; 508cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->ops = &sbus_esp_ops; 509cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 510cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (hme) 511cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp->flags |= ESP_FLAG_WIDE_CAPABLE; 512cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 513334ae614772b1147435dce9be3911f9040dff0d9David S. Miller err = esp_sbus_setup_dma(esp, espdma); 514cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err < 0) 515cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_unlink; 516cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 517cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller err = esp_sbus_map_regs(esp, hme); 518cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err < 0) 519cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_unlink; 520cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 521cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller err = esp_sbus_map_command_block(esp); 522cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err < 0) 523cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_unmap_regs; 524cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 525cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller err = esp_sbus_register_irq(esp); 526cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err < 0) 527cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_unmap_command_block; 528cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 529cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller esp_sbus_get_props(esp, espdma); 530cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 531cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* Before we try to touch the ESP chip, ESC1 dma can 532cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * come up with the reset bit set, so make sure that 533cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller * is clear first. 534cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller */ 535334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (esp->dmarev == dvmaesc1) { 536cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 val = dma_read32(DMA_CSR); 537cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 538cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val & ~DMA_RST_SCSI, DMA_CSR); 539cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 540cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 54105bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dev_set_drvdata(&op->dev, esp); 542cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 54305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller err = scsi_esp_register(esp, &op->dev); 544cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (err) 545cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller goto fail_free_irq; 546cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 547cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 548cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 549cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail_free_irq: 550cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller free_irq(host->irq, esp); 551cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail_unmap_command_block: 55205bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dma_free_coherent(&op->dev, 16, 553738f2b7b813913e651f39387d007dd961755dee2David S. Miller esp->command_block, 554738f2b7b813913e651f39387d007dd961755dee2David S. Miller esp->command_block_dma); 555cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail_unmap_regs: 55605bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller of_iounmap(&op->resource[(hme ? 1 : 0)], esp->regs, SBUS_ESP_REG_SIZE); 557cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail_unlink: 558cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_host_put(host); 559cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerfail: 560cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return err; 561cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 562cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 5636f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_sbus_probe(struct platform_device *op) 564cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 565334ae614772b1147435dce9be3911f9040dff0d9David S. Miller struct device_node *dma_node = NULL; 56661c7a080a5a061c976988fd4b844dfb468dda255Grant Likely struct device_node *dp = op->dev.of_node; 5672dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *dma_of = NULL; 568cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller int hme = 0; 569cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 570cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller if (dp->parent && 571cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller (!strcmp(dp->parent->name, "espdma") || 572cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller !strcmp(dp->parent->name, "dma"))) 573334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dma_node = dp->parent; 574cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller else if (!strcmp(dp->name, "SUNW,fas")) { 57561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely dma_node = op->dev.of_node; 576cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller hme = 1; 577cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller } 578334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (dma_node) 579334ae614772b1147435dce9be3911f9040dff0d9David S. Miller dma_of = of_find_device_by_node(dma_node); 580334ae614772b1147435dce9be3911f9040dff0d9David S. Miller if (!dma_of) 581334ae614772b1147435dce9be3911f9040dff0d9David S. Miller return -ENODEV; 582cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 58305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller return esp_sbus_probe_one(op, dma_of, hme); 584cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 585cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 5866f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartmanstatic int esp_sbus_remove(struct platform_device *op) 587cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 58805bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller struct esp *esp = dev_get_drvdata(&op->dev); 5892dc11581376829303b98eadb2de253bee065a56aGrant Likely struct platform_device *dma_of = esp->dma; 590cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller unsigned int irq = esp->host->irq; 59105bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller bool is_hme; 592cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller u32 val; 593cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 594cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_esp_unregister(esp); 595cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 596cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller /* Disable interrupts. */ 597cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller val = dma_read32(DMA_CSR); 598cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller dma_write32(val & ~DMA_INT_ENAB, DMA_CSR); 599cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 600cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller free_irq(irq, esp); 60105bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller 60205bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller is_hme = (esp->dmarev == dvmahme); 60305bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller 60405bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dma_free_coherent(&op->dev, 16, 605738f2b7b813913e651f39387d007dd961755dee2David S. Miller esp->command_block, 606738f2b7b813913e651f39387d007dd961755dee2David S. Miller esp->command_block_dma); 60705bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller of_iounmap(&op->resource[(is_hme ? 1 : 0)], esp->regs, 60805bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller SBUS_ESP_REG_SIZE); 609334ae614772b1147435dce9be3911f9040dff0d9David S. Miller of_iounmap(&dma_of->resource[0], esp->dma_regs, 610334ae614772b1147435dce9be3911f9040dff0d9David S. Miller resource_size(&dma_of->resource[0])); 611cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 612cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller scsi_host_put(esp->host); 613cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 61405bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller dev_set_drvdata(&op->dev, NULL); 61505bb5e93f2ef3f14e0c5a7e9281d07e7a7e4233dDavid S. Miller 616cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller return 0; 617cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 618cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 619fd098316ef533e8441576f020ead4beab93154ceDavid S. Millerstatic const struct of_device_id esp_match[] = { 620cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller { 621cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .name = "SUNW,esp", 622cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller }, 623cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller { 624cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .name = "SUNW,fas", 625cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller }, 626cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller { 627cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .name = "esp", 628cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller }, 629cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller {}, 630cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller}; 631cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_DEVICE_TABLE(of, esp_match); 632cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 6334ebb24f707187196937607c60810d42f7112d7aaGrant Likelystatic struct platform_driver esp_sbus_driver = { 6344018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .driver = { 6354018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .name = "esp", 6364018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .owner = THIS_MODULE, 6374018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .of_match_table = esp_match, 6384018294b53d1dae026880e45f174c1cc63b5d435Grant Likely }, 639cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller .probe = esp_sbus_probe, 6406f039790510fd630ff348efe8c4802dbaa041fbaGreg Kroah-Hartman .remove = esp_sbus_remove, 641cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller}; 642cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 643cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic int __init sunesp_init(void) 644cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 6454ebb24f707187196937607c60810d42f7112d7aaGrant Likely return platform_driver_register(&esp_sbus_driver); 646cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 647cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 648cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millerstatic void __exit sunesp_exit(void) 649cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller{ 6504ebb24f707187196937607c60810d42f7112d7aaGrant Likely platform_driver_unregister(&esp_sbus_driver); 651cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller} 652cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 653cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_DESCRIPTION("Sun ESP SCSI driver"); 654cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); 655cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_LICENSE("GPL"); 656cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. MillerMODULE_VERSION(DRV_VERSION); 657cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Miller 658cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millermodule_init(sunesp_init); 659cd9ad58d4061494e7fdd70ded7bcf2418daf356aDavid S. Millermodule_exit(sunesp_exit); 660