Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Michael Schmitz | 3917 | 96.60% | 1 | 33.33% |
Finn Thain | 138 | 3.40% | 2 | 66.67% |
Total | 4055 | 3 |
// SPDX-License-Identifier: GPL-2.0 /* * ESP front-end for Amiga ZORRO SCSI systems. * * Copyright (C) 1996 Jesper Skov (jskov@cygnus.co.uk) * * Copyright (C) 2011,2018 Michael Schmitz (schmitz@debian.org) for * migration to ESP SCSI core * * Copyright (C) 2013 Tuomas Vainikka (tuomas.vainikka@aalto.fi) for * Blizzard 1230 DMA and probe function fixes */ /* * ZORRO bus code from: */ /* * Detection routine for the NCR53c710 based Amiga SCSI Controllers for Linux. * Amiga MacroSystemUS WarpEngine SCSI controller. * Amiga Technologies/DKB A4091 SCSI controller. * * Written 1997 by Alan Hourihane <alanh@fairlite.demon.co.uk> * plus modifications of the 53c7xx.c driver to support the Amiga. * * Rewritten to use 53c700.c by Kars de Jong <jongk@linux-m68k.org> */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/module.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/dma-mapping.h> #include <linux/scatterlist.h> #include <linux/delay.h> #include <linux/zorro.h> #include <linux/slab.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/cacheflush.h> #include <asm/amigahw.h> #include <asm/amigaints.h> #include <scsi/scsi_host.h> #include <scsi/scsi_transport_spi.h> #include <scsi/scsi_device.h> #include <scsi/scsi_tcq.h> #include "esp_scsi.h" MODULE_AUTHOR("Michael Schmitz <schmitz@debian.org>"); MODULE_DESCRIPTION("Amiga Zorro NCR5C9x (ESP) driver"); MODULE_LICENSE("GPL"); /* per-board register layout definitions */ /* Blizzard 1230 DMA interface */ struct blz1230_dma_registers { unsigned char dma_addr; /* DMA address [0x0000] */ unsigned char dmapad2[0x7fff]; unsigned char dma_latch; /* DMA latch [0x8000] */ }; /* Blizzard 1230II DMA interface */ struct blz1230II_dma_registers { unsigned char dma_addr; /* DMA address [0x0000] */ unsigned char dmapad2[0xf]; unsigned char dma_latch; /* DMA latch [0x0010] */ }; /* Blizzard 2060 DMA interface */ struct blz2060_dma_registers { unsigned char dma_led_ctrl; /* DMA led control [0x000] */ unsigned char dmapad1[0x0f]; unsigned char dma_addr0; /* DMA address (MSB) [0x010] */ unsigned char dmapad2[0x03]; unsigned char dma_addr1; /* DMA address [0x014] */ unsigned char dmapad3[0x03]; unsigned char dma_addr2; /* DMA address [0x018] */ unsigned char dmapad4[0x03]; unsigned char dma_addr3; /* DMA address (LSB) [0x01c] */ }; /* DMA control bits */ #define DMA_WRITE 0x80000000 /* Cyberstorm DMA interface */ struct cyber_dma_registers { unsigned char dma_addr0; /* DMA address (MSB) [0x000] */ unsigned char dmapad1[1]; unsigned char dma_addr1; /* DMA address [0x002] */ unsigned char dmapad2[1]; unsigned char dma_addr2; /* DMA address [0x004] */ unsigned char dmapad3[1]; unsigned char dma_addr3; /* DMA address (LSB) [0x006] */ unsigned char dmapad4[0x3fb]; unsigned char cond_reg; /* DMA cond (ro) [0x402] */ #define ctrl_reg cond_reg /* DMA control (wo) [0x402] */ }; /* DMA control bits */ #define CYBER_DMA_WRITE 0x40 /* DMA direction. 1 = write */ #define CYBER_DMA_Z3 0x20 /* 16 (Z2) or 32 (CHIP/Z3) bit DMA transfer */ /* DMA status bits */ #define CYBER_DMA_HNDL_INTR 0x80 /* DMA IRQ pending? */ /* The CyberStorm II DMA interface */ struct cyberII_dma_registers { unsigned char cond_reg; /* DMA cond (ro) [0x000] */ #define ctrl_reg cond_reg /* DMA control (wo) [0x000] */ unsigned char dmapad4[0x3f]; unsigned char dma_addr0; /* DMA address (MSB) [0x040] */ unsigned char dmapad1[3]; unsigned char dma_addr1; /* DMA address [0x044] */ unsigned char dmapad2[3]; unsigned char dma_addr2; /* DMA address [0x048] */ unsigned char dmapad3[3]; unsigned char dma_addr3; /* DMA address (LSB) [0x04c] */ }; /* Fastlane DMA interface */ struct fastlane_dma_registers { unsigned char cond_reg; /* DMA status (ro) [0x0000] */ #define ctrl_reg cond_reg /* DMA control (wo) [0x0000] */ char dmapad1[0x3f]; unsigned char clear_strobe; /* DMA clear (wo) [0x0040] */ }; /* * The controller registers can be found in the Z2 config area at these * offsets: */ #define FASTLANE_ESP_ADDR 0x1000001 /* DMA status bits */ #define FASTLANE_DMA_MINT 0x80 #define FASTLANE_DMA_IACT 0x40 #define FASTLANE_DMA_CREQ 0x20 /* DMA control bits */ #define FASTLANE_DMA_FCODE 0xa0 #define FASTLANE_DMA_MASK 0xf3 #define FASTLANE_DMA_WRITE 0x08 /* 1 = write */ #define FASTLANE_DMA_ENABLE 0x04 /* Enable DMA */ #define FASTLANE_DMA_EDI 0x02 /* Enable DMA IRQ ? */ #define FASTLANE_DMA_ESI 0x01 /* Enable SCSI IRQ */ /* * private data used for driver */ struct zorro_esp_priv { struct esp *esp; /* our ESP instance - for Scsi_host* */ void __iomem *board_base; /* virtual address (Zorro III board) */ int zorro3; /* board is Zorro III */ unsigned char ctrl_data; /* shadow copy of ctrl_reg */ }; /* * On all implementations except for the Oktagon, padding between ESP * registers is three bytes. * On Oktagon, it is one byte - use a different accessor there. * * Oktagon needs PDMA - currently unsupported! */ static void zorro_esp_write8(struct esp *esp, u8 val, unsigned long reg) { writeb(val, esp->regs + (reg * 4UL)); } static u8 zorro_esp_read8(struct esp *esp, unsigned long reg) { return readb(esp->regs + (reg * 4UL)); } static int zorro_esp_irq_pending(struct esp *esp) { /* check ESP status register; DMA has no status reg. */ if (zorro_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR) return 1; return 0; } static int cyber_esp_irq_pending(struct esp *esp) { struct cyber_dma_registers __iomem *dregs = esp->dma_regs; unsigned char dma_status = readb(&dregs->cond_reg); /* It's important to check the DMA IRQ bit in the correct way! */ return ((zorro_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR) && (dma_status & CYBER_DMA_HNDL_INTR)); } static int fastlane_esp_irq_pending(struct esp *esp) { struct fastlane_dma_registers __iomem *dregs = esp->dma_regs; unsigned char dma_status; dma_status = readb(&dregs->cond_reg); if (dma_status & FASTLANE_DMA_IACT) return 0; /* not our IRQ */ /* Return non-zero if ESP requested IRQ */ return ( (dma_status & FASTLANE_DMA_CREQ) && (!(dma_status & FASTLANE_DMA_MINT)) && (zorro_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR)); } static u32 zorro_esp_dma_length_limit(struct esp *esp, u32 dma_addr, u32 dma_len) { return dma_len > 0xFFFF ? 0xFFFF : dma_len; } static void zorro_esp_reset_dma(struct esp *esp) { /* nothing to do here */ } static void zorro_esp_dma_drain(struct esp *esp) { /* nothing to do here */ } static void zorro_esp_dma_invalidate(struct esp *esp) { /* nothing to do here */ } static void fastlane_esp_dma_invalidate(struct esp *esp) { struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev); struct fastlane_dma_registers __iomem *dregs = esp->dma_regs; unsigned char *ctrl_data = &zep->ctrl_data; *ctrl_data = (*ctrl_data & FASTLANE_DMA_MASK); writeb(0, &dregs->clear_strobe); z_writel(0, zep->board_base); } /* Blizzard 1230/60 SCSI-IV DMA */ static void zorro_esp_send_blz1230_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, u32 dma_count, int write, u8 cmd) { struct blz1230_dma_registers __iomem *dregs = esp->dma_regs; u8 phase = esp->sreg & ESP_STAT_PMASK; /* * Use PIO if transferring message bytes to esp->command_block_dma. * PIO requires a virtual address, so substitute esp->command_block * for addr. */ if (phase == ESP_MIP && addr == esp->command_block_dma) { esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count, dma_count, write, cmd); return; } /* Clear the results of a possible prior esp->ops->send_dma_cmd() */ esp->send_cmd_error = 0; esp->send_cmd_residual = 0; if (write) /* DMA receive */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_FROM_DEVICE); else /* DMA send */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_TO_DEVICE); addr >>= 1; if (write) addr &= ~(DMA_WRITE); else addr |= DMA_WRITE; writeb((addr >> 24) & 0xff, &dregs->dma_latch); writeb((addr >> 24) & 0xff, &dregs->dma_addr); writeb((addr >> 16) & 0xff, &dregs->dma_addr); writeb((addr >> 8) & 0xff, &dregs->dma_addr); writeb(addr & 0xff, &dregs->dma_addr); scsi_esp_cmd(esp, ESP_CMD_DMA); zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); scsi_esp_cmd(esp, cmd); } /* Blizzard 1230-II DMA */ static void zorro_esp_send_blz1230II_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, u32 dma_count, int write, u8 cmd) { struct blz1230II_dma_registers __iomem *dregs = esp->dma_regs; u8 phase = esp->sreg & ESP_STAT_PMASK; /* Use PIO if transferring message bytes to esp->command_block_dma */ if (phase == ESP_MIP && addr == esp->command_block_dma) { esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count, dma_count, write, cmd); return; } esp->send_cmd_error = 0; esp->send_cmd_residual = 0; if (write) /* DMA receive */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_FROM_DEVICE); else /* DMA send */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_TO_DEVICE); addr >>= 1; if (write) addr &= ~(DMA_WRITE); else addr |= DMA_WRITE; writeb((addr >> 24) & 0xff, &dregs->dma_latch); writeb((addr >> 16) & 0xff, &dregs->dma_addr); writeb((addr >> 8) & 0xff, &dregs->dma_addr); writeb(addr & 0xff, &dregs->dma_addr); scsi_esp_cmd(esp, ESP_CMD_DMA); zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); scsi_esp_cmd(esp, cmd); } /* Blizzard 2060 DMA */ static void zorro_esp_send_blz2060_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, u32 dma_count, int write, u8 cmd) { struct blz2060_dma_registers __iomem *dregs = esp->dma_regs; u8 phase = esp->sreg & ESP_STAT_PMASK; /* Use PIO if transferring message bytes to esp->command_block_dma */ if (phase == ESP_MIP && addr == esp->command_block_dma) { esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count, dma_count, write, cmd); return; } esp->send_cmd_error = 0; esp->send_cmd_residual = 0; if (write) /* DMA receive */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_FROM_DEVICE); else /* DMA send */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_TO_DEVICE); addr >>= 1; if (write) addr &= ~(DMA_WRITE); else addr |= DMA_WRITE; writeb(addr & 0xff, &dregs->dma_addr3); writeb((addr >> 8) & 0xff, &dregs->dma_addr2); writeb((addr >> 16) & 0xff, &dregs->dma_addr1); writeb((addr >> 24) & 0xff, &dregs->dma_addr0); scsi_esp_cmd(esp, ESP_CMD_DMA); zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); scsi_esp_cmd(esp, cmd); } /* Cyberstorm I DMA */ static void zorro_esp_send_cyber_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, u32 dma_count, int write, u8 cmd) { struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev); struct cyber_dma_registers __iomem *dregs = esp->dma_regs; u8 phase = esp->sreg & ESP_STAT_PMASK; unsigned char *ctrl_data = &zep->ctrl_data; /* Use PIO if transferring message bytes to esp->command_block_dma */ if (phase == ESP_MIP && addr == esp->command_block_dma) { esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count, dma_count, write, cmd); return; } esp->send_cmd_error = 0; esp->send_cmd_residual = 0; zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); if (write) { /* DMA receive */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_FROM_DEVICE); addr &= ~(1); } else { /* DMA send */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_TO_DEVICE); addr |= 1; } writeb((addr >> 24) & 0xff, &dregs->dma_addr0); writeb((addr >> 16) & 0xff, &dregs->dma_addr1); writeb((addr >> 8) & 0xff, &dregs->dma_addr2); writeb(addr & 0xff, &dregs->dma_addr3); if (write) *ctrl_data &= ~(CYBER_DMA_WRITE); else *ctrl_data |= CYBER_DMA_WRITE; *ctrl_data &= ~(CYBER_DMA_Z3); /* Z2, do 16 bit DMA */ writeb(*ctrl_data, &dregs->ctrl_reg); scsi_esp_cmd(esp, cmd); } /* Cyberstorm II DMA */ static void zorro_esp_send_cyberII_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, u32 dma_count, int write, u8 cmd) { struct cyberII_dma_registers __iomem *dregs = esp->dma_regs; u8 phase = esp->sreg & ESP_STAT_PMASK; /* Use PIO if transferring message bytes to esp->command_block_dma */ if (phase == ESP_MIP && addr == esp->command_block_dma) { esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count, dma_count, write, cmd); return; } esp->send_cmd_error = 0; esp->send_cmd_residual = 0; zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); if (write) { /* DMA receive */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_FROM_DEVICE); addr &= ~(1); } else { /* DMA send */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_TO_DEVICE); addr |= 1; } writeb((addr >> 24) & 0xff, &dregs->dma_addr0); writeb((addr >> 16) & 0xff, &dregs->dma_addr1); writeb((addr >> 8) & 0xff, &dregs->dma_addr2); writeb(addr & 0xff, &dregs->dma_addr3); scsi_esp_cmd(esp, cmd); } /* Fastlane DMA */ static void zorro_esp_send_fastlane_dma_cmd(struct esp *esp, u32 addr, u32 esp_count, u32 dma_count, int write, u8 cmd) { struct zorro_esp_priv *zep = dev_get_drvdata(esp->dev); struct fastlane_dma_registers __iomem *dregs = esp->dma_regs; u8 phase = esp->sreg & ESP_STAT_PMASK; unsigned char *ctrl_data = &zep->ctrl_data; /* Use PIO if transferring message bytes to esp->command_block_dma */ if (phase == ESP_MIP && addr == esp->command_block_dma) { esp_send_pio_cmd(esp, (u32)esp->command_block, esp_count, dma_count, write, cmd); return; } esp->send_cmd_error = 0; esp->send_cmd_residual = 0; zorro_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW); zorro_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED); if (write) { /* DMA receive */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_FROM_DEVICE); addr &= ~(1); } else { /* DMA send */ dma_sync_single_for_device(esp->dev, addr, esp_count, DMA_TO_DEVICE); addr |= 1; } writeb(0, &dregs->clear_strobe); z_writel(addr, ((addr & 0x00ffffff) + zep->board_base)); if (write) { *ctrl_data = (*ctrl_data & FASTLANE_DMA_MASK) | FASTLANE_DMA_ENABLE; } else { *ctrl_data = ((*ctrl_data & FASTLANE_DMA_MASK) | FASTLANE_DMA_ENABLE | FASTLANE_DMA_WRITE); } writeb(*ctrl_data, &dregs->ctrl_reg); scsi_esp_cmd(esp, cmd); } static int zorro_esp_dma_error(struct esp *esp) { return esp->send_cmd_error; } /* per-board ESP driver ops */ static const struct esp_driver_ops blz1230_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, .irq_pending = zorro_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, .dma_drain = zorro_esp_dma_drain, .dma_invalidate = zorro_esp_dma_invalidate, .send_dma_cmd = zorro_esp_send_blz1230_dma_cmd, .dma_error = zorro_esp_dma_error, }; static const struct esp_driver_ops blz1230II_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, .irq_pending = zorro_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, .dma_drain = zorro_esp_dma_drain, .dma_invalidate = zorro_esp_dma_invalidate, .send_dma_cmd = zorro_esp_send_blz1230II_dma_cmd, .dma_error = zorro_esp_dma_error, }; static const struct esp_driver_ops blz2060_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, .irq_pending = zorro_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, .dma_drain = zorro_esp_dma_drain, .dma_invalidate = zorro_esp_dma_invalidate, .send_dma_cmd = zorro_esp_send_blz2060_dma_cmd, .dma_error = zorro_esp_dma_error, }; static const struct esp_driver_ops cyber_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, .irq_pending = cyber_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, .dma_drain = zorro_esp_dma_drain, .dma_invalidate = zorro_esp_dma_invalidate, .send_dma_cmd = zorro_esp_send_cyber_dma_cmd, .dma_error = zorro_esp_dma_error, }; static const struct esp_driver_ops cyberII_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, .irq_pending = zorro_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, .dma_drain = zorro_esp_dma_drain, .dma_invalidate = zorro_esp_dma_invalidate, .send_dma_cmd = zorro_esp_send_cyberII_dma_cmd, .dma_error = zorro_esp_dma_error, }; static const struct esp_driver_ops fastlane_esp_ops = { .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, .irq_pending = fastlane_esp_irq_pending, .dma_length_limit = zorro_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, .dma_drain = zorro_esp_dma_drain, .dma_invalidate = fastlane_esp_dma_invalidate, .send_dma_cmd = zorro_esp_send_fastlane_dma_cmd, .dma_error = zorro_esp_dma_error, }; /* Zorro driver config data */ struct zorro_driver_data { const char *name; unsigned long offset; unsigned long dma_offset; int absolute; /* offset is absolute address */ int scsi_option; const struct esp_driver_ops *esp_ops; }; /* board types */ enum { ZORRO_BLZ1230, ZORRO_BLZ1230II, ZORRO_BLZ2060, ZORRO_CYBER, ZORRO_CYBERII, ZORRO_FASTLANE, }; /* per-board config data */ static const struct zorro_driver_data zorro_esp_boards[] = { [ZORRO_BLZ1230] = { .name = "Blizzard 1230", .offset = 0x8000, .dma_offset = 0x10000, .scsi_option = 1, .esp_ops = &blz1230_esp_ops, }, [ZORRO_BLZ1230II] = { .name = "Blizzard 1230II", .offset = 0x10000, .dma_offset = 0x10021, .scsi_option = 1, .esp_ops = &blz1230II_esp_ops, }, [ZORRO_BLZ2060] = { .name = "Blizzard 2060", .offset = 0x1ff00, .dma_offset = 0x1ffe0, .esp_ops = &blz2060_esp_ops, }, [ZORRO_CYBER] = { .name = "CyberStormI", .offset = 0xf400, .dma_offset = 0xf800, .esp_ops = &cyber_esp_ops, }, [ZORRO_CYBERII] = { .name = "CyberStormII", .offset = 0x1ff03, .dma_offset = 0x1ff43, .scsi_option = 1, .esp_ops = &cyberII_esp_ops, }, [ZORRO_FASTLANE] = { .name = "Fastlane", .offset = 0x1000001, .dma_offset = 0x1000041, .esp_ops = &fastlane_esp_ops, }, }; static const struct zorro_device_id zorro_esp_zorro_tbl[] = { { /* Blizzard 1230 IV */ .id = ZORRO_ID(PHASE5, 0x11, 0), .driver_data = ZORRO_BLZ1230, }, { /* Blizzard 1230 II (Zorro II) or Fastlane (Zorro III) */ .id = ZORRO_ID(PHASE5, 0x0B, 0), .driver_data = ZORRO_BLZ1230II, }, { /* Blizzard 2060 */ .id = ZORRO_ID(PHASE5, 0x18, 0), .driver_data = ZORRO_BLZ2060, }, { /* Cyberstorm */ .id = ZORRO_ID(PHASE5, 0x0C, 0), .driver_data = ZORRO_CYBER, }, { /* Cyberstorm II */ .id = ZORRO_ID(PHASE5, 0x19, 0), .driver_data = ZORRO_CYBERII, }, { 0 } }; MODULE_DEVICE_TABLE(zorro, zorro_esp_zorro_tbl); static int zorro_esp_probe(struct zorro_dev *z, const struct zorro_device_id *ent) { struct scsi_host_template *tpnt = &scsi_esp_template; struct Scsi_Host *host; struct esp *esp; const struct zorro_driver_data *zdd; struct zorro_esp_priv *zep; unsigned long board, ioaddr, dmaaddr; int err; board = zorro_resource_start(z); zdd = &zorro_esp_boards[ent->driver_data]; pr_info("%s found at address 0x%lx.\n", zdd->name, board); zep = kzalloc(sizeof(*zep), GFP_KERNEL); if (!zep) { pr_err("Can't allocate device private data!\n"); return -ENOMEM; } /* let's figure out whether we have a Zorro II or Zorro III board */ if ((z->rom.er_Type & ERT_TYPEMASK) == ERT_ZORROIII) { if (board > 0xffffff) zep->zorro3 = 1; } else { /* * Even though most of these boards identify as Zorro II, * they are in fact CPU expansion slot boards and have full * access to all of memory. Fix up DMA bitmask here. */ z->dev.coherent_dma_mask = DMA_BIT_MASK(32); } /* * If Zorro III and ID matches Fastlane, our device table entry * contains data for the Blizzard 1230 II board which does share the * same ID. Fix up device table entry here. * TODO: Some Cyberstom060 boards also share this ID but would need * to use the Cyberstorm I driver data ... we catch this by checking * for presence of ESP chip later, but don't try to fix up yet. */ if (zep->zorro3 && ent->driver_data == ZORRO_BLZ1230II) { pr_info("%s at address 0x%lx is Fastlane Z3, fixing data!\n", zdd->name, board); zdd = &zorro_esp_boards[ZORRO_FASTLANE]; } if (zdd->absolute) { ioaddr = zdd->offset; dmaaddr = zdd->dma_offset; } else { ioaddr = board + zdd->offset; dmaaddr = board + zdd->dma_offset; } if (!zorro_request_device(z, zdd->name)) { pr_err("cannot reserve region 0x%lx, abort\n", board); err = -EBUSY; goto fail_free_zep; } host = scsi_host_alloc(tpnt, sizeof(struct esp)); if (!host) { pr_err("No host detected; board configuration problem?\n"); err = -ENOMEM; goto fail_release_device; } host->base = ioaddr; host->this_id = 7; esp = shost_priv(host); esp->host = host; esp->dev = &z->dev; esp->scsi_id = host->this_id; esp->scsi_id_mask = (1 << esp->scsi_id); esp->cfreq = 40000000; zep->esp = esp; dev_set_drvdata(esp->dev, zep); /* additional setup required for Fastlane */ if (zep->zorro3 && ent->driver_data == ZORRO_BLZ1230II) { /* map full address space up to ESP base for DMA */ zep->board_base = ioremap_nocache(board, FASTLANE_ESP_ADDR-1); if (!zep->board_base) { pr_err("Cannot allocate board address space\n"); err = -ENOMEM; goto fail_free_host; } /* initialize DMA control shadow register */ zep->ctrl_data = (FASTLANE_DMA_FCODE | FASTLANE_DMA_EDI | FASTLANE_DMA_ESI); } esp->ops = zdd->esp_ops; if (ioaddr > 0xffffff) esp->regs = ioremap_nocache(ioaddr, 0x20); else /* ZorroII address space remapped nocache by early startup */ esp->regs = ZTWO_VADDR(ioaddr); if (!esp->regs) { err = -ENOMEM; goto fail_unmap_fastlane; } esp->fifo_reg = esp->regs + ESP_FDATA * 4; /* Check whether a Blizzard 12x0 or CyberstormII really has SCSI */ if (zdd->scsi_option) { zorro_esp_write8(esp, (ESP_CONFIG1_PENABLE | 7), ESP_CFG1); if (zorro_esp_read8(esp, ESP_CFG1) != (ESP_CONFIG1_PENABLE|7)) { err = -ENODEV; goto fail_unmap_regs; } } if (zep->zorro3) { /* * Only Fastlane Z3 for now - add switch for correct struct * dma_registers size if adding any more */ esp->dma_regs = ioremap_nocache(dmaaddr, sizeof(struct fastlane_dma_registers)); } else /* ZorroII address space remapped nocache by early startup */ esp->dma_regs = ZTWO_VADDR(dmaaddr); if (!esp->dma_regs) { err = -ENOMEM; goto fail_unmap_regs; } esp->command_block = dma_alloc_coherent(esp->dev, 16, &esp->command_block_dma, GFP_KERNEL); if (!esp->command_block) { err = -ENOMEM; goto fail_unmap_dma_regs; } host->irq = IRQ_AMIGA_PORTS; err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "Amiga Zorro ESP", esp); if (err < 0) { err = -ENODEV; goto fail_free_command_block; } /* register the chip */ err = scsi_esp_register(esp); if (err) { err = -ENOMEM; goto fail_free_irq; } return 0; fail_free_irq: free_irq(host->irq, esp); fail_free_command_block: dma_free_coherent(esp->dev, 16, esp->command_block, esp->command_block_dma); fail_unmap_dma_regs: if (zep->zorro3) iounmap(esp->dma_regs); fail_unmap_regs: if (ioaddr > 0xffffff) iounmap(esp->regs); fail_unmap_fastlane: if (zep->zorro3) iounmap(zep->board_base); fail_free_host: scsi_host_put(host); fail_release_device: zorro_release_device(z); fail_free_zep: kfree(zep); return err; } static void zorro_esp_remove(struct zorro_dev *z) { struct zorro_esp_priv *zep = dev_get_drvdata(&z->dev); struct esp *esp = zep->esp; struct Scsi_Host *host = esp->host; scsi_esp_unregister(esp); free_irq(host->irq, esp); dma_free_coherent(esp->dev, 16, esp->command_block, esp->command_block_dma); if (zep->zorro3) { iounmap(zep->board_base); iounmap(esp->dma_regs); } if (host->base > 0xffffff) iounmap(esp->regs); scsi_host_put(host); zorro_release_device(z); kfree(zep); } static struct zorro_driver zorro_esp_driver = { .name = KBUILD_MODNAME, .id_table = zorro_esp_zorro_tbl, .probe = zorro_esp_probe, .remove = zorro_esp_remove, }; static int __init zorro_esp_scsi_init(void) { return zorro_register_driver(&zorro_esp_driver); } static void __exit zorro_esp_scsi_exit(void) { zorro_unregister_driver(&zorro_esp_driver); } module_init(zorro_esp_scsi_init); module_exit(zorro_esp_scsi_exit);
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1