linux/drivers/scsi/aha1740.c
<<
>>
Prefs
   1/*  $Id$
   2 *  1993/03/31
   3 *  linux/kernel/aha1740.c
   4 *
   5 *  Based loosely on aha1542.c which is
   6 *  Copyright (C) 1992  Tommy Thorn and
   7 *  Modified by Eric Youngdale
   8 *
   9 *  This file is aha1740.c, written and
  10 *  Copyright (C) 1992,1993  Brad McLean
  11 *  brad@saturn.gaylord.com or brad@bradpc.gaylord.com.
  12 *  
  13 *  Modifications to makecode and queuecommand
  14 *  for proper handling of multiple devices courteously
  15 *  provided by Michael Weller, March, 1993
  16 *
  17 *  Multiple adapter support, extended translation detection,
  18 *  update to current scsi subsystem changes, proc fs support,
  19 *  working (!) module support based on patches from Andreas Arens,
  20 *  by Andreas Degert <ad@papyrus.hamburg.com>, 2/1997
  21 *
  22 * aha1740_makecode may still need even more work
  23 * if it doesn't work for your devices, take a look.
  24 *
  25 * Reworked for new_eh and new locking by Alan Cox <alan@lxorguk.ukuu.org.uk>
  26 *
  27 * Converted to EISA and generic DMA APIs by Marc Zyngier
  28 * <maz@wild-wind.fr.eu.org>, 4/2003.
  29 *
  30 * Shared interrupt support added by Rask Ingemann Lambertsen
  31 * <rask@sygehus.dk>, 10/2003
  32 *
  33 * For the avoidance of doubt the "preferred form" of this code is one which
  34 * is in an open non patent encumbered format. Where cryptographic key signing
  35 * forms part of the process of creating an executable the information
  36 * including keys needed to generate an equivalently functional executable
  37 * are deemed to be part of the source code.
  38 */
  39
  40#include <linux/blkdev.h>
  41#include <linux/interrupt.h>
  42#include <linux/module.h>
  43#include <linux/kernel.h>
  44#include <linux/types.h>
  45#include <linux/string.h>
  46#include <linux/ioport.h>
  47#include <linux/proc_fs.h>
  48#include <linux/stat.h>
  49#include <linux/init.h>
  50#include <linux/device.h>
  51#include <linux/eisa.h>
  52#include <linux/dma-mapping.h>
  53#include <linux/gfp.h>
  54
  55#include <asm/dma.h>
  56#include <asm/io.h>
  57
  58#include "scsi.h"
  59#include <scsi/scsi_host.h>
  60#include "aha1740.h"
  61
  62/* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
  63   IT WORK, THEN:
  64#define DEBUG
  65*/
  66#ifdef DEBUG
  67#define DEB(x) x
  68#else
  69#define DEB(x)
  70#endif
  71
  72struct aha1740_hostdata {
  73        struct eisa_device *edev;
  74        unsigned int translation;
  75        unsigned int last_ecb_used;
  76        dma_addr_t ecb_dma_addr;
  77        struct ecb ecb[AHA1740_ECBS];
  78};
  79
  80struct aha1740_sg {
  81        struct aha1740_chain sg_chain[AHA1740_SCATTER];
  82        dma_addr_t sg_dma_addr;
  83        dma_addr_t buf_dma_addr;
  84};
  85
  86#define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata)
  87
  88static inline struct ecb *ecb_dma_to_cpu (struct Scsi_Host *host,
  89                                          dma_addr_t dma)
  90{
  91        struct aha1740_hostdata *hdata = HOSTDATA (host);
  92        dma_addr_t offset;
  93
  94        offset = dma - hdata->ecb_dma_addr;
  95
  96        return (struct ecb *)(((char *) hdata->ecb) + (unsigned int) offset);
  97}
  98
  99static inline dma_addr_t ecb_cpu_to_dma (struct Scsi_Host *host, void *cpu)
 100{
 101        struct aha1740_hostdata *hdata = HOSTDATA (host);
 102        dma_addr_t offset;
 103    
 104        offset = (char *) cpu - (char *) hdata->ecb;
 105
 106        return hdata->ecb_dma_addr + offset;
 107}
 108
 109static int aha1740_show_info(struct seq_file *m, struct Scsi_Host *shpnt)
 110{
 111        struct aha1740_hostdata *host = HOSTDATA(shpnt);
 112        seq_printf(m, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n"
 113                      "Extended translation %sabled.\n",
 114                      shpnt->io_port, shpnt->irq, host->edev->slot,
 115                      host->translation ? "en" : "dis");
 116        return 0;
 117}
 118
 119static int aha1740_makecode(unchar *sense, unchar *status)
 120{
 121        struct statusword
 122        {
 123                ushort  don:1,  /* Command Done - No Error */
 124                        du:1,   /* Data underrun */
 125                    :1, qf:1,   /* Queue full */
 126                        sc:1,   /* Specification Check */
 127                        dor:1,  /* Data overrun */
 128                        ch:1,   /* Chaining Halted */
 129                        intr:1, /* Interrupt issued */
 130                        asa:1,  /* Additional Status Available */
 131                        sns:1,  /* Sense information Stored */
 132                    :1, ini:1,  /* Initialization Required */
 133                        me:1,   /* Major error or exception */
 134                    :1, eca:1,  /* Extended Contingent alliance */
 135                    :1;
 136        } status_word;
 137        int retval = DID_OK;
 138
 139        status_word = * (struct statusword *) status;
 140#ifdef DEBUG
 141        printk("makecode from %x,%x,%x,%x %x,%x,%x,%x",
 142               status[0], status[1], status[2], status[3],
 143               sense[0], sense[1], sense[2], sense[3]);
 144#endif
 145        if (!status_word.don) { /* Anything abnormal was detected */
 146                if ( (status[1]&0x18) || status_word.sc ) {
 147                        /*Additional info available*/
 148                        /* Use the supplied info for further diagnostics */
 149                        switch ( status[2] ) {
 150                        case 0x12:
 151                                if ( status_word.dor )
 152                                        retval=DID_ERROR; /* It's an Overrun */
 153                                /* If not overrun, assume underrun and
 154                                 * ignore it! */
 155                        case 0x00: /* No info, assume no error, should
 156                                    * not occur */
 157                                break;
 158                        case 0x11:
 159                        case 0x21:
 160                                retval=DID_TIME_OUT;
 161                                break;
 162                        case 0x0a:
 163                                retval=DID_BAD_TARGET;
 164                                break;
 165                        case 0x04:
 166                        case 0x05:
 167                                retval=DID_ABORT;
 168                                /* Either by this driver or the
 169                                 * AHA1740 itself */
 170                                break;
 171                        default:
 172                                retval=DID_ERROR; /* No further
 173                                                   * diagnostics
 174                                                   * possible */
 175                        }
 176                } else {
 177                        /* Michael suggests, and Brad concurs: */
 178                        if ( status_word.qf ) {
 179                                retval = DID_TIME_OUT; /* forces a redo */
 180                                /* I think this specific one should
 181                                 * not happen -Brad */
 182                                printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
 183                        } else
 184                                if ( status[0]&0x60 ) {
 185                                         /* Didn't find a better error */
 186                                        retval = DID_ERROR;
 187                                }
 188                        /* In any other case return DID_OK so for example
 189                           CONDITION_CHECKS make it through to the appropriate
 190                           device driver */
 191                }
 192        }
 193        /* Under all circumstances supply the target status -Michael */
 194        return status[3] | retval << 16;
 195}
 196
 197static int aha1740_test_port(unsigned int base)
 198{
 199        if ( inb(PORTADR(base)) & PORTADDR_ENH )
 200                return 1;   /* Okay, we're all set */
 201        
 202        printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n");
 203        return 0;
 204}
 205
 206/* A "high" level interrupt handler */
 207static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
 208{
 209        struct Scsi_Host *host = (struct Scsi_Host *) dev_id;
 210        void (*my_done)(struct scsi_cmnd *);
 211        int errstatus, adapstat;
 212        int number_serviced;
 213        struct ecb *ecbptr;
 214        struct scsi_cmnd *SCtmp;
 215        unsigned int base;
 216        unsigned long flags;
 217        int handled = 0;
 218        struct aha1740_sg *sgptr;
 219        struct eisa_device *edev;
 220        
 221        if (!host)
 222                panic("aha1740.c: Irq from unknown host!\n");
 223        spin_lock_irqsave(host->host_lock, flags);
 224        base = host->io_port;
 225        number_serviced = 0;
 226        edev = HOSTDATA(host)->edev;
 227
 228        while(inb(G2STAT(base)) & G2STAT_INTPEND) {
 229                handled = 1;
 230                DEB(printk("aha1740_intr top of loop.\n"));
 231                adapstat = inb(G2INTST(base));
 232                ecbptr = ecb_dma_to_cpu (host, inl(MBOXIN0(base)));
 233                outb(G2CNTRL_IRST,G2CNTRL(base)); /* interrupt reset */
 234      
 235                switch ( adapstat & G2INTST_MASK ) {
 236                case    G2INTST_CCBRETRY:
 237                case    G2INTST_CCBERROR:
 238                case    G2INTST_CCBGOOD:
 239                        /* Host Ready -> Mailbox in complete */
 240                        outb(G2CNTRL_HRDY,G2CNTRL(base));
 241                        if (!ecbptr) {
 242                                printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
 243                                       inb(G2STAT(base)),adapstat,
 244                                       inb(G2INTST(base)), number_serviced++);
 245                                continue;
 246                        }
 247                        SCtmp = ecbptr->SCpnt;
 248                        if (!SCtmp) {
 249                                printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
 250                                       inb(G2STAT(base)),adapstat,
 251                                       inb(G2INTST(base)), number_serviced++);
 252                                continue;
 253                        }
 254                        sgptr = (struct aha1740_sg *) SCtmp->host_scribble;
 255                        scsi_dma_unmap(SCtmp);
 256
 257                        /* Free the sg block */
 258                        dma_free_coherent (&edev->dev,
 259                                           sizeof (struct aha1740_sg),
 260                                           SCtmp->host_scribble,
 261                                           sgptr->sg_dma_addr);
 262            
 263                        /* Fetch the sense data, and tuck it away, in
 264                           the required slot.  The Adaptec
 265                           automatically fetches it, and there is no
 266                           guarantee that we will still have it in the
 267                           cdb when we come back */
 268                        if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR ) {
 269                                memcpy(SCtmp->sense_buffer, ecbptr->sense, 
 270                                       SCSI_SENSE_BUFFERSIZE);
 271                                errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
 272                        } else
 273                                errstatus = 0;
 274                        DEB(if (errstatus)
 275                            printk("aha1740_intr_handle: returning %6x\n",
 276                                   errstatus));
 277                        SCtmp->result = errstatus;
 278                        my_done = ecbptr->done;
 279                        memset(ecbptr,0,sizeof(struct ecb)); 
 280                        if ( my_done )
 281                                my_done(SCtmp);
 282                        break;
 283                        
 284                case    G2INTST_HARDFAIL:
 285                        printk(KERN_ALERT "aha1740 hardware failure!\n");
 286                        panic("aha1740.c");     /* Goodbye */
 287                        
 288                case    G2INTST_ASNEVENT:
 289                        printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
 290                               adapstat,
 291                               inb(MBOXIN0(base)),
 292                               inb(MBOXIN1(base)),
 293                               inb(MBOXIN2(base)),
 294                               inb(MBOXIN3(base))); /* Say What? */
 295                        /* Host Ready -> Mailbox in complete */
 296                        outb(G2CNTRL_HRDY,G2CNTRL(base));
 297                        break;
 298                        
 299                case    G2INTST_CMDGOOD:
 300                        /* set immediate command success flag here: */
 301                        break;
 302                        
 303                case    G2INTST_CMDERROR:
 304                        /* Set immediate command failure flag here: */
 305                        break;
 306                }
 307                number_serviced++;
 308        }
 309
 310        spin_unlock_irqrestore(host->host_lock, flags);
 311        return IRQ_RETVAL(handled);
 312}
 313
 314static int aha1740_queuecommand_lck(struct scsi_cmnd * SCpnt,
 315                                    void (*done)(struct scsi_cmnd *))
 316{
 317        unchar direction;
 318        unchar *cmd = (unchar *) SCpnt->cmnd;
 319        unchar target = scmd_id(SCpnt);
 320        struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host);
 321        unsigned long flags;
 322        dma_addr_t sg_dma;
 323        struct aha1740_sg *sgptr;
 324        int ecbno, nseg;
 325        DEB(int i);
 326
 327        if(*cmd == REQUEST_SENSE) {
 328                SCpnt->result = 0;
 329                done(SCpnt); 
 330                return 0;
 331        }
 332
 333#ifdef DEBUG
 334        if (*cmd == READ_10 || *cmd == WRITE_10)
 335                i = xscsi2int(cmd+2);
 336        else if (*cmd == READ_6 || *cmd == WRITE_6)
 337                i = scsi2int(cmd+2);
 338        else
 339                i = -1;
 340        printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ",
 341               target, *cmd, i, bufflen);
 342        printk("scsi cmd:");
 343        for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
 344        printk("\n");
 345#endif
 346
 347        /* locate an available ecb */
 348        spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 349        ecbno = host->last_ecb_used + 1; /* An optimization */
 350        if (ecbno >= AHA1740_ECBS)
 351                ecbno = 0;
 352        do {
 353                if (!host->ecb[ecbno].cmdw)
 354                        break;
 355                ecbno++;
 356                if (ecbno >= AHA1740_ECBS)
 357                        ecbno = 0;
 358        } while (ecbno != host->last_ecb_used);
 359
 360        if (host->ecb[ecbno].cmdw)
 361                panic("Unable to find empty ecb for aha1740.\n");
 362
 363        host->ecb[ecbno].cmdw = AHA1740CMD_INIT; /* SCSI Initiator Command
 364                                                    doubles as reserved flag */
 365
 366        host->last_ecb_used = ecbno;    
 367        spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 368
 369#ifdef DEBUG
 370        printk("Sending command (%d %x)...", ecbno, done);
 371#endif
 372
 373        host->ecb[ecbno].cdblen = SCpnt->cmd_len; /* SCSI Command
 374                                                   * Descriptor Block
 375                                                   * Length */
 376
 377        direction = 0;
 378        if (*cmd == READ_10 || *cmd == READ_6)
 379                direction = 1;
 380        else if (*cmd == WRITE_10 || *cmd == WRITE_6)
 381                direction = 0;
 382
 383        memcpy(host->ecb[ecbno].cdb, cmd, SCpnt->cmd_len);
 384
 385        SCpnt->host_scribble = dma_alloc_coherent (&host->edev->dev,
 386                                                   sizeof (struct aha1740_sg),
 387                                                   &sg_dma, GFP_ATOMIC);
 388        if(SCpnt->host_scribble == NULL) {
 389                printk(KERN_WARNING "aha1740: out of memory in queuecommand!\n");
 390                return 1;
 391        }
 392        sgptr = (struct aha1740_sg *) SCpnt->host_scribble;
 393        sgptr->sg_dma_addr = sg_dma;
 394
 395        nseg = scsi_dma_map(SCpnt);
 396        BUG_ON(nseg < 0);
 397        if (nseg) {
 398                struct scatterlist *sg;
 399                struct aha1740_chain * cptr;
 400                int i;
 401                DEB(unsigned char * ptr);
 402
 403                host->ecb[ecbno].sg = 1;  /* SCSI Initiator Command
 404                                           * w/scatter-gather*/
 405                cptr = sgptr->sg_chain;
 406                scsi_for_each_sg(SCpnt, sg, nseg, i) {
 407                        cptr[i].datalen = sg_dma_len (sg);
 408                        cptr[i].dataptr = sg_dma_address (sg);
 409                }
 410                host->ecb[ecbno].datalen = nseg * sizeof(struct aha1740_chain);
 411                host->ecb[ecbno].dataptr = sg_dma;
 412#ifdef DEBUG
 413                printk("cptr %x: ",cptr);
 414                ptr = (unsigned char *) cptr;
 415                for(i=0;i<24;i++) printk("%02x ", ptr[i]);
 416#endif
 417        } else {
 418                host->ecb[ecbno].datalen = 0;
 419                host->ecb[ecbno].dataptr = 0;
 420        }
 421        host->ecb[ecbno].lun = SCpnt->device->lun;
 422        host->ecb[ecbno].ses = 1; /* Suppress underrun errors */
 423        host->ecb[ecbno].dir = direction;
 424        host->ecb[ecbno].ars = 1; /* Yes, get the sense on an error */
 425        host->ecb[ecbno].senselen = 12;
 426        host->ecb[ecbno].senseptr = ecb_cpu_to_dma (SCpnt->device->host,
 427                                                    host->ecb[ecbno].sense);
 428        host->ecb[ecbno].statusptr = ecb_cpu_to_dma (SCpnt->device->host,
 429                                                     host->ecb[ecbno].status);
 430        host->ecb[ecbno].done = done;
 431        host->ecb[ecbno].SCpnt = SCpnt;
 432#ifdef DEBUG
 433        {
 434                int i;
 435                printk("aha1740_command: sending.. ");
 436                for (i = 0; i < sizeof(host->ecb[ecbno]) - 10; i++)
 437                        printk("%02x ", ((unchar *)&host->ecb[ecbno])[i]);
 438        }
 439        printk("\n");
 440#endif
 441        if (done) {
 442        /* The Adaptec Spec says the card is so fast that the loops
 443           will only be executed once in the code below. Even if this
 444           was true with the fastest processors when the spec was
 445           written, it doesn't seem to be true with today's fast
 446           processors. We print a warning if the code is executed more
 447           often than LOOPCNT_WARN. If this happens, it should be
 448           investigated. If the count reaches LOOPCNT_MAX, we assume
 449           something is broken; since there is no way to return an
 450           error (the return value is ignored by the mid-level scsi
 451           layer) we have to panic (and maybe that's the best thing we
 452           can do then anyhow). */
 453
 454#define LOOPCNT_WARN 10         /* excessive mbxout wait -> syslog-msg */
 455#define LOOPCNT_MAX 1000000     /* mbxout deadlock -> panic() after ~ 2 sec. */
 456                int loopcnt;
 457                unsigned int base = SCpnt->device->host->io_port;
 458                DEB(printk("aha1740[%d] critical section\n",ecbno));
 459
 460                spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 461                for (loopcnt = 0; ; loopcnt++) {
 462                        if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
 463                        if (loopcnt == LOOPCNT_WARN) {
 464                                printk("aha1740[%d]_mbxout wait!\n",ecbno);
 465                        }
 466                        if (loopcnt == LOOPCNT_MAX)
 467                                panic("aha1740.c: mbxout busy!\n");
 468                }
 469                outl (ecb_cpu_to_dma (SCpnt->device->host, host->ecb + ecbno),
 470                      MBOXOUT0(base));
 471                for (loopcnt = 0; ; loopcnt++) {
 472                        if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break;
 473                        if (loopcnt == LOOPCNT_WARN) {
 474                                printk("aha1740[%d]_attn wait!\n",ecbno);
 475                        }
 476                        if (loopcnt == LOOPCNT_MAX)
 477                                panic("aha1740.c: attn wait failed!\n");
 478                }
 479                outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
 480                spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 481                DEB(printk("aha1740[%d] request queued.\n",ecbno));
 482        } else
 483                printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
 484        return 0;
 485}
 486
 487static DEF_SCSI_QCMD(aha1740_queuecommand)
 488
 489/* Query the board for its irq_level and irq_type.  Nothing else matters
 490   in enhanced mode on an EISA bus. */
 491
 492static void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
 493                              unsigned int *irq_type,
 494                              unsigned int *translation)
 495{
 496        static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
 497
 498        *irq_level = intab[inb(INTDEF(base)) & 0x7];
 499        *irq_type  = (inb(INTDEF(base)) & 0x8) >> 3;
 500        *translation = inb(RESV1(base)) & 0x1;
 501        outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
 502}
 503
 504static int aha1740_biosparam(struct scsi_device *sdev,
 505                             struct block_device *dev,
 506                             sector_t capacity, int* ip)
 507{
 508        int size = capacity;
 509        int extended = HOSTDATA(sdev->host)->translation;
 510
 511        DEB(printk("aha1740_biosparam\n"));
 512        if (extended && (ip[2] > 1024)) {
 513                ip[0] = 255;
 514                ip[1] = 63;
 515                ip[2] = size / (255 * 63);
 516        } else {
 517                ip[0] = 64;
 518                ip[1] = 32;
 519                ip[2] = size >> 11;
 520        }
 521        return 0;
 522}
 523
 524static int aha1740_eh_abort_handler (struct scsi_cmnd *dummy)
 525{
 526/*
 527 * From Alan Cox :
 528 * The AHA1740 has firmware handled abort/reset handling. The "head in
 529 * sand" kernel code is correct for once 8)
 530 *
 531 * So we define a dummy handler just to keep the kernel SCSI code as
 532 * quiet as possible...
 533 */
 534
 535        return SUCCESS;
 536}
 537
 538static struct scsi_host_template aha1740_template = {
 539        .module           = THIS_MODULE,
 540        .proc_name        = "aha1740",
 541        .show_info        = aha1740_show_info,
 542        .name             = "Adaptec 174x (EISA)",
 543        .queuecommand     = aha1740_queuecommand,
 544        .bios_param       = aha1740_biosparam,
 545        .can_queue        = AHA1740_ECBS,
 546        .this_id          = 7,
 547        .sg_tablesize     = AHA1740_SCATTER,
 548        .eh_abort_handler = aha1740_eh_abort_handler,
 549};
 550
 551static int aha1740_probe (struct device *dev)
 552{
 553        int slotbase, rc;
 554        unsigned int irq_level, irq_type, translation;
 555        struct Scsi_Host *shpnt;
 556        struct aha1740_hostdata *host;
 557        struct eisa_device *edev = to_eisa_device (dev);
 558
 559        DEB(printk("aha1740_probe: \n"));
 560        
 561        slotbase = edev->base_addr + EISA_VENDOR_ID_OFFSET;
 562        if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */
 563                return -EBUSY;
 564        if (!aha1740_test_port(slotbase))
 565                goto err_release_region;
 566        aha1740_getconfig(slotbase,&irq_level,&irq_type,&translation);
 567        if ((inb(G2STAT(slotbase)) &
 568             (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) {
 569                /* If the card isn't ready, hard reset it */
 570                outb(G2CNTRL_HRST, G2CNTRL(slotbase));
 571                outb(0, G2CNTRL(slotbase));
 572        }
 573        printk(KERN_INFO "Configuring slot %d at IO:%x, IRQ %u (%s)\n",
 574               edev->slot, slotbase, irq_level, irq_type ? "edge" : "level");
 575        printk(KERN_INFO "aha174x: Extended translation %sabled.\n",
 576               translation ? "en" : "dis");
 577        shpnt = scsi_host_alloc(&aha1740_template,
 578                              sizeof(struct aha1740_hostdata));
 579        if(shpnt == NULL)
 580                goto err_release_region;
 581
 582        shpnt->base = 0;
 583        shpnt->io_port = slotbase;
 584        shpnt->n_io_port = SLOTSIZE;
 585        shpnt->irq = irq_level;
 586        shpnt->dma_channel = 0xff;
 587        host = HOSTDATA(shpnt);
 588        host->edev = edev;
 589        host->translation = translation;
 590        host->ecb_dma_addr = dma_map_single (&edev->dev, host->ecb,
 591                                             sizeof (host->ecb),
 592                                             DMA_BIDIRECTIONAL);
 593        if (!host->ecb_dma_addr) {
 594                printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n");
 595                goto err_host_put;
 596        }
 597        
 598        DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level));
 599        if (request_irq(irq_level,aha1740_intr_handle,irq_type ? 0 : IRQF_SHARED,
 600                        "aha1740",shpnt)) {
 601                printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n",
 602                       irq_level);
 603                goto err_unmap;
 604        }
 605
 606        eisa_set_drvdata (edev, shpnt);
 607
 608        rc = scsi_add_host (shpnt, dev);
 609        if (rc)
 610                goto err_irq;
 611
 612        scsi_scan_host (shpnt);
 613        return 0;
 614
 615 err_irq:
 616        free_irq(irq_level, shpnt);
 617 err_unmap:
 618        dma_unmap_single (&edev->dev, host->ecb_dma_addr,
 619                          sizeof (host->ecb), DMA_BIDIRECTIONAL);
 620 err_host_put:
 621        scsi_host_put (shpnt);
 622 err_release_region:
 623        release_region(slotbase, SLOTSIZE);
 624
 625        return -ENODEV;
 626}
 627
 628static int aha1740_remove (struct device *dev)
 629{
 630        struct Scsi_Host *shpnt = dev_get_drvdata(dev);
 631        struct aha1740_hostdata *host = HOSTDATA (shpnt);
 632
 633        scsi_remove_host(shpnt);
 634        
 635        free_irq (shpnt->irq, shpnt);
 636        dma_unmap_single (dev, host->ecb_dma_addr,
 637                          sizeof (host->ecb), DMA_BIDIRECTIONAL);
 638        release_region (shpnt->io_port, SLOTSIZE);
 639
 640        scsi_host_put (shpnt);
 641        
 642        return 0;
 643}
 644
 645static struct eisa_device_id aha1740_ids[] = {
 646        { "ADP0000" },          /* 1740  */
 647        { "ADP0001" },          /* 1740A */
 648        { "ADP0002" },          /* 1742A */
 649        { "ADP0400" },          /* 1744  */
 650        { "" }
 651};
 652MODULE_DEVICE_TABLE(eisa, aha1740_ids);
 653
 654static struct eisa_driver aha1740_driver = {
 655        .id_table = aha1740_ids,
 656        .driver   = {
 657                .name    = "aha1740",
 658                .probe   = aha1740_probe,
 659                .remove  = aha1740_remove,
 660        },
 661};
 662
 663static __init int aha1740_init (void)
 664{
 665        return eisa_driver_register (&aha1740_driver);
 666}
 667
 668static __exit void aha1740_exit (void)
 669{
 670        eisa_driver_unregister (&aha1740_driver);
 671}
 672
 673module_init (aha1740_init);
 674module_exit (aha1740_exit);
 675
 676MODULE_LICENSE("GPL");
 677