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                                break;
 156                        case 0x00: /* No info, assume no error, should
 157                                    * not occur */
 158                                break;
 159                        case 0x11:
 160                        case 0x21:
 161                                retval=DID_TIME_OUT;
 162                                break;
 163                        case 0x0a:
 164                                retval=DID_BAD_TARGET;
 165                                break;
 166                        case 0x04:
 167                        case 0x05:
 168                                retval=DID_ABORT;
 169                                /* Either by this driver or the
 170                                 * AHA1740 itself */
 171                                break;
 172                        default:
 173                                retval=DID_ERROR; /* No further
 174                                                   * diagnostics
 175                                                   * possible */
 176                        }
 177                } else {
 178                        /* Michael suggests, and Brad concurs: */
 179                        if ( status_word.qf ) {
 180                                retval = DID_TIME_OUT; /* forces a redo */
 181                                /* I think this specific one should
 182                                 * not happen -Brad */
 183                                printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
 184                        } else
 185                                if ( status[0]&0x60 ) {
 186                                         /* Didn't find a better error */
 187                                        retval = DID_ERROR;
 188                                }
 189                        /* In any other case return DID_OK so for example
 190                           CONDITION_CHECKS make it through to the appropriate
 191                           device driver */
 192                }
 193        }
 194        /* Under all circumstances supply the target status -Michael */
 195        return status[3] | retval << 16;
 196}
 197
 198static int aha1740_test_port(unsigned int base)
 199{
 200        if ( inb(PORTADR(base)) & PORTADDR_ENH )
 201                return 1;   /* Okay, we're all set */
 202        
 203        printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n");
 204        return 0;
 205}
 206
 207/* A "high" level interrupt handler */
 208static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
 209{
 210        struct Scsi_Host *host = (struct Scsi_Host *) dev_id;
 211        void (*my_done)(struct scsi_cmnd *);
 212        int errstatus, adapstat;
 213        int number_serviced;
 214        struct ecb *ecbptr;
 215        struct scsi_cmnd *SCtmp;
 216        unsigned int base;
 217        unsigned long flags;
 218        int handled = 0;
 219        struct aha1740_sg *sgptr;
 220        struct eisa_device *edev;
 221        
 222        if (!host)
 223                panic("aha1740.c: Irq from unknown host!\n");
 224        spin_lock_irqsave(host->host_lock, flags);
 225        base = host->io_port;
 226        number_serviced = 0;
 227        edev = HOSTDATA(host)->edev;
 228
 229        while(inb(G2STAT(base)) & G2STAT_INTPEND) {
 230                handled = 1;
 231                DEB(printk("aha1740_intr top of loop.\n"));
 232                adapstat = inb(G2INTST(base));
 233                ecbptr = ecb_dma_to_cpu (host, inl(MBOXIN0(base)));
 234                outb(G2CNTRL_IRST,G2CNTRL(base)); /* interrupt reset */
 235      
 236                switch ( adapstat & G2INTST_MASK ) {
 237                case    G2INTST_CCBRETRY:
 238                case    G2INTST_CCBERROR:
 239                case    G2INTST_CCBGOOD:
 240                        /* Host Ready -> Mailbox in complete */
 241                        outb(G2CNTRL_HRDY,G2CNTRL(base));
 242                        if (!ecbptr) {
 243                                printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
 244                                       inb(G2STAT(base)),adapstat,
 245                                       inb(G2INTST(base)), number_serviced++);
 246                                continue;
 247                        }
 248                        SCtmp = ecbptr->SCpnt;
 249                        if (!SCtmp) {
 250                                printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
 251                                       inb(G2STAT(base)),adapstat,
 252                                       inb(G2INTST(base)), number_serviced++);
 253                                continue;
 254                        }
 255                        sgptr = (struct aha1740_sg *) SCtmp->host_scribble;
 256                        scsi_dma_unmap(SCtmp);
 257
 258                        /* Free the sg block */
 259                        dma_free_coherent (&edev->dev,
 260                                           sizeof (struct aha1740_sg),
 261                                           SCtmp->host_scribble,
 262                                           sgptr->sg_dma_addr);
 263            
 264                        /* Fetch the sense data, and tuck it away, in
 265                           the required slot.  The Adaptec
 266                           automatically fetches it, and there is no
 267                           guarantee that we will still have it in the
 268                           cdb when we come back */
 269                        if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR ) {
 270                                memcpy(SCtmp->sense_buffer, ecbptr->sense, 
 271                                       SCSI_SENSE_BUFFERSIZE);
 272                                errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
 273                        } else
 274                                errstatus = 0;
 275                        DEB(if (errstatus)
 276                            printk("aha1740_intr_handle: returning %6x\n",
 277                                   errstatus));
 278                        SCtmp->result = errstatus;
 279                        my_done = ecbptr->done;
 280                        memset(ecbptr,0,sizeof(struct ecb)); 
 281                        if ( my_done )
 282                                my_done(SCtmp);
 283                        break;
 284                        
 285                case    G2INTST_HARDFAIL:
 286                        printk(KERN_ALERT "aha1740 hardware failure!\n");
 287                        panic("aha1740.c");     /* Goodbye */
 288                        
 289                case    G2INTST_ASNEVENT:
 290                        printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
 291                               adapstat,
 292                               inb(MBOXIN0(base)),
 293                               inb(MBOXIN1(base)),
 294                               inb(MBOXIN2(base)),
 295                               inb(MBOXIN3(base))); /* Say What? */
 296                        /* Host Ready -> Mailbox in complete */
 297                        outb(G2CNTRL_HRDY,G2CNTRL(base));
 298                        break;
 299                        
 300                case    G2INTST_CMDGOOD:
 301                        /* set immediate command success flag here: */
 302                        break;
 303                        
 304                case    G2INTST_CMDERROR:
 305                        /* Set immediate command failure flag here: */
 306                        break;
 307                }
 308                number_serviced++;
 309        }
 310
 311        spin_unlock_irqrestore(host->host_lock, flags);
 312        return IRQ_RETVAL(handled);
 313}
 314
 315static int aha1740_queuecommand_lck(struct scsi_cmnd * SCpnt,
 316                                    void (*done)(struct scsi_cmnd *))
 317{
 318        unchar direction;
 319        unchar *cmd = (unchar *) SCpnt->cmnd;
 320        unchar target = scmd_id(SCpnt);
 321        struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host);
 322        unsigned long flags;
 323        dma_addr_t sg_dma;
 324        struct aha1740_sg *sgptr;
 325        int ecbno, nseg;
 326        DEB(int i);
 327
 328        if(*cmd == REQUEST_SENSE) {
 329                SCpnt->result = 0;
 330                done(SCpnt); 
 331                return 0;
 332        }
 333
 334#ifdef DEBUG
 335        if (*cmd == READ_10 || *cmd == WRITE_10)
 336                i = xscsi2int(cmd+2);
 337        else if (*cmd == READ_6 || *cmd == WRITE_6)
 338                i = scsi2int(cmd+2);
 339        else
 340                i = -1;
 341        printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ",
 342               target, *cmd, i, bufflen);
 343        printk("scsi cmd:");
 344        for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
 345        printk("\n");
 346#endif
 347
 348        /* locate an available ecb */
 349        spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 350        ecbno = host->last_ecb_used + 1; /* An optimization */
 351        if (ecbno >= AHA1740_ECBS)
 352                ecbno = 0;
 353        do {
 354                if (!host->ecb[ecbno].cmdw)
 355                        break;
 356                ecbno++;
 357                if (ecbno >= AHA1740_ECBS)
 358                        ecbno = 0;
 359        } while (ecbno != host->last_ecb_used);
 360
 361        if (host->ecb[ecbno].cmdw)
 362                panic("Unable to find empty ecb for aha1740.\n");
 363
 364        host->ecb[ecbno].cmdw = AHA1740CMD_INIT; /* SCSI Initiator Command
 365                                                    doubles as reserved flag */
 366
 367        host->last_ecb_used = ecbno;    
 368        spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 369
 370#ifdef DEBUG
 371        printk("Sending command (%d %x)...", ecbno, done);
 372#endif
 373
 374        host->ecb[ecbno].cdblen = SCpnt->cmd_len; /* SCSI Command
 375                                                   * Descriptor Block
 376                                                   * Length */
 377
 378        direction = 0;
 379        if (*cmd == READ_10 || *cmd == READ_6)
 380                direction = 1;
 381        else if (*cmd == WRITE_10 || *cmd == WRITE_6)
 382                direction = 0;
 383
 384        memcpy(host->ecb[ecbno].cdb, cmd, SCpnt->cmd_len);
 385
 386        SCpnt->host_scribble = dma_alloc_coherent (&host->edev->dev,
 387                                                   sizeof (struct aha1740_sg),
 388                                                   &sg_dma, GFP_ATOMIC);
 389        if(SCpnt->host_scribble == NULL) {
 390                printk(KERN_WARNING "aha1740: out of memory in queuecommand!\n");
 391                return 1;
 392        }
 393        sgptr = (struct aha1740_sg *) SCpnt->host_scribble;
 394        sgptr->sg_dma_addr = sg_dma;
 395
 396        nseg = scsi_dma_map(SCpnt);
 397        BUG_ON(nseg < 0);
 398        if (nseg) {
 399                struct scatterlist *sg;
 400                struct aha1740_chain * cptr;
 401                int i;
 402                DEB(unsigned char * ptr);
 403
 404                host->ecb[ecbno].sg = 1;  /* SCSI Initiator Command
 405                                           * w/scatter-gather*/
 406                cptr = sgptr->sg_chain;
 407                scsi_for_each_sg(SCpnt, sg, nseg, i) {
 408                        cptr[i].datalen = sg_dma_len (sg);
 409                        cptr[i].dataptr = sg_dma_address (sg);
 410                }
 411                host->ecb[ecbno].datalen = nseg * sizeof(struct aha1740_chain);
 412                host->ecb[ecbno].dataptr = sg_dma;
 413#ifdef DEBUG
 414                printk("cptr %x: ",cptr);
 415                ptr = (unsigned char *) cptr;
 416                for(i=0;i<24;i++) printk("%02x ", ptr[i]);
 417#endif
 418        } else {
 419                host->ecb[ecbno].datalen = 0;
 420                host->ecb[ecbno].dataptr = 0;
 421        }
 422        host->ecb[ecbno].lun = SCpnt->device->lun;
 423        host->ecb[ecbno].ses = 1; /* Suppress underrun errors */
 424        host->ecb[ecbno].dir = direction;
 425        host->ecb[ecbno].ars = 1; /* Yes, get the sense on an error */
 426        host->ecb[ecbno].senselen = 12;
 427        host->ecb[ecbno].senseptr = ecb_cpu_to_dma (SCpnt->device->host,
 428                                                    host->ecb[ecbno].sense);
 429        host->ecb[ecbno].statusptr = ecb_cpu_to_dma (SCpnt->device->host,
 430                                                     host->ecb[ecbno].status);
 431        host->ecb[ecbno].done = done;
 432        host->ecb[ecbno].SCpnt = SCpnt;
 433#ifdef DEBUG
 434        {
 435                int i;
 436                printk("aha1740_command: sending.. ");
 437                for (i = 0; i < sizeof(host->ecb[ecbno]) - 10; i++)
 438                        printk("%02x ", ((unchar *)&host->ecb[ecbno])[i]);
 439        }
 440        printk("\n");
 441#endif
 442        if (done) {
 443        /* The Adaptec Spec says the card is so fast that the loops
 444           will only be executed once in the code below. Even if this
 445           was true with the fastest processors when the spec was
 446           written, it doesn't seem to be true with today's fast
 447           processors. We print a warning if the code is executed more
 448           often than LOOPCNT_WARN. If this happens, it should be
 449           investigated. If the count reaches LOOPCNT_MAX, we assume
 450           something is broken; since there is no way to return an
 451           error (the return value is ignored by the mid-level scsi
 452           layer) we have to panic (and maybe that's the best thing we
 453           can do then anyhow). */
 454
 455#define LOOPCNT_WARN 10         /* excessive mbxout wait -> syslog-msg */
 456#define LOOPCNT_MAX 1000000     /* mbxout deadlock -> panic() after ~ 2 sec. */
 457                int loopcnt;
 458                unsigned int base = SCpnt->device->host->io_port;
 459                DEB(printk("aha1740[%d] critical section\n",ecbno));
 460
 461                spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 462                for (loopcnt = 0; ; loopcnt++) {
 463                        if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
 464                        if (loopcnt == LOOPCNT_WARN) {
 465                                printk("aha1740[%d]_mbxout wait!\n",ecbno);
 466                        }
 467                        if (loopcnt == LOOPCNT_MAX)
 468                                panic("aha1740.c: mbxout busy!\n");
 469                }
 470                outl (ecb_cpu_to_dma (SCpnt->device->host, host->ecb + ecbno),
 471                      MBOXOUT0(base));
 472                for (loopcnt = 0; ; loopcnt++) {
 473                        if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break;
 474                        if (loopcnt == LOOPCNT_WARN) {
 475                                printk("aha1740[%d]_attn wait!\n",ecbno);
 476                        }
 477                        if (loopcnt == LOOPCNT_MAX)
 478                                panic("aha1740.c: attn wait failed!\n");
 479                }
 480                outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
 481                spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 482                DEB(printk("aha1740[%d] request queued.\n",ecbno));
 483        } else
 484                printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
 485        return 0;
 486}
 487
 488static DEF_SCSI_QCMD(aha1740_queuecommand)
 489
 490/* Query the board for its irq_level and irq_type.  Nothing else matters
 491   in enhanced mode on an EISA bus. */
 492
 493static void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
 494                              unsigned int *irq_type,
 495                              unsigned int *translation)
 496{
 497        static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
 498
 499        *irq_level = intab[inb(INTDEF(base)) & 0x7];
 500        *irq_type  = (inb(INTDEF(base)) & 0x8) >> 3;
 501        *translation = inb(RESV1(base)) & 0x1;
 502        outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
 503}
 504
 505static int aha1740_biosparam(struct scsi_device *sdev,
 506                             struct block_device *dev,
 507                             sector_t capacity, int* ip)
 508{
 509        int size = capacity;
 510        int extended = HOSTDATA(sdev->host)->translation;
 511
 512        DEB(printk("aha1740_biosparam\n"));
 513        if (extended && (ip[2] > 1024)) {
 514                ip[0] = 255;
 515                ip[1] = 63;
 516                ip[2] = size / (255 * 63);
 517        } else {
 518                ip[0] = 64;
 519                ip[1] = 32;
 520                ip[2] = size >> 11;
 521        }
 522        return 0;
 523}
 524
 525static int aha1740_eh_abort_handler (struct scsi_cmnd *dummy)
 526{
 527/*
 528 * From Alan Cox :
 529 * The AHA1740 has firmware handled abort/reset handling. The "head in
 530 * sand" kernel code is correct for once 8)
 531 *
 532 * So we define a dummy handler just to keep the kernel SCSI code as
 533 * quiet as possible...
 534 */
 535
 536        return SUCCESS;
 537}
 538
 539static struct scsi_host_template aha1740_template = {
 540        .module           = THIS_MODULE,
 541        .proc_name        = "aha1740",
 542        .show_info        = aha1740_show_info,
 543        .name             = "Adaptec 174x (EISA)",
 544        .queuecommand     = aha1740_queuecommand,
 545        .bios_param       = aha1740_biosparam,
 546        .can_queue        = AHA1740_ECBS,
 547        .this_id          = 7,
 548        .sg_tablesize     = AHA1740_SCATTER,
 549        .eh_abort_handler = aha1740_eh_abort_handler,
 550};
 551
 552static int aha1740_probe (struct device *dev)
 553{
 554        int slotbase, rc;
 555        unsigned int irq_level, irq_type, translation;
 556        struct Scsi_Host *shpnt;
 557        struct aha1740_hostdata *host;
 558        struct eisa_device *edev = to_eisa_device (dev);
 559
 560        DEB(printk("aha1740_probe: \n"));
 561        
 562        slotbase = edev->base_addr + EISA_VENDOR_ID_OFFSET;
 563        if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */
 564                return -EBUSY;
 565        if (!aha1740_test_port(slotbase))
 566                goto err_release_region;
 567        aha1740_getconfig(slotbase,&irq_level,&irq_type,&translation);
 568        if ((inb(G2STAT(slotbase)) &
 569             (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) {
 570                /* If the card isn't ready, hard reset it */
 571                outb(G2CNTRL_HRST, G2CNTRL(slotbase));
 572                outb(0, G2CNTRL(slotbase));
 573        }
 574        printk(KERN_INFO "Configuring slot %d at IO:%x, IRQ %u (%s)\n",
 575               edev->slot, slotbase, irq_level, irq_type ? "edge" : "level");
 576        printk(KERN_INFO "aha174x: Extended translation %sabled.\n",
 577               translation ? "en" : "dis");
 578        shpnt = scsi_host_alloc(&aha1740_template,
 579                              sizeof(struct aha1740_hostdata));
 580        if(shpnt == NULL)
 581                goto err_release_region;
 582
 583        shpnt->base = 0;
 584        shpnt->io_port = slotbase;
 585        shpnt->n_io_port = SLOTSIZE;
 586        shpnt->irq = irq_level;
 587        shpnt->dma_channel = 0xff;
 588        host = HOSTDATA(shpnt);
 589        host->edev = edev;
 590        host->translation = translation;
 591        host->ecb_dma_addr = dma_map_single (&edev->dev, host->ecb,
 592                                             sizeof (host->ecb),
 593                                             DMA_BIDIRECTIONAL);
 594        if (!host->ecb_dma_addr) {
 595                printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n");
 596                goto err_host_put;
 597        }
 598        
 599        DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level));
 600        if (request_irq(irq_level,aha1740_intr_handle,irq_type ? 0 : IRQF_SHARED,
 601                        "aha1740",shpnt)) {
 602                printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n",
 603                       irq_level);
 604                goto err_unmap;
 605        }
 606
 607        eisa_set_drvdata (edev, shpnt);
 608
 609        rc = scsi_add_host (shpnt, dev);
 610        if (rc)
 611                goto err_irq;
 612
 613        scsi_scan_host (shpnt);
 614        return 0;
 615
 616 err_irq:
 617        free_irq(irq_level, shpnt);
 618 err_unmap:
 619        dma_unmap_single (&edev->dev, host->ecb_dma_addr,
 620                          sizeof (host->ecb), DMA_BIDIRECTIONAL);
 621 err_host_put:
 622        scsi_host_put (shpnt);
 623 err_release_region:
 624        release_region(slotbase, SLOTSIZE);
 625
 626        return -ENODEV;
 627}
 628
 629static int aha1740_remove (struct device *dev)
 630{
 631        struct Scsi_Host *shpnt = dev_get_drvdata(dev);
 632        struct aha1740_hostdata *host = HOSTDATA (shpnt);
 633
 634        scsi_remove_host(shpnt);
 635        
 636        free_irq (shpnt->irq, shpnt);
 637        dma_unmap_single (dev, host->ecb_dma_addr,
 638                          sizeof (host->ecb), DMA_BIDIRECTIONAL);
 639        release_region (shpnt->io_port, SLOTSIZE);
 640
 641        scsi_host_put (shpnt);
 642        
 643        return 0;
 644}
 645
 646static struct eisa_device_id aha1740_ids[] = {
 647        { "ADP0000" },          /* 1740  */
 648        { "ADP0001" },          /* 1740A */
 649        { "ADP0002" },          /* 1742A */
 650        { "ADP0400" },          /* 1744  */
 651        { "" }
 652};
 653MODULE_DEVICE_TABLE(eisa, aha1740_ids);
 654
 655static struct eisa_driver aha1740_driver = {
 656        .id_table = aha1740_ids,
 657        .driver   = {
 658                .name    = "aha1740",
 659                .probe   = aha1740_probe,
 660                .remove  = aha1740_remove,
 661        },
 662};
 663
 664static __init int aha1740_init (void)
 665{
 666        return eisa_driver_register (&aha1740_driver);
 667}
 668
 669static __exit void aha1740_exit (void)
 670{
 671        eisa_driver_unregister (&aha1740_driver);
 672}
 673
 674module_init (aha1740_init);
 675module_exit (aha1740_exit);
 676
 677MODULE_LICENSE("GPL");
 678