linux/drivers/scsi/gvp11.c
<<
>>
Prefs
   1#include <linux/types.h>
   2#include <linux/init.h>
   3#include <linux/interrupt.h>
   4#include <linux/mm.h>
   5#include <linux/slab.h>
   6#include <linux/spinlock.h>
   7#include <linux/zorro.h>
   8#include <linux/module.h>
   9
  10#include <asm/page.h>
  11#include <asm/pgtable.h>
  12#include <asm/amigaints.h>
  13#include <asm/amigahw.h>
  14
  15#include "scsi.h"
  16#include "wd33c93.h"
  17#include "gvp11.h"
  18
  19
  20#define CHECK_WD33C93
  21
  22struct gvp11_hostdata {
  23        struct WD33C93_hostdata wh;
  24        struct gvp11_scsiregs *regs;
  25};
  26
  27static irqreturn_t gvp11_intr(int irq, void *data)
  28{
  29        struct Scsi_Host *instance = data;
  30        struct gvp11_hostdata *hdata = shost_priv(instance);
  31        unsigned int status = hdata->regs->CNTR;
  32        unsigned long flags;
  33
  34        if (!(status & GVP11_DMAC_INT_PENDING))
  35                return IRQ_NONE;
  36
  37        spin_lock_irqsave(instance->host_lock, flags);
  38        wd33c93_intr(instance);
  39        spin_unlock_irqrestore(instance->host_lock, flags);
  40        return IRQ_HANDLED;
  41}
  42
  43static int gvp11_xfer_mask = 0;
  44
  45void gvp11_setup(char *str, int *ints)
  46{
  47        gvp11_xfer_mask = ints[1];
  48}
  49
  50static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
  51{
  52        struct Scsi_Host *instance = cmd->device->host;
  53        struct gvp11_hostdata *hdata = shost_priv(instance);
  54        struct WD33C93_hostdata *wh = &hdata->wh;
  55        struct gvp11_scsiregs *regs = hdata->regs;
  56        unsigned short cntr = GVP11_DMAC_INT_ENABLE;
  57        unsigned long addr = virt_to_bus(cmd->SCp.ptr);
  58        int bank_mask;
  59        static int scsi_alloc_out_of_range = 0;
  60
  61        /* use bounce buffer if the physical address is bad */
  62        if (addr & wh->dma_xfer_mask) {
  63                wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff;
  64
  65                if (!scsi_alloc_out_of_range) {
  66                        wh->dma_bounce_buffer =
  67                                kmalloc(wh->dma_bounce_len, GFP_KERNEL);
  68                        wh->dma_buffer_pool = BUF_SCSI_ALLOCED;
  69                }
  70
  71                if (scsi_alloc_out_of_range ||
  72                    !wh->dma_bounce_buffer) {
  73                        wh->dma_bounce_buffer =
  74                                amiga_chip_alloc(wh->dma_bounce_len,
  75                                                 "GVP II SCSI Bounce Buffer");
  76
  77                        if (!wh->dma_bounce_buffer) {
  78                                wh->dma_bounce_len = 0;
  79                                return 1;
  80                        }
  81
  82                        wh->dma_buffer_pool = BUF_CHIP_ALLOCED;
  83                }
  84
  85                /* check if the address of the bounce buffer is OK */
  86                addr = virt_to_bus(wh->dma_bounce_buffer);
  87
  88                if (addr & wh->dma_xfer_mask) {
  89                        /* fall back to Chip RAM if address out of range */
  90                        if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED) {
  91                                kfree(wh->dma_bounce_buffer);
  92                                scsi_alloc_out_of_range = 1;
  93                        } else {
  94                                amiga_chip_free(wh->dma_bounce_buffer);
  95                        }
  96
  97                        wh->dma_bounce_buffer =
  98                                amiga_chip_alloc(wh->dma_bounce_len,
  99                                                 "GVP II SCSI Bounce Buffer");
 100
 101                        if (!wh->dma_bounce_buffer) {
 102                                wh->dma_bounce_len = 0;
 103                                return 1;
 104                        }
 105
 106                        addr = virt_to_bus(wh->dma_bounce_buffer);
 107                        wh->dma_buffer_pool = BUF_CHIP_ALLOCED;
 108                }
 109
 110                if (!dir_in) {
 111                        /* copy to bounce buffer for a write */
 112                        memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr,
 113                               cmd->SCp.this_residual);
 114                }
 115        }
 116
 117        /* setup dma direction */
 118        if (!dir_in)
 119                cntr |= GVP11_DMAC_DIR_WRITE;
 120
 121        wh->dma_dir = dir_in;
 122        regs->CNTR = cntr;
 123
 124        /* setup DMA *physical* address */
 125        regs->ACR = addr;
 126
 127        if (dir_in) {
 128                /* invalidate any cache */
 129                cache_clear(addr, cmd->SCp.this_residual);
 130        } else {
 131                /* push any dirty cache */
 132                cache_push(addr, cmd->SCp.this_residual);
 133        }
 134
 135        bank_mask = (~wh->dma_xfer_mask >> 18) & 0x01c0;
 136        if (bank_mask)
 137                regs->BANK = bank_mask & (addr >> 18);
 138
 139        /* start DMA */
 140        regs->ST_DMA = 1;
 141
 142        /* return success */
 143        return 0;
 144}
 145
 146static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
 147                     int status)
 148{
 149        struct gvp11_hostdata *hdata = shost_priv(instance);
 150        struct WD33C93_hostdata *wh = &hdata->wh;
 151        struct gvp11_scsiregs *regs = hdata->regs;
 152
 153        /* stop DMA */
 154        regs->SP_DMA = 1;
 155        /* remove write bit from CONTROL bits */
 156        regs->CNTR = GVP11_DMAC_INT_ENABLE;
 157
 158        /* copy from a bounce buffer, if necessary */
 159        if (status && wh->dma_bounce_buffer) {
 160                if (wh->dma_dir && SCpnt)
 161                        memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer,
 162                               SCpnt->SCp.this_residual);
 163
 164                if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED)
 165                        kfree(wh->dma_bounce_buffer);
 166                else
 167                        amiga_chip_free(wh->dma_bounce_buffer);
 168
 169                wh->dma_bounce_buffer = NULL;
 170                wh->dma_bounce_len = 0;
 171        }
 172}
 173
 174static int gvp11_bus_reset(struct scsi_cmnd *cmd)
 175{
 176        struct Scsi_Host *instance = cmd->device->host;
 177
 178        /* FIXME perform bus-specific reset */
 179
 180        /* FIXME 2: shouldn't we no-op this function (return
 181           FAILED), and fall back to host reset function,
 182           wd33c93_host_reset ? */
 183
 184        spin_lock_irq(instance->host_lock);
 185        wd33c93_host_reset(cmd);
 186        spin_unlock_irq(instance->host_lock);
 187
 188        return SUCCESS;
 189}
 190
 191static struct scsi_host_template gvp11_scsi_template = {
 192        .module                 = THIS_MODULE,
 193        .name                   = "GVP Series II SCSI",
 194        .proc_info              = wd33c93_proc_info,
 195        .proc_name              = "GVP11",
 196        .queuecommand           = wd33c93_queuecommand,
 197        .eh_abort_handler       = wd33c93_abort,
 198        .eh_bus_reset_handler   = gvp11_bus_reset,
 199        .eh_host_reset_handler  = wd33c93_host_reset,
 200        .can_queue              = CAN_QUEUE,
 201        .this_id                = 7,
 202        .sg_tablesize           = SG_ALL,
 203        .cmd_per_lun            = CMD_PER_LUN,
 204        .use_clustering         = DISABLE_CLUSTERING
 205};
 206
 207static int check_wd33c93(struct gvp11_scsiregs *regs)
 208{
 209#ifdef CHECK_WD33C93
 210        volatile unsigned char *sasr_3393, *scmd_3393;
 211        unsigned char save_sasr;
 212        unsigned char q, qq;
 213
 214        /*
 215         * These darn GVP boards are a problem - it can be tough to tell
 216         * whether or not they include a SCSI controller. This is the
 217         * ultimate Yet-Another-GVP-Detection-Hack in that it actually
 218         * probes for a WD33c93 chip: If we find one, it's extremely
 219         * likely that this card supports SCSI, regardless of Product_
 220         * Code, Board_Size, etc.
 221         */
 222
 223        /* Get pointers to the presumed register locations and save contents */
 224
 225        sasr_3393 = &regs->SASR;
 226        scmd_3393 = &regs->SCMD;
 227        save_sasr = *sasr_3393;
 228
 229        /* First test the AuxStatus Reg */
 230
 231        q = *sasr_3393; /* read it */
 232        if (q & 0x08)   /* bit 3 should always be clear */
 233                return -ENODEV;
 234        *sasr_3393 = WD_AUXILIARY_STATUS;       /* setup indirect address */
 235        if (*sasr_3393 == WD_AUXILIARY_STATUS) {        /* shouldn't retain the write */
 236                *sasr_3393 = save_sasr; /* Oops - restore this byte */
 237                return -ENODEV;
 238        }
 239        if (*sasr_3393 != q) {  /* should still read the same */
 240                *sasr_3393 = save_sasr; /* Oops - restore this byte */
 241                return -ENODEV;
 242        }
 243        if (*scmd_3393 != q)    /* and so should the image at 0x1f */
 244                return -ENODEV;
 245
 246        /*
 247         * Ok, we probably have a wd33c93, but let's check a few other places
 248         * for good measure. Make sure that this works for both 'A and 'B
 249         * chip versions.
 250         */
 251
 252        *sasr_3393 = WD_SCSI_STATUS;
 253        q = *scmd_3393;
 254        *sasr_3393 = WD_SCSI_STATUS;
 255        *scmd_3393 = ~q;
 256        *sasr_3393 = WD_SCSI_STATUS;
 257        qq = *scmd_3393;
 258        *sasr_3393 = WD_SCSI_STATUS;
 259        *scmd_3393 = q;
 260        if (qq != q)    /* should be read only */
 261                return -ENODEV;
 262        *sasr_3393 = 0x1e;      /* this register is unimplemented */
 263        q = *scmd_3393;
 264        *sasr_3393 = 0x1e;
 265        *scmd_3393 = ~q;
 266        *sasr_3393 = 0x1e;
 267        qq = *scmd_3393;
 268        *sasr_3393 = 0x1e;
 269        *scmd_3393 = q;
 270        if (qq != q || qq != 0xff)      /* should be read only, all 1's */
 271                return -ENODEV;
 272        *sasr_3393 = WD_TIMEOUT_PERIOD;
 273        q = *scmd_3393;
 274        *sasr_3393 = WD_TIMEOUT_PERIOD;
 275        *scmd_3393 = ~q;
 276        *sasr_3393 = WD_TIMEOUT_PERIOD;
 277        qq = *scmd_3393;
 278        *sasr_3393 = WD_TIMEOUT_PERIOD;
 279        *scmd_3393 = q;
 280        if (qq != (~q & 0xff))  /* should be read/write */
 281                return -ENODEV;
 282#endif /* CHECK_WD33C93 */
 283
 284        return 0;
 285}
 286
 287static int gvp11_probe(struct zorro_dev *z, const struct zorro_device_id *ent)
 288{
 289        struct Scsi_Host *instance;
 290        unsigned long address;
 291        int error;
 292        unsigned int epc;
 293        unsigned int default_dma_xfer_mask;
 294        struct gvp11_hostdata *hdata;
 295        struct gvp11_scsiregs *regs;
 296        wd33c93_regs wdregs;
 297
 298        default_dma_xfer_mask = ent->driver_data;
 299
 300        /*
 301         * Rumors state that some GVP ram boards use the same product
 302         * code as the SCSI controllers. Therefore if the board-size
 303         * is not 64KB we assume it is a ram board and bail out.
 304         */
 305        if (zorro_resource_len(z) != 0x10000)
 306                return -ENODEV;
 307
 308        address = z->resource.start;
 309        if (!request_mem_region(address, 256, "wd33c93"))
 310                return -EBUSY;
 311
 312        regs = (struct gvp11_scsiregs *)(ZTWO_VADDR(address));
 313
 314        error = check_wd33c93(regs);
 315        if (error)
 316                goto fail_check_or_alloc;
 317
 318        instance = scsi_host_alloc(&gvp11_scsi_template,
 319                                   sizeof(struct gvp11_hostdata));
 320        if (!instance) {
 321                error = -ENOMEM;
 322                goto fail_check_or_alloc;
 323        }
 324
 325        instance->irq = IRQ_AMIGA_PORTS;
 326        instance->unique_id = z->slotaddr;
 327
 328        regs->secret2 = 1;
 329        regs->secret1 = 0;
 330        regs->secret3 = 15;
 331        while (regs->CNTR & GVP11_DMAC_BUSY)
 332                ;
 333        regs->CNTR = 0;
 334        regs->BANK = 0;
 335
 336        wdregs.SASR = &regs->SASR;
 337        wdregs.SCMD = &regs->SCMD;
 338
 339        hdata = shost_priv(instance);
 340        if (gvp11_xfer_mask)
 341                hdata->wh.dma_xfer_mask = gvp11_xfer_mask;
 342        else
 343                hdata->wh.dma_xfer_mask = default_dma_xfer_mask;
 344
 345        hdata->wh.no_sync = 0xff;
 346        hdata->wh.fast = 0;
 347        hdata->wh.dma_mode = CTRL_DMA;
 348        hdata->regs = regs;
 349
 350        /*
 351         * Check for 14MHz SCSI clock
 352         */
 353        epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000);
 354        wd33c93_init(instance, wdregs, dma_setup, dma_stop,
 355                     (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10
 356                                             : WD33C93_FS_12_15);
 357
 358        error = request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED,
 359                            "GVP11 SCSI", instance);
 360        if (error)
 361                goto fail_irq;
 362
 363        regs->CNTR = GVP11_DMAC_INT_ENABLE;
 364
 365        error = scsi_add_host(instance, NULL);
 366        if (error)
 367                goto fail_host;
 368
 369        zorro_set_drvdata(z, instance);
 370        scsi_scan_host(instance);
 371        return 0;
 372
 373fail_host:
 374        free_irq(IRQ_AMIGA_PORTS, instance);
 375fail_irq:
 376        scsi_host_put(instance);
 377fail_check_or_alloc:
 378        release_mem_region(address, 256);
 379        return error;
 380}
 381
 382static void gvp11_remove(struct zorro_dev *z)
 383{
 384        struct Scsi_Host *instance = zorro_get_drvdata(z);
 385        struct gvp11_hostdata *hdata = shost_priv(instance);
 386
 387        hdata->regs->CNTR = 0;
 388        scsi_remove_host(instance);
 389        free_irq(IRQ_AMIGA_PORTS, instance);
 390        scsi_host_put(instance);
 391        release_mem_region(z->resource.start, 256);
 392}
 393
 394        /*
 395         * This should (hopefully) be the correct way to identify
 396         * all the different GVP SCSI controllers (except for the
 397         * SERIES I though).
 398         */
 399
 400static struct zorro_device_id gvp11_zorro_tbl[] = {
 401        { ZORRO_PROD_GVP_COMBO_030_R3_SCSI,     ~0x00ffffff },
 402        { ZORRO_PROD_GVP_SERIES_II,             ~0x00ffffff },
 403        { ZORRO_PROD_GVP_GFORCE_030_SCSI,       ~0x01ffffff },
 404        { ZORRO_PROD_GVP_A530_SCSI,             ~0x01ffffff },
 405        { ZORRO_PROD_GVP_COMBO_030_R4_SCSI,     ~0x01ffffff },
 406        { ZORRO_PROD_GVP_A1291,                 ~0x07ffffff },
 407        { ZORRO_PROD_GVP_GFORCE_040_SCSI_1,     ~0x07ffffff },
 408        { 0 }
 409};
 410MODULE_DEVICE_TABLE(zorro, gvp11_zorro_tbl);
 411
 412static struct zorro_driver gvp11_driver = {
 413        .name           = "gvp11",
 414        .id_table       = gvp11_zorro_tbl,
 415        .probe          = gvp11_probe,
 416        .remove         = gvp11_remove,
 417};
 418
 419static int __init gvp11_init(void)
 420{
 421        return zorro_register_driver(&gvp11_driver);
 422}
 423module_init(gvp11_init);
 424
 425static void __exit gvp11_exit(void)
 426{
 427        zorro_unregister_driver(&gvp11_driver);
 428}
 429module_exit(gvp11_exit);
 430
 431MODULE_DESCRIPTION("GVP Series II SCSI");
 432MODULE_LICENSE("GPL");
 433
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.