linux/drivers/scsi/sun3x_esp.c
<<
>>
Prefs
   1/* sun3x_esp.c: ESP front-end for Sun3x systems.
   2 *
   3 * Copyright (C) 2007,2008 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
   4 */
   5
   6#include <linux/kernel.h>
   7#include <linux/gfp.h>
   8#include <linux/types.h>
   9#include <linux/delay.h>
  10#include <linux/module.h>
  11#include <linux/init.h>
  12#include <linux/platform_device.h>
  13#include <linux/dma-mapping.h>
  14#include <linux/interrupt.h>
  15
  16#include <asm/sun3x.h>
  17#include <asm/io.h>
  18#include <asm/dma.h>
  19#include <asm/dvma.h>
  20
  21/* DMA controller reg offsets */
  22#define DMA_CSR         0x00UL  /* rw  DMA control/status register    0x00   */
  23#define DMA_ADDR        0x04UL  /* rw  DMA transfer address register  0x04   */
  24#define DMA_COUNT       0x08UL  /* rw  DMA transfer count register    0x08   */
  25#define DMA_TEST        0x0cUL  /* rw  DMA test/debug register        0x0c   */
  26
  27#include <scsi/scsi_host.h>
  28
  29#include "esp_scsi.h"
  30
  31#define DRV_MODULE_NAME         "sun3x_esp"
  32#define PFX DRV_MODULE_NAME     ": "
  33#define DRV_VERSION             "1.000"
  34#define DRV_MODULE_RELDATE      "Nov 1, 2007"
  35
  36/*
  37 * m68k always assumes readl/writel operate on little endian
  38 * mmio space; this is wrong at least for Sun3x, so we
  39 * need to workaround this until a proper way is found
  40 */
  41#if 0
  42#define dma_read32(REG) \
  43        readl(esp->dma_regs + (REG))
  44#define dma_write32(VAL, REG) \
  45        writel((VAL), esp->dma_regs + (REG))
  46#else
  47#define dma_read32(REG) \
  48        *(volatile u32 *)(esp->dma_regs + (REG))
  49#define dma_write32(VAL, REG) \
  50        do { *(volatile u32 *)(esp->dma_regs + (REG)) = (VAL); } while (0)
  51#endif
  52
  53static void sun3x_esp_write8(struct esp *esp, u8 val, unsigned long reg)
  54{
  55        writeb(val, esp->regs + (reg * 4UL));
  56}
  57
  58static u8 sun3x_esp_read8(struct esp *esp, unsigned long reg)
  59{
  60        return readb(esp->regs + (reg * 4UL));
  61}
  62
  63static dma_addr_t sun3x_esp_map_single(struct esp *esp, void *buf,
  64                                      size_t sz, int dir)
  65{
  66        return dma_map_single(esp->dev, buf, sz, dir);
  67}
  68
  69static int sun3x_esp_map_sg(struct esp *esp, struct scatterlist *sg,
  70                                  int num_sg, int dir)
  71{
  72        return dma_map_sg(esp->dev, sg, num_sg, dir);
  73}
  74
  75static void sun3x_esp_unmap_single(struct esp *esp, dma_addr_t addr,
  76                                  size_t sz, int dir)
  77{
  78        dma_unmap_single(esp->dev, addr, sz, dir);
  79}
  80
  81static void sun3x_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
  82                              int num_sg, int dir)
  83{
  84        dma_unmap_sg(esp->dev, sg, num_sg, dir);
  85}
  86
  87static int sun3x_esp_irq_pending(struct esp *esp)
  88{
  89        if (dma_read32(DMA_CSR) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
  90                return 1;
  91        return 0;
  92}
  93
  94static void sun3x_esp_reset_dma(struct esp *esp)
  95{
  96        u32 val;
  97
  98        val = dma_read32(DMA_CSR);
  99        dma_write32(val | DMA_RST_SCSI, DMA_CSR);
 100        dma_write32(val & ~DMA_RST_SCSI, DMA_CSR);
 101
 102        /* Enable interrupts.  */
 103        val = dma_read32(DMA_CSR);
 104        dma_write32(val | DMA_INT_ENAB, DMA_CSR);
 105}
 106
 107static void sun3x_esp_dma_drain(struct esp *esp)
 108{
 109        u32 csr;
 110        int lim;
 111
 112        csr = dma_read32(DMA_CSR);
 113        if (!(csr & DMA_FIFO_ISDRAIN))
 114                return;
 115
 116        dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR);
 117
 118        lim = 1000;
 119        while (dma_read32(DMA_CSR) & DMA_FIFO_ISDRAIN) {
 120                if (--lim == 0) {
 121                        printk(KERN_ALERT PFX "esp%d: DMA will not drain!\n",
 122                               esp->hostef">DMA_FIFO_ISDRAINss="sref">DMA_CSRH-lass="falt">asm/dma.h>
csr;
 117
123" class="sref">esp-> 117
 106
1253x_esp.c#L115" id="L.h>
csr;
 117
 106
  68
  29#include1 "sun>sun3x_esp_dma_drain(struct esp)
 108{
 121      val;
  97
1PFX 111
13 class="line" name="L94">  94static v1dma_write32( 119      ="drivers1/scsi/sun3x_esp.c#L36" i1d="L31353x_esp.c#L11ad32DMA_INT_E/a>(DMA_CSR);
DMA_FIFO_ISDRAIN) {
 120      ass="comm1ent">/*
 121      ass="comm1ent"> * m68k always assu1mes r1adl/wref">esp->KERN_ALERT PFX "esp%d: DMA will not drain!\n",
  35
 * mmio space; this1 is w138l/wref">esp->hostef">DMA_FIFO_ISDRAINss="sref">DMA_CSRH-lass="falt">asm/dma.h>
csr;
 117
 * need to workarou1nd th139l/wref">esp-> 117
 */
lim == 0) ss="line" name="L68">  68
printk>
csr;
 117
  68
rea14 class="line" name="L94">  94static v1DMA_RST_S= ~a href="drivers/scsiR, "a hST_WRIasDMA_FIFO_STDRAIN, DMBCe=DMA_C17" class="line" name="L117"> 117
wr1tel((DMA_INT_EN/a>( 111
dma_write32(csr | esp-> 117
(DMA_RST_S= ~>( 111
dma_unmap_single(csr | esp-> 117
  80
  81static v1a href="d1rivers/scsi/sun3x_esp.c#1L52" 15lass="sref">sun3x_esp_unmap_sg(struct sendrt csr;
(struct sendrt esp)
val;
sz, val;
  81static v1aa href="1/scsi/sun3x_esp.c#L53" i1d="L515p" class="sref">esp->>
val;
sun3x_esp_read8(strcm2f">csr;
 108{
  84        1f="driver1s/scsi/sun3x_esp.c#L55" 1id="L15>dma_write32(csr;
 110      wr156" class="line" name="L116"> 116      f="driver1s/scsi/sun3x_esp.c#L57" 1id="L15>dma_write32(&quoBUG_as*csr;
) ESP_CMD_ idf">csr;
lass="line" name="L110"> 110        58static <1a href="+1code=u8" class="sref">u81 15sref">dma_unmap_single(esp *csr;
 117
esp * 117
dma_read32(DMA_CSR);
 113      f="driver1s/scsi/sun3x_esp.c#L62" 1id="L161= 1000;
DMA_FI/a>( 113      fa href="1/scsi/sun3x_esp.c#L63" i1d="L616p" class="sre=( 108{
espDMA_FI/a>("a hST_WRIasDMA_lass="line" name="L113"> 113      f="driver1                       47#define 1f="driver1s/scsi/sun3x_esp.c#L66" 1id="L1653x_esp.c#L115" id="L.h>
DMA_FI= ~>("a hST_WRIasDMA_lass="line" name="L113"> 113      f<dma_write32(csr | DMA_f="+code=regs" clscsi/sun3x_esp.c#L117" id="L117" class="line" name="L117"> 117
csr | sz, /* rw  DMA tranclass="line" name="L117"> 117
  69static i1nt escm2f">csr;
  f">escm2*(strcm2f">csr;
  17#include &eturn   80
 112      return sun3x_esp_irq_pending(s/a> erroref">sz, (s/a> error*esp)
 108{
  84        1="drivers1/scsi/sun3x_esp.c#L75" i1d="L717>dma_write32(csr;
(DMA_CSR);
 113      oid  116               1                 (DMA_FIFO_ISDRAIN))
 116       <esp->L91" class="line" name="L91">  91        1  69static i1f="driver1s/scsi/sun3x_esp.c#L80" 1id="L17   92}
  80
 112               1             int (s/name=_op="sref">reg a>(s/name=_op=f="drivers/scsi/sun3ding(sop="sref">reg ding(sop=0" c  84        1f="driver1s/scsi/sun3x_esp.c#L84" 1id="L183" class="sre./a> *esp *esp *  81static v1dma_unmap_s./a> *(sf="+c>dma_unmap=ef="+code=csr" class="truct esp *  81static v1->esp *  81static v1<        1/scsi/sun3x_esp.c#L87" i1d="L8186>dma_unmap_s./a> *->=ef="+code=csr" class="truct esp *  81static v1<<->esp *  81static v1<<->=ef="+code=csr" class="truct esp *  81static v1<="driver1ef="+code=dma_read32" cl1ass="1ref">dma_read3./a> *esp *esp *  81static v1        r1eturn 1;
esp *esp *  81static v1 id esp *esp *  81static v1         1s/scsi/sun3x_esp.c#L93" 1id="L192.c#L92" id="./a> *  81static v1 ="driver1/scsi/sun3x_esp.c#L94" i1d="L9193" class="sre./a> *csr;
csr;
(struct sendrt   81static v1 a href="1ef="+code=sun3x_esp_rese1t_dma19">dma_unmap_s./a> *sz,  error*sz, (s/a> error*  81static v1 id   92}
1u32 107static="drivers1/scsi/sun3x_esp.c#L98" i1d="L919 class="sref">sun3x_esp_irq_penuct s107sg,  116      1val 109      dma_write32 *estemplathref="+code=esp" o28"">estemplathDMA_lass="line" name="L113"> 113     2  dma_write32 *DMA_CSRH-lass="So28"Hf">ef="drivers/scsi/sun3ef">DMA_CSRH-lass="falt">aslass="line" name="L113"> 113     2 1 *esp)
 113     2 2 *esourchef="drivers/scsi/sun3>esref="+code=esp">es8" class="line" name="L113"> 113     2 3 = sun3x_esp_irq_penurref">sz,  113     2 4  75static v2ref="driv2rs/scsi/sun3x_esp.c#L1062 id="20el((DMA_CSRH-lass="falt">as(esp)
 110     2ef="drive2s/scsi/sun3x_esp.c#L107"2id="L20=size_t" clas=DMA_CSRH-lass="falt">asaass="line" name="L116"> 116     2 void esp->gotocode=esp" class=fairef">esp->fair8" class="line" name="L113"> 113     2 8oid 2 id="20 class="line" name="L69">  69static i2   DMA_CSRH-lass="falt">asm/dma.h>
csr;
as 113     2  int l21>dma_write32(esp)
DMA_CSRH-lass="falt">asalass="line" name="L113"> 113     2 1 112     2   = esp)
DMA_CSRH-lass="falt">asd/a>(DMA_CSRH-lass="falt">aslass="line" name="L113"> 113     2  if (!(<2 href="+code=csr" class=2sref"21 = esp)
sg, sg,  113     2 4esp)
reg op=0" creg ding(sop=0" class="line" name="L113"> 113     2 ef="driv2s/scsi/sun3x_esp.c#L116"2id="L216" class="line" name="L116"> 116     2  dma_write32(es8" c(esourch);
sg,  113     2 void esref="+code=esp">es8" c<|| !ef="+code=VAL" >esref="+code=esp">es8" cFO_ISDRAINss="srs="rlass="sref">sgasaass="line" name="L116"> 116     2  esp->gotocode=esp" class=fair_un cl class="sref">KEfair_un cl 0" class="line" name="L113"> 113     2   113     2         2if (--esp)
reg * 4UL));
/a>(es8" cFO_ISDRAINss="srs="rlass="sref">sgasod0x20alass="line" name="L113"> 113     2         2        p=esp)
reg * 4UL));aass="line" name="L116"> 116     2         2               espreg fair_unp 113     222 class="line" name="L94">  94static v2<        2+code=DMA_COUNT" class="2sref"22>dma_write32(es8" c(esourch);
sg,  117
2253x_esp.c#L11=esref="+code=esp">es8" c<|| !ef="+code=VAL" >esref="+code=esp">es8" cFO_ISDRAINss="srs="rlass="sref">sgasaass="line" name="L116"> 116     2< reg fair_unp 113     2  58static <2="drivers2/scsi/sun3x_esp.c#L29" i2d="L222sref">dma_unmap_single(<"sref">esp)
reg sA_CSRs=L));
/a>(es8" cFO_ISDRAINss="srs="rlass="sref">sgasod0x10alass="line" name="L113"> 113     2   113     2="drivers2/scsi/sun3x_esp.c#L31" i2d="L323>dma_write32(esp)
KEiverand_bloc ="+c(esp)
sg,   81static v2printk(esp)
  81static v22PFXesp  asalass="line" name="L113"> 113     23<23sr & (esp)
KEiverand_bloc ="+caass="line" name="L116"> 116     2dma_write32 113     2="drivers2/scsi/sun3x_esp.c#L36" i2d="L3236" class="line" name="L116"> 116     2ass="comm2ent">/*
DMA_CSRH-lass="falt">asm/dma.h>
(sg,  113     2ass="comm2ent"> * m68k always assu2mes r237dma_write32(sz, equest_irq);
DMA_CSRH-lass="falt">asm/dma.h>
esintref">sz, esintr="+code=num_sg" classIRQF_SHAREDn3x_esp.c#L113"IRQF_SHARED*  81static v2<"drivers2ent"> * mmio space; this2 is w238l/wref">esp->,
hostef">DMA_FIalass="line" name="L113"> 113     2a  * need to workarou2nd th23ef">dma_read32(sz,  113     2ass="comm2ent"> */
lim == 0) gotocode=esp" class=fair_unpKEfair_unp 113     2 href="dr2ivers/scsi/sun3x_esp.c#L242" i242" class="line" name="L112"> 112     2esp)
csr;
 113     2 <rea24 = esp)
DMA_CSRH-lass="falt">asm/dma.h>
csr;
esp)
csr;
 113     2 a href="2+code=dma_write32" class2="sre24>dma_write32(esp)
KEdo28"i2_mas *esp)
csr;
 113     2wr2tel((esp)
eqclass="sref">KEif>eq* 113     2 107stati2(sg, sg, hostef">DMA_FIalass="line" name="L113"> 113     2 ss="comm2e   69static i2sz, esassisteref">sz, esassister);
esp)
sg, sg,  113     2do { *(vo2latile ;
(sz,  113     2a href="d2rivers/scsi/sun3x_esp.c#2L52" 25lass="sref">printkee_irqref="+code=esp"fair_f>ee_irq* 113     2aa href="2/scsi/sun3x_esp.c#L53" i2d="L525p" class="line" name="L113"> 113     2a<  92}
  75static v2wr256" clode=esp" class=fair_f>ee_irqref="+code=esp"fair_f>ee_irq*  75static v2ee_irqref="+code=esp"f>ee_irq*DMA_CSRH-lass="falt">asm/dma.h>
hostef">DMA_FIalass="line" name="L113"> 113     2KEfair_unp  75static v2u82 25sref">dma_unmap_single(ee_cohere/ssp.c#L108" id="t ee_cohere/s);
esp)
sg,   81static v2f="driver2s/scsi/sun3x_esp.c#L60" 2id="L259l/wref">esp->(esp)
KEiverand_bloc ="+cos="line" name="L81">  81static v2return lim == 0) (esp)
 113     2f="driver2s/scsi/sun3x_esp.c#L62" 2id="L261= 10ode=esp" class=fair_unp  75static v2fa href="2/scsi/sun3x_esp.c#L63" i2d="L626 = esp)
reg sA_CSRs=L));alass="line" name="L113"> 113     2f<reg fair_unp  75static v2f="driver2                     dma_write32(esp)
reg * 4UL));alass="line" name="L113"> 113     2fa href="2s/scsi/sun3x_esp.c#L66" 2id="L266" clode=esp" class=fair_un cl class="sref">KEfair_un cl 0" c:s="line" name="L75">  75static v2fss="comm2eef="+ambig=include/asm-2ld="L26>dma_write32(sgDMA_CSRH-lass="falt">asalass="line" name="L113"> 113     2fa href="2s/scsi/sun3x_esp.c#L68" 2id="L26 clasode=esp" class=fairclass="sref">KEfair0" c:s="line" name="L75">  75static v2fss="comm2/scsi/sun3x_esp.c#L69" i2d="L626sref">dma_unmL92" cl>(sz,  113     2f="driver2f="+code=sun3x_esp_map_s2g" cl26" class="line" name="L80">  80
  81static v2f="driver2s/scsi/sun3x_esp.c#L72" 2id="L27lass="sref">">sun3x_esp_irq_penuct s107sg,  116     2return  109     2f="driver2s/scsi/sun3x_esp.c#L74" 2id="L27 = esp)
(sg, sg,  113     2="drivers2/scsi/sun3x_esp.c#L75" i2d="L727>dma_write32">sun3x_esp_irq_penirqref="+code=esp"irq8" c(esp)
DMA_CSRH-lass="falt">asm/dma.h>
 113     2=a href="2ef="+code=sun3x_esp_unma2p_sin27el((val;
  97
 107stati2 <(esunassisteref">sz, esunassister);
esp)
 113     2=ss="comm2+code=dma_unmap_single" 2class27 class="line" name="L69">  69static i2f="driver2s/scsi/sun3x_esp.c#L80" 2id="L27 /* Disable>">surrupts.  */5" class="line" name="L35">  35
DMA_INT_E/a>(DMA_CSR);
 113     2oid csr | esp->(DMIe=DMA_C17" f="+code=regs" clscsi/sun3x_esp.c#L117" id="L117" class="line" name="L117"> 117
 113     2f="driver2s/scsi/sun3x_esp.c#L84" 2id="L28 = ee_irq*hostef">DMA_FIalass="line" name="L113"> 113     2ee_cohere/ssp.c#L108" id="t ee_cohere/s);
esp)
sg,   81static v2esp)
KEiverand_bloc ="+cos="line" name="L81">  81static v2<        2/scsi/sun3x_esp.c#L87" i2d="L828=size_t" class="sref"(esp)
 113     2<<  58static <2<<dma_unmap_single(sgesp)
DMA_CSRH-lass="falt">asalass="line" name="L113"> 113     2<="driver2ef="+code=dma_read32" cl2ass="28"srefass="line" name="L113"> 113     2        r2eturn 1;
  92}
  80
 113     2 ="driver2/scsi/sun3x_esp.c#L94" i2d="L9293" cl"sref">ref="+code=esp" class=platform_dname=ref="+code=esp"platform_dname=f="drivers/scsi/sun3uct s107 109     2 a href="2ef="+code=sun3x_esp_rese2t_dma29">dma_unmap_s./a> *(  81static v2 id (  81static v2         2+code=u32" class="sref">2u32dma_unmap_s./a> * 109     2 <esp->./a> *,
 " id="L122" class="line" name="L109"> 109     2 <2valesp->./a> *(  81static v2 ="driver2+code=dma_write32" class2="sre2">dma_write32<}os="line" name="L81">  81static v3  dma_}ss="line" name="L92">  92}
 112     3 2sun3x_esp_irq_pen__ini>DMA_CSRH-lass="__ini>f="drivers/scsi/sun3ding(sini>DMA_CSRH-lass="ding(sini>* 116     3 3  84        3 4sz,  113     3ref="driv3rs/scsi/sun3x_esp.c#L1063 id="30el  80
 107stati3 void DMA_CSRH-lass="__exi>f="drivers/scsi/sun3ding(sexi>DMA_CSRH-lass="ding(sexi>* 116     3 8oid 3 id="3009" class="line" name="L109"> 109     3   sz,  113     3  int l31code=ss="line" name="L80">  80
 112     3   = &quoMODULE_DESCRIPTIas*,
 113     3 3,
 113     3 4,
 113     3 ef="driv3s/scsi/sun3x_esp.c#L116"3id="L316" clode=esp" class=MODULE_VERSIass="string">&quoMODULE_VERSIas);
&quosRV_VERSIasINT_alass="line" name="L113"> 113     3 f="drive3"+code=dma_write32" clas3="sre317" class="line" name="L107"> 107stati3 void DMA_CSRH-lass="modulesini>);
(sini>* 113     3 8oid DMA_CSRH-lass="modulesexi>);
(sexi>* 113     3  ,
 " id="L122" calass="line" name="L113"> 113     3         3if (--LXR iveruni>y="+codthis experire/sal me="ion by ss="line"mailto:lxr@ef=ux.no">lxr@ef=ux.no="+c.
lxr.ef=ux.no kindly falted by ss="line"http://www.redpill-ef=pro.no">Redpill Lf=pro AS* and oper"srons servichs sincee1">5.