Hi Michael,

On Sun, Mar 4, 2018 at 12:54 AM, Michael Schmitz <schmitz...@gmail.com> wrote:
> From: Michael Schmitz <schm...@debian.org>
>
> 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 -- ge...@linux-m68k.org

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

Reply via email to