Hi Michael, On Sun, Mar 4, 2018 at 12:54 AM, Michael Schmitz <schmitzmic@xxxxxxxxx> wrote:
From: Michael Schmitz <schmitz@xxxxxxxxxx> New combined SCSI driver for all ESP based Zorro SCSI boards for m68k Amiga.
Thanks for your patch!
--- /dev/null +++ b/drivers/scsi/zorro_esp.c @@ -0,0 +1,785 @@
+static struct zorro_driver_data { + const char *name; + unsigned long offset; + unsigned long dma_offset; + int absolute; + int zorro3; /* offset is absolute address */
zorro3 is unused.
+} zorro_esp_driver_data[] = { + { .name = "CyberStormI", .offset = 0xf400, .dma_offset = 0xf800, + .absolute = 0, .zorro3 = 0 }, + { .name = "CyberStormII", .offset = 0x1ff03, .dma_offset = 0x1ff43, + .absolute = 0, .zorro3 = 0 }, + { .name = "Blizzard 2060", .offset = 0x1ff00, .dma_offset = 0x1ffe0, + .absolute = 0, .zorro3 = 0 }, + { .name = "Blizzard 1230", .offset = 0x8000, .dma_offset = 0x10000, + .absolute = 0, .zorro3 = 0 }, + { .name = "Blizzard 1230II", .offset = 0x10000, .dma_offset = 0x10021, + .absolute = 0, .zorro3 = 0 }, + { .name = "Fastlane", .offset = 0x1000001, .dma_offset = 0x1000041, + .absolute = 0, .zorro3 = 1 }, + { 0 }
I think it's better to not use an array here, but individual structs: static struct zorro_driver_data cyberstorm_data = ... static struct zorro_driver_data cyberstorm2_data = ... ... That makes it easier to review the references from zorro_esp_zorro_tbl[] below.
+}; + +static struct zorro_device_id zorro_esp_zorro_tbl[] = { + { + .id = ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM, + .driver_data = (unsigned long)&zorro_esp_driver_data[0], + },
[...]
+static unsigned char ctrl_data; /* Keep backup of the stuff written + * to ctrl_reg. Always write a copy + * to this register when writing to + * the hardware register! + */
This should be part of the device's zorro_esp_priv.
+/* + * private data used for PIO + */ +struct zorro_esp_priv { + struct esp *esp; + int error; +} zorro_esp_private_data[8];
Dynamic allocation, please.
+static void zorro_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, + u32 dma_count, int write, u8 cmd) +{ + struct zorro_esp_priv *zep = ZORRO_ESP_GET_PRIV(esp); + u8 __iomem *fifo = esp->regs + ESP_FDATA * 16; + u8 phase = esp->sreg & ESP_STAT_PMASK; + + cmd &= ~ESP_CMD_DMA; + zep->error = 0; + + /* We are passed DMA addresses i.e. physical addresses, but must use + * kernel virtual addresses here, so remap to virtual. This is easy + * enough for the case of residual bytes of an extended message in + * transfer - we know the address must be esp->command_block_dma. + * In other cases, hope that phys_to_virt() works ... + */ + if (addr == esp->command_block_dma) + addr = (u32) esp->command_block; + else + addr = (u32) phys_to_virt(addr);
To avoid having a need for phys_to_virt(), you should remember the addresses passed to/returned from dma_map_*(). if you assign the address to a different variable with the proper type, you don't need the cast below.... + if (write) { + u8 *dst = (u8 *)addr; ... here.
+ } else {
The read case doesn't use addr?
+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 *dregs = + (struct blz1230_dma_registers *) (esp->dma_regs); + u8 phase = esp->sreg & ESP_STAT_PMASK; + + if (phase == ESP_MIP) { + zorro_esp_send_pio_cmd(esp, addr, esp_count, + dma_count, write, cmd); + return; + } + + BUG_ON(!(cmd & ESP_CMD_DMA)); + + if (write) + cache_clear(addr, esp_count); + else + cache_push(addr, esp_count);
dma_sync_*()
+static int zorro_esp_init_one(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; + struct zorro_driver_data *zdd; + struct zorro_esp_priv *zep; + unsigned long board, ioaddr, dmaaddr; + int err = -ENOMEM;
Initialization not needed.
+ + board = zorro_resource_start(z); + zdd = (struct zorro_driver_data *)ent->driver_data; + + pr_info(PFX "%s found at address 0x%lx.\n", zdd->name, board); + + 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(PFX "cannot reserve region 0x%lx, abort\n", + board); + return -EBUSY; + } + + /* Fill in the required pieces of hostdata */ + + host = scsi_host_alloc(tpnt, sizeof(struct esp)); + + if (!host) { + pr_err(PFX "No host detected; board configuration problem?\n"); + goto out_free; + } + + 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); + + /* Switch to the correct the DMA routine and clock frequency. */ + switch (ent->id) { + case ZORRO_PROD_PHASE5_BLIZZARD_2060: { + zorro_esp_ops.send_dma_cmd = zorro_esp_send_blz2060_dma_cmd; + esp->cfreq = 40000000; + break; + } + case ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260: { + zorro_esp_ops.send_dma_cmd = zorro_esp_send_blz1230_dma_cmd; + esp->cfreq = 40000000; + break; + } + case ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM: { + zorro_esp_ops.send_dma_cmd = zorro_esp_send_cyber_dma_cmd; + zorro_esp_ops.irq_pending = cyber_esp_irq_pending; + esp->cfreq = 40000000; + break;
Store send_dma_cmd and cfreq in zorro_driver_data?
+ } + default: { + /* Oh noes */ + pr_err(PFX "Unsupported board!\n"); + goto fail_free_host; + } + } + + esp->ops = &zorro_esp_ops; + + if (ioaddr > 0xffffff) + esp->regs = ioremap_nocache(ioaddr, 0x20); + else + esp->regs = (void __iomem *)ZTWO_VADDR(ioaddr); + + if (!esp->regs) + goto fail_free_host; + + /* Let's check whether a Blizzard 12x0 really has SCSI */ + if ((ent->id == ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260) || + (ent->id == ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060)) {
Add a flag to zorro_driver_data (optional_scsi?) instead of checking for IDs here. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line "unsubscribe linux-m68k" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html