提交 352e921f 编写于 作者: T Thomas Bogendoerfer 提交者: James Bottomley

[SCSI] jazz_esp: converted to use esp_core

Use new esp_scsi for JAZZ SCSI host adapter driver
Signed-off-by: NThomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 72d39fea
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -121,7 +121,7 @@ obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o
obj-$(CONFIG_SCSI_PPA) += ppa.o
obj-$(CONFIG_SCSI_IMM) += imm.o
obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o
obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o
obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o
obj-$(CONFIG_SCSI_FCAL) += fcal.o
obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
......
/*
* jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture)
/* jazz_esp.c: ESP front-end for MIPS JAZZ systems.
*
* Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
*
* jazz_esp is based on David S. Miller's ESP driver and cyber_esp
* Copyright (C) 2007 Thomas Bogendrfer (tsbogend@alpha.frankende)
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "NCR53C9x.h"
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/jazz.h>
#include <asm/jazzdma.h>
#include <asm/dma.h>
#include <asm/pgtable.h>
static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp);
static void dma_dump_state(struct NCR_ESP *esp);
static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
static void dma_ints_off(struct NCR_ESP *esp);
static void dma_ints_on(struct NCR_ESP *esp);
static int dma_irq_p(struct NCR_ESP *esp);
static int dma_ports_p(struct NCR_ESP *esp);
static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
static void dma_advance_sg (struct scsi_cmnd *sp);
static void dma_led_off(struct NCR_ESP *);
static void dma_led_on(struct NCR_ESP *);
static volatile unsigned char cmd_buffer[16];
/* This is where all commands are put
* before they are trasfered to the ESP chip
* via PIO.
*/
static int jazz_esp_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
#include <scsi/scsi_host.h>
/***************************************************************** Detection */
static int jazz_esp_detect(struct scsi_host_template *tpnt)
{
struct NCR_ESP *esp;
struct ConfigDev *esp_dev;
/*
* first assumption it is there:-)
*/
if (1) {
esp_dev = NULL;
esp = esp_allocate(tpnt, esp_dev, 0);
/* Do command transfer with programmed I/O */
esp->do_pio_cmds = 1;
/* Required functions */
esp->dma_bytes_sent = &dma_bytes_sent;
esp->dma_can_transfer = &dma_can_transfer;
esp->dma_dump_state = &dma_dump_state;
esp->dma_init_read = &dma_init_read;
esp->dma_init_write = &dma_init_write;
esp->dma_ints_off = &dma_ints_off;
esp->dma_ints_on = &dma_ints_on;
esp->dma_irq_p = &dma_irq_p;
esp->dma_ports_p = &dma_ports_p;
esp->dma_setup = &dma_setup;
/* Optional functions */
esp->dma_barrier = NULL;
esp->dma_drain = NULL;
esp->dma_invalidate = NULL;
esp->dma_irq_entry = NULL;
esp->dma_irq_exit = NULL;
esp->dma_poll = NULL;
esp->dma_reset = NULL;
esp->dma_led_off = &dma_led_off;
esp->dma_led_on = &dma_led_on;
/* virtual DMA functions */
esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one;
esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl;
esp->dma_advance_sg = &dma_advance_sg;
/* SCSI chip speed */
esp->cfreq = 40000000;
#include "esp_scsi.h"
/*
* we don't give the address of DMA channel, but the number
* of DMA channel, so we can use the jazz DMA functions
*
*/
esp->dregs = (void *) JAZZ_SCSI_DMA;
/* ESP register base */
esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE);
/* Set the command buffer */
esp->esp_command = (volatile unsigned char *)cmd_buffer;
/* get virtual dma address for command buffer */
esp->esp_command_dvma = vdma_alloc(CPHYSADDR(cmd_buffer), sizeof (cmd_buffer));
esp->irq = JAZZ_SCSI_IRQ;
request_irq(JAZZ_SCSI_IRQ, esp_intr, IRQF_DISABLED, "JAZZ SCSI",
esp->ehost);
/*
* FIXME, look if the scsi id is available from NVRAM
*/
esp->scsi_id = 7;
/* Check for differential SCSI-bus */
/* What is this stuff? */
esp->diff = 0;
esp_initialize(esp);
printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
esps_running = esps_in_use;
return esps_in_use;
}
return 0;
}
#define DRV_MODULE_NAME "jazz_esp"
#define PFX DRV_MODULE_NAME ": "
#define DRV_VERSION "1.000"
#define DRV_MODULE_RELDATE "May 19, 2007"
/************************************************************* DMA Functions */
static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
static void jazz_esp_write8(struct esp *esp, u8 val, unsigned long reg)
{
return fifo_count;
*(volatile u8 *)(esp->regs + reg) = val;
}
static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp)
static u8 jazz_esp_read8(struct esp *esp, unsigned long reg)
{
/*
* maximum DMA size is 1MB
*/
unsigned long sz = sp->SCp.this_residual;
if(sz > 0x100000)
sz = 0x100000;
return sz;
return *(volatile u8 *)(esp->regs + reg);
}
static void dma_dump_state(struct NCR_ESP *esp)
static dma_addr_t jazz_esp_map_single(struct esp *esp, void *buf,
size_t sz, int dir)
{
ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_residue((int)esp->dregs)));
return dma_map_single(esp->dev, buf, sz, dir);
}
static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
static int jazz_esp_map_sg(struct esp *esp, struct scatterlist *sg,
int num_sg, int dir)
{
dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length);
vdma_disable ((int)esp->dregs);
vdma_set_mode ((int)esp->dregs, DMA_MODE_READ);
vdma_set_addr ((int)esp->dregs, vaddress);
vdma_set_count ((int)esp->dregs, length);
vdma_enable ((int)esp->dregs);
return dma_map_sg(esp->dev, sg, num_sg, dir);
}
static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
static void jazz_esp_unmap_single(struct esp *esp, dma_addr_t addr,
size_t sz, int dir)
{
dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length);
vdma_disable ((int)esp->dregs);
vdma_set_mode ((int)esp->dregs, DMA_MODE_WRITE);
vdma_set_addr ((int)esp->dregs, vaddress);
vdma_set_count ((int)esp->dregs, length);
vdma_enable ((int)esp->dregs);
dma_unmap_single(esp->dev, addr, sz, dir);
}
static void dma_ints_off(struct NCR_ESP *esp)
static void jazz_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
int num_sg, int dir)
{
disable_irq(esp->irq);
dma_unmap_sg(esp->dev, sg, num_sg, dir);
}
static void dma_ints_on(struct NCR_ESP *esp)
static int jazz_esp_irq_pending(struct esp *esp)
{
enable_irq(esp->irq);
if (jazz_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR)
return 1;
return 0;
}
static int dma_irq_p(struct NCR_ESP *esp)
static void jazz_esp_reset_dma(struct esp *esp)
{
return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR);
vdma_disable ((int)esp->dma_regs);
}
static int dma_ports_p(struct NCR_ESP *esp)
static void jazz_esp_dma_drain(struct esp *esp)
{
int enable = vdma_get_enable((int)esp->dregs);
return (enable & R4030_CHNL_ENABLE);
/* nothing to do */
}
static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
static void jazz_esp_dma_invalidate(struct esp *esp)
{
/*
* On the Sparc, DMA_ST_WRITE means "move data from device to memory"
* so when (write) is true, it actually means READ!
*/
if(write){
dma_init_read(esp, addr, count);
} else {
dma_init_write(esp, addr, count);
}
vdma_disable ((int)esp->dma_regs);
}
static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
static void jazz_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
u32 dma_count, int write, u8 cmd)
{
sp->SCp.have_data_in = vdma_alloc(CPHYSADDR(sp->SCp.buffer), sp->SCp.this_residual);
sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in);
BUG_ON(!(cmd & ESP_CMD_DMA));
jazz_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
jazz_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
vdma_disable ((int)esp->dma_regs);
if (write)
vdma_set_mode ((int)esp->dma_regs, DMA_MODE_READ);
else
vdma_set_mode ((int)esp->dma_regs, DMA_MODE_WRITE);
vdma_set_addr ((int)esp->dma_regs, addr);
vdma_set_count ((int)esp->dma_regs, dma_count);
vdma_enable ((int)esp->dma_regs);
scsi_esp_cmd(esp, cmd);
}
static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
{
int sz = sp->SCp.buffers_residual;
struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer;
while (sz >= 0) {
sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length);
sz--;
}
sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address);
}
static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
static int jazz_esp_dma_error(struct esp *esp)
{
vdma_free(sp->SCp.have_data_in);
u32 enable = vdma_get_enable((int)esp->dma_regs);
if (enable & (R4030_MEM_INTR|R4030_ADDR_INTR))
return 1;
return 0;
}
static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
static const struct esp_driver_ops jazz_esp_ops = {
.esp_write8 = jazz_esp_write8,
.esp_read8 = jazz_esp_read8,
.map_single = jazz_esp_map_single,
.map_sg = jazz_esp_map_sg,
.unmap_single = jazz_esp_unmap_single,
.unmap_sg = jazz_esp_unmap_sg,
.irq_pending = jazz_esp_irq_pending,
.reset_dma = jazz_esp_reset_dma,
.dma_drain = jazz_esp_dma_drain,
.dma_invalidate = jazz_esp_dma_invalidate,
.send_dma_cmd = jazz_esp_send_dma_cmd,
.dma_error = jazz_esp_dma_error,
};
static int __devinit esp_jazz_probe(struct platform_device *dev)
{
int sz = sp->use_sg - 1;
struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
while(sz >= 0) {
vdma_free(sg[sz].dma_address);
sz--;
}
struct scsi_host_template *tpnt = &scsi_esp_template;
struct Scsi_Host *host;
struct esp *esp;
struct resource *res;
int err;
host = scsi_host_alloc(tpnt, sizeof(struct esp));
err = -ENOMEM;
if (!host)
goto fail;
host->max_id = 8;
esp = host_to_esp(host);
esp->host = host;
esp->dev = dev;
esp->ops = &jazz_esp_ops;
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!res)
goto fail_unlink;
esp->regs = (void __iomem *)res->start;
if (!esp->regs)
goto fail_unlink;
res = platform_get_resource(dev, IORESOURCE_MEM, 1);
if (!res)
goto fail_unlink;
esp->dma_regs = (void __iomem *)res->start;
esp->command_block = dma_alloc_coherent(esp->dev, 16,
&esp->command_block_dma,
GFP_KERNEL);
if (!esp->command_block)
goto fail_unmap_regs;
host->irq = platform_get_irq(dev, 0);
err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
if (err < 0)
goto fail_unmap_command_block;
esp->scsi_id = 7;
esp->host->this_id = esp->scsi_id;
esp->scsi_id_mask = (1 << esp->scsi_id);
esp->cfreq = 40000000;
dev_set_drvdata(&dev->dev, esp);
err = scsi_esp_register(esp, &dev->dev);
if (err)
goto fail_free_irq;
return 0;
fail_free_irq:
free_irq(host->irq, esp);
fail_unmap_command_block:
dma_free_coherent(esp->dev, 16,
esp->command_block,
esp->command_block_dma);
fail_unmap_regs:
fail_unlink:
scsi_host_put(host);
fail:
return err;
}
static void dma_advance_sg (struct scsi_cmnd *sp)
static int __devexit esp_jazz_remove(struct platform_device *dev)
{
sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
struct esp *esp = dev_get_drvdata(&dev->dev);
unsigned int irq = esp->host->irq;
scsi_esp_unregister(esp);
free_irq(irq, esp);
dma_free_coherent(esp->dev, 16,
esp->command_block,
esp->command_block_dma);
scsi_host_put(esp->host);
return 0;
}
#define JAZZ_HDC_LED 0xe000d100 /* FIXME, find correct address */
static struct platform_driver esp_jazz_driver = {
.probe = esp_jazz_probe,
.remove = __devexit_p(esp_jazz_remove),
.driver = {
.name = "jazz_esp",
},
};
static void dma_led_off(struct NCR_ESP *esp)
static int __init jazz_esp_init(void)
{
#if 0
*(unsigned char *)JAZZ_HDC_LED = 0;
#endif
return platform_driver_register(&esp_jazz_driver);
}
static void dma_led_on(struct NCR_ESP *esp)
{
#if 0
*(unsigned char *)JAZZ_HDC_LED = 1;
#endif
static void __exit jazz_esp_exit(void)
{
platform_driver_unregister(&esp_jazz_driver);
}
static struct scsi_host_template driver_template = {
.proc_name = "jazz_esp",
.proc_info = esp_proc_info,
.name = "ESP 100/100a/200",
.detect = jazz_esp_detect,
.slave_alloc = esp_slave_alloc,
.slave_destroy = esp_slave_destroy,
.release = jazz_esp_release,
.info = esp_info,
.queuecommand = esp_queue,
.eh_abort_handler = esp_abort,
.eh_bus_reset_handler = esp_reset,
.can_queue = 7,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
};
#include "scsi_module.c"
MODULE_DESCRIPTION("JAZZ ESP SCSI driver");
MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
module_init(jazz_esp_init);
module_exit(jazz_esp_exit);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部