Back to home page

OSCL-LXR

 
 

    


0001 /*  $Id$
0002  *  1993/03/31
0003  *  linux/kernel/aha1740.c
0004  *
0005  *  Based loosely on aha1542.c which is
0006  *  Copyright (C) 1992  Tommy Thorn and
0007  *  Modified by Eric Youngdale
0008  *
0009  *  This file is aha1740.c, written and
0010  *  Copyright (C) 1992,1993  Brad McLean
0011  *  brad@saturn.gaylord.com or brad@bradpc.gaylord.com.
0012  *  
0013  *  Modifications to makecode and queuecommand
0014  *  for proper handling of multiple devices courteously
0015  *  provided by Michael Weller, March, 1993
0016  *
0017  *  Multiple adapter support, extended translation detection,
0018  *  update to current scsi subsystem changes, proc fs support,
0019  *  working (!) module support based on patches from Andreas Arens,
0020  *  by Andreas Degert <ad@papyrus.hamburg.com>, 2/1997
0021  *
0022  * aha1740_makecode may still need even more work
0023  * if it doesn't work for your devices, take a look.
0024  *
0025  * Reworked for new_eh and new locking by Alan Cox <alan@lxorguk.ukuu.org.uk>
0026  *
0027  * Converted to EISA and generic DMA APIs by Marc Zyngier
0028  * <maz@wild-wind.fr.eu.org>, 4/2003.
0029  *
0030  * Shared interrupt support added by Rask Ingemann Lambertsen
0031  * <rask@sygehus.dk>, 10/2003
0032  *
0033  * For the avoidance of doubt the "preferred form" of this code is one which
0034  * is in an open non patent encumbered format. Where cryptographic key signing
0035  * forms part of the process of creating an executable the information
0036  * including keys needed to generate an equivalently functional executable
0037  * are deemed to be part of the source code.
0038  */
0039 
0040 #include <linux/blkdev.h>
0041 #include <linux/interrupt.h>
0042 #include <linux/module.h>
0043 #include <linux/kernel.h>
0044 #include <linux/types.h>
0045 #include <linux/string.h>
0046 #include <linux/ioport.h>
0047 #include <linux/proc_fs.h>
0048 #include <linux/stat.h>
0049 #include <linux/init.h>
0050 #include <linux/device.h>
0051 #include <linux/eisa.h>
0052 #include <linux/dma-mapping.h>
0053 #include <linux/gfp.h>
0054 
0055 #include <asm/dma.h>
0056 #include <asm/io.h>
0057 
0058 #include <scsi/scsi.h>
0059 #include <scsi/scsi_cmnd.h>
0060 #include <scsi/scsi_device.h>
0061 #include <scsi/scsi_eh.h>
0062 #include <scsi/scsi_host.h>
0063 #include <scsi/scsi_tcq.h>
0064 #include "aha1740.h"
0065 
0066 /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
0067    IT WORK, THEN:
0068 #define DEBUG
0069 */
0070 #ifdef DEBUG
0071 #define DEB(x) x
0072 #else
0073 #define DEB(x)
0074 #endif
0075 
0076 struct aha1740_hostdata {
0077     struct eisa_device *edev;
0078     unsigned int translation;
0079     unsigned int last_ecb_used;
0080     dma_addr_t ecb_dma_addr;
0081     struct ecb ecb[AHA1740_ECBS];
0082 };
0083 
0084 struct aha1740_sg {
0085     struct aha1740_chain sg_chain[AHA1740_SCATTER];
0086     dma_addr_t sg_dma_addr;
0087     dma_addr_t buf_dma_addr;
0088 };
0089 
0090 #define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata)
0091 
0092 static inline struct ecb *ecb_dma_to_cpu (struct Scsi_Host *host,
0093                       dma_addr_t dma)
0094 {
0095     struct aha1740_hostdata *hdata = HOSTDATA (host);
0096     dma_addr_t offset;
0097 
0098     offset = dma - hdata->ecb_dma_addr;
0099 
0100     return (struct ecb *)(((char *) hdata->ecb) + (unsigned int) offset);
0101 }
0102 
0103 static inline dma_addr_t ecb_cpu_to_dma (struct Scsi_Host *host, void *cpu)
0104 {
0105     struct aha1740_hostdata *hdata = HOSTDATA (host);
0106     dma_addr_t offset;
0107     
0108     offset = (char *) cpu - (char *) hdata->ecb;
0109 
0110     return hdata->ecb_dma_addr + offset;
0111 }
0112 
0113 static int aha1740_show_info(struct seq_file *m, struct Scsi_Host *shpnt)
0114 {
0115     struct aha1740_hostdata *host = HOSTDATA(shpnt);
0116     seq_printf(m, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n"
0117               "Extended translation %sabled.\n",
0118               shpnt->io_port, shpnt->irq, host->edev->slot,
0119               host->translation ? "en" : "dis");
0120     return 0;
0121 }
0122 
0123 static int aha1740_makecode(unchar *sense, unchar *status)
0124 {
0125     struct statusword
0126     {
0127         ushort  don:1,  /* Command Done - No Error */
0128             du:1,   /* Data underrun */
0129             :1, qf:1,   /* Queue full */
0130                 sc:1,   /* Specification Check */
0131                 dor:1,  /* Data overrun */
0132                 ch:1,   /* Chaining Halted */
0133                 intr:1, /* Interrupt issued */
0134                 asa:1,  /* Additional Status Available */
0135                 sns:1,  /* Sense information Stored */
0136             :1, ini:1,  /* Initialization Required */
0137             me:1,   /* Major error or exception */
0138             :1, eca:1,  /* Extended Contingent alliance */
0139             :1;
0140     } status_word;
0141     int retval = DID_OK;
0142 
0143     status_word = * (struct statusword *) status;
0144 #ifdef DEBUG
0145     printk("makecode from %x,%x,%x,%x %x,%x,%x,%x",
0146            status[0], status[1], status[2], status[3],
0147            sense[0], sense[1], sense[2], sense[3]);
0148 #endif
0149     if (!status_word.don) { /* Anything abnormal was detected */
0150         if ( (status[1]&0x18) || status_word.sc ) {
0151             /*Additional info available*/
0152             /* Use the supplied info for further diagnostics */
0153             switch ( status[2] ) {
0154             case 0x12:
0155                 if ( status_word.dor )
0156                     retval=DID_ERROR; /* It's an Overrun */
0157                 /* If not overrun, assume underrun and
0158                  * ignore it! */
0159                 break;
0160             case 0x00: /* No info, assume no error, should
0161                     * not occur */
0162                 break;
0163             case 0x11:
0164             case 0x21:
0165                 retval=DID_TIME_OUT;
0166                 break;
0167             case 0x0a:
0168                 retval=DID_BAD_TARGET;
0169                 break;
0170             case 0x04:
0171             case 0x05:
0172                 retval=DID_ABORT;
0173                 /* Either by this driver or the
0174                  * AHA1740 itself */
0175                 break;
0176             default:
0177                 retval=DID_ERROR; /* No further
0178                            * diagnostics
0179                            * possible */
0180             }
0181         } else {
0182             /* Michael suggests, and Brad concurs: */
0183             if ( status_word.qf ) {
0184                 retval = DID_TIME_OUT; /* forces a redo */
0185                 /* I think this specific one should
0186                  * not happen -Brad */
0187                 printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
0188             } else
0189                 if ( status[0]&0x60 ) {
0190                      /* Didn't find a better error */
0191                     retval = DID_ERROR;
0192                 }
0193             /* In any other case return DID_OK so for example
0194                CONDITION_CHECKS make it through to the appropriate
0195                device driver */
0196         }
0197     }
0198     /* Under all circumstances supply the target status -Michael */
0199     return status[3] | retval << 16;
0200 }
0201 
0202 static int aha1740_test_port(unsigned int base)
0203 {
0204     if ( inb(PORTADR(base)) & PORTADDR_ENH )
0205         return 1;   /* Okay, we're all set */
0206     
0207     printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n");
0208     return 0;
0209 }
0210 
0211 /* A "high" level interrupt handler */
0212 static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
0213 {
0214     struct Scsi_Host *host = (struct Scsi_Host *) dev_id;
0215         void (*my_done)(struct scsi_cmnd *);
0216     int errstatus, adapstat;
0217     int number_serviced;
0218     struct ecb *ecbptr;
0219     struct scsi_cmnd *SCtmp;
0220     unsigned int base;
0221     unsigned long flags;
0222     int handled = 0;
0223     struct aha1740_sg *sgptr;
0224     struct eisa_device *edev;
0225     
0226     if (!host)
0227         panic("aha1740.c: Irq from unknown host!\n");
0228     spin_lock_irqsave(host->host_lock, flags);
0229     base = host->io_port;
0230     number_serviced = 0;
0231     edev = HOSTDATA(host)->edev;
0232 
0233     while(inb(G2STAT(base)) & G2STAT_INTPEND) {
0234         handled = 1;
0235         DEB(printk("aha1740_intr top of loop.\n"));
0236         adapstat = inb(G2INTST(base));
0237         ecbptr = ecb_dma_to_cpu (host, inl(MBOXIN0(base)));
0238         outb(G2CNTRL_IRST,G2CNTRL(base)); /* interrupt reset */
0239       
0240         switch ( adapstat & G2INTST_MASK ) {
0241         case    G2INTST_CCBRETRY:
0242         case    G2INTST_CCBERROR:
0243         case    G2INTST_CCBGOOD:
0244             /* Host Ready -> Mailbox in complete */
0245             outb(G2CNTRL_HRDY,G2CNTRL(base));
0246             if (!ecbptr) {
0247                 printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
0248                        inb(G2STAT(base)),adapstat,
0249                        inb(G2INTST(base)), number_serviced++);
0250                 continue;
0251             }
0252             SCtmp = ecbptr->SCpnt;
0253             if (!SCtmp) {
0254                 printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
0255                        inb(G2STAT(base)),adapstat,
0256                        inb(G2INTST(base)), number_serviced++);
0257                 continue;
0258             }
0259             sgptr = (struct aha1740_sg *) SCtmp->host_scribble;
0260             scsi_dma_unmap(SCtmp);
0261 
0262             /* Free the sg block */
0263             dma_free_coherent (&edev->dev,
0264                        sizeof (struct aha1740_sg),
0265                        SCtmp->host_scribble,
0266                        sgptr->sg_dma_addr);
0267         
0268             /* Fetch the sense data, and tuck it away, in
0269                the required slot.  The Adaptec
0270                automatically fetches it, and there is no
0271                guarantee that we will still have it in the
0272                cdb when we come back */
0273             if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR ) {
0274                 memcpy_and_pad(SCtmp->sense_buffer,
0275                            SCSI_SENSE_BUFFERSIZE,
0276                            ecbptr->sense,
0277                            sizeof(ecbptr->sense),
0278                            0);
0279                 errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
0280             } else
0281                 errstatus = 0;
0282             DEB(if (errstatus)
0283                 printk("aha1740_intr_handle: returning %6x\n",
0284                    errstatus));
0285             SCtmp->result = errstatus;
0286             my_done = ecbptr->done;
0287             memset(ecbptr,0,sizeof(struct ecb)); 
0288             if ( my_done )
0289                 my_done(SCtmp);
0290             break;
0291             
0292         case    G2INTST_HARDFAIL:
0293             printk(KERN_ALERT "aha1740 hardware failure!\n");
0294             panic("aha1740.c"); /* Goodbye */
0295             
0296         case    G2INTST_ASNEVENT:
0297             printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
0298                    adapstat,
0299                    inb(MBOXIN0(base)),
0300                    inb(MBOXIN1(base)),
0301                    inb(MBOXIN2(base)),
0302                    inb(MBOXIN3(base))); /* Say What? */
0303             /* Host Ready -> Mailbox in complete */
0304             outb(G2CNTRL_HRDY,G2CNTRL(base));
0305             break;
0306             
0307         case    G2INTST_CMDGOOD:
0308             /* set immediate command success flag here: */
0309             break;
0310             
0311         case    G2INTST_CMDERROR:
0312             /* Set immediate command failure flag here: */
0313             break;
0314         }
0315         number_serviced++;
0316     }
0317 
0318     spin_unlock_irqrestore(host->host_lock, flags);
0319     return IRQ_RETVAL(handled);
0320 }
0321 
0322 static int aha1740_queuecommand_lck(struct scsi_cmnd *SCpnt)
0323 {
0324     void (*done)(struct scsi_cmnd *) = scsi_done;
0325     unchar direction;
0326     unchar *cmd = (unchar *) SCpnt->cmnd;
0327     unchar target = scmd_id(SCpnt);
0328     struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host);
0329     unsigned long flags;
0330     dma_addr_t sg_dma;
0331     struct aha1740_sg *sgptr;
0332     int ecbno, nseg;
0333     DEB(int i);
0334 
0335     if(*cmd == REQUEST_SENSE) {
0336         SCpnt->result = 0;
0337         done(SCpnt); 
0338         return 0;
0339     }
0340 
0341 #ifdef DEBUG
0342     if (*cmd == READ_10 || *cmd == WRITE_10)
0343         i = xscsi2int(cmd+2);
0344     else if (*cmd == READ_6 || *cmd == WRITE_6)
0345         i = scsi2int(cmd+2);
0346     else
0347         i = -1;
0348     printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ",
0349            target, *cmd, i, bufflen);
0350     printk("scsi cmd:");
0351     for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
0352     printk("\n");
0353 #endif
0354 
0355     /* locate an available ecb */
0356     spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
0357     ecbno = host->last_ecb_used + 1; /* An optimization */
0358     if (ecbno >= AHA1740_ECBS)
0359         ecbno = 0;
0360     do {
0361         if (!host->ecb[ecbno].cmdw)
0362             break;
0363         ecbno++;
0364         if (ecbno >= AHA1740_ECBS)
0365             ecbno = 0;
0366     } while (ecbno != host->last_ecb_used);
0367 
0368     if (host->ecb[ecbno].cmdw)
0369         panic("Unable to find empty ecb for aha1740.\n");
0370 
0371     host->ecb[ecbno].cmdw = AHA1740CMD_INIT; /* SCSI Initiator Command
0372                             doubles as reserved flag */
0373 
0374     host->last_ecb_used = ecbno;    
0375     spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
0376 
0377 #ifdef DEBUG
0378     printk("Sending command (%d %x)...", ecbno, done);
0379 #endif
0380 
0381     host->ecb[ecbno].cdblen = SCpnt->cmd_len; /* SCSI Command
0382                            * Descriptor Block
0383                            * Length */
0384 
0385     direction = 0;
0386     if (*cmd == READ_10 || *cmd == READ_6)
0387         direction = 1;
0388     else if (*cmd == WRITE_10 || *cmd == WRITE_6)
0389         direction = 0;
0390 
0391     memcpy(host->ecb[ecbno].cdb, cmd, SCpnt->cmd_len);
0392 
0393     SCpnt->host_scribble = dma_alloc_coherent (&host->edev->dev,
0394                            sizeof (struct aha1740_sg),
0395                            &sg_dma, GFP_ATOMIC);
0396     if(SCpnt->host_scribble == NULL) {
0397         printk(KERN_WARNING "aha1740: out of memory in queuecommand!\n");
0398         return 1;
0399     }
0400     sgptr = (struct aha1740_sg *) SCpnt->host_scribble;
0401     sgptr->sg_dma_addr = sg_dma;
0402 
0403     nseg = scsi_dma_map(SCpnt);
0404     BUG_ON(nseg < 0);
0405     if (nseg) {
0406         struct scatterlist *sg;
0407         struct aha1740_chain * cptr;
0408         int i;
0409         DEB(unsigned char * ptr);
0410 
0411         host->ecb[ecbno].sg = 1;  /* SCSI Initiator Command
0412                        * w/scatter-gather*/
0413         cptr = sgptr->sg_chain;
0414         scsi_for_each_sg(SCpnt, sg, nseg, i) {
0415             cptr[i].datalen = sg_dma_len (sg);
0416             cptr[i].dataptr = sg_dma_address (sg);
0417         }
0418         host->ecb[ecbno].datalen = nseg * sizeof(struct aha1740_chain);
0419         host->ecb[ecbno].dataptr = sg_dma;
0420 #ifdef DEBUG
0421         printk("cptr %x: ",cptr);
0422         ptr = (unsigned char *) cptr;
0423         for(i=0;i<24;i++) printk("%02x ", ptr[i]);
0424 #endif
0425     } else {
0426         host->ecb[ecbno].datalen = 0;
0427         host->ecb[ecbno].dataptr = 0;
0428     }
0429     host->ecb[ecbno].lun = SCpnt->device->lun;
0430     host->ecb[ecbno].ses = 1; /* Suppress underrun errors */
0431     host->ecb[ecbno].dir = direction;
0432     host->ecb[ecbno].ars = 1; /* Yes, get the sense on an error */
0433     host->ecb[ecbno].senselen = 12;
0434     host->ecb[ecbno].senseptr = ecb_cpu_to_dma (SCpnt->device->host,
0435                             host->ecb[ecbno].sense);
0436     host->ecb[ecbno].statusptr = ecb_cpu_to_dma (SCpnt->device->host,
0437                              host->ecb[ecbno].status);
0438     host->ecb[ecbno].done = done;
0439     host->ecb[ecbno].SCpnt = SCpnt;
0440 #ifdef DEBUG
0441     {
0442         int i;
0443         printk("aha1740_command: sending.. ");
0444         for (i = 0; i < sizeof(host->ecb[ecbno]) - 10; i++)
0445             printk("%02x ", ((unchar *)&host->ecb[ecbno])[i]);
0446     }
0447     printk("\n");
0448 #endif
0449     if (done) {
0450     /* The Adaptec Spec says the card is so fast that the loops
0451            will only be executed once in the code below. Even if this
0452            was true with the fastest processors when the spec was
0453            written, it doesn't seem to be true with today's fast
0454            processors. We print a warning if the code is executed more
0455            often than LOOPCNT_WARN. If this happens, it should be
0456            investigated. If the count reaches LOOPCNT_MAX, we assume
0457            something is broken; since there is no way to return an
0458            error (the return value is ignored by the mid-level scsi
0459            layer) we have to panic (and maybe that's the best thing we
0460            can do then anyhow). */
0461 
0462 #define LOOPCNT_WARN 10     /* excessive mbxout wait -> syslog-msg */
0463 #define LOOPCNT_MAX 1000000 /* mbxout deadlock -> panic() after ~ 2 sec. */
0464         int loopcnt;
0465         unsigned int base = SCpnt->device->host->io_port;
0466         DEB(printk("aha1740[%d] critical section\n",ecbno));
0467 
0468         spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
0469         for (loopcnt = 0; ; loopcnt++) {
0470             if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
0471             if (loopcnt == LOOPCNT_WARN) {
0472                 printk("aha1740[%d]_mbxout wait!\n",ecbno);
0473             }
0474             if (loopcnt == LOOPCNT_MAX)
0475                 panic("aha1740.c: mbxout busy!\n");
0476         }
0477         outl (ecb_cpu_to_dma (SCpnt->device->host, host->ecb + ecbno),
0478               MBOXOUT0(base));
0479         for (loopcnt = 0; ; loopcnt++) {
0480             if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break;
0481             if (loopcnt == LOOPCNT_WARN) {
0482                 printk("aha1740[%d]_attn wait!\n",ecbno);
0483             }
0484             if (loopcnt == LOOPCNT_MAX)
0485                 panic("aha1740.c: attn wait failed!\n");
0486         }
0487         outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
0488         spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
0489         DEB(printk("aha1740[%d] request queued.\n",ecbno));
0490     } else
0491         printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
0492     return 0;
0493 }
0494 
0495 static DEF_SCSI_QCMD(aha1740_queuecommand)
0496 
0497 /* Query the board for its irq_level and irq_type.  Nothing else matters
0498    in enhanced mode on an EISA bus. */
0499 
0500 static void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
0501                   unsigned int *irq_type,
0502                   unsigned int *translation)
0503 {
0504     static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
0505 
0506     *irq_level = intab[inb(INTDEF(base)) & 0x7];
0507     *irq_type  = (inb(INTDEF(base)) & 0x8) >> 3;
0508     *translation = inb(RESV1(base)) & 0x1;
0509     outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
0510 }
0511 
0512 static int aha1740_biosparam(struct scsi_device *sdev,
0513                  struct block_device *dev,
0514                  sector_t capacity, int* ip)
0515 {
0516     int size = capacity;
0517     int extended = HOSTDATA(sdev->host)->translation;
0518 
0519     DEB(printk("aha1740_biosparam\n"));
0520     if (extended && (ip[2] > 1024)) {
0521         ip[0] = 255;
0522         ip[1] = 63;
0523         ip[2] = size / (255 * 63);
0524     } else {
0525         ip[0] = 64;
0526         ip[1] = 32;
0527         ip[2] = size >> 11;
0528     }
0529     return 0;
0530 }
0531 
0532 static int aha1740_eh_abort_handler (struct scsi_cmnd *dummy)
0533 {
0534 /*
0535  * From Alan Cox :
0536  * The AHA1740 has firmware handled abort/reset handling. The "head in
0537  * sand" kernel code is correct for once 8)
0538  *
0539  * So we define a dummy handler just to keep the kernel SCSI code as
0540  * quiet as possible...
0541  */
0542 
0543     return SUCCESS;
0544 }
0545 
0546 static struct scsi_host_template aha1740_template = {
0547     .module           = THIS_MODULE,
0548     .proc_name        = "aha1740",
0549     .show_info        = aha1740_show_info,
0550     .name             = "Adaptec 174x (EISA)",
0551     .queuecommand     = aha1740_queuecommand,
0552     .bios_param       = aha1740_biosparam,
0553     .can_queue        = AHA1740_ECBS,
0554     .this_id          = 7,
0555     .sg_tablesize     = AHA1740_SCATTER,
0556     .eh_abort_handler = aha1740_eh_abort_handler,
0557 };
0558 
0559 static int aha1740_probe (struct device *dev)
0560 {
0561     int slotbase, rc;
0562     unsigned int irq_level, irq_type, translation;
0563     struct Scsi_Host *shpnt;
0564     struct aha1740_hostdata *host;
0565     struct eisa_device *edev = to_eisa_device (dev);
0566 
0567     DEB(printk("aha1740_probe: \n"));
0568     
0569     slotbase = edev->base_addr + EISA_VENDOR_ID_OFFSET;
0570     if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */
0571         return -EBUSY;
0572     if (!aha1740_test_port(slotbase))
0573         goto err_release_region;
0574     aha1740_getconfig(slotbase,&irq_level,&irq_type,&translation);
0575     if ((inb(G2STAT(slotbase)) &
0576          (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) {
0577         /* If the card isn't ready, hard reset it */
0578         outb(G2CNTRL_HRST, G2CNTRL(slotbase));
0579         outb(0, G2CNTRL(slotbase));
0580     }
0581     printk(KERN_INFO "Configuring slot %d at IO:%x, IRQ %u (%s)\n",
0582            edev->slot, slotbase, irq_level, irq_type ? "edge" : "level");
0583     printk(KERN_INFO "aha174x: Extended translation %sabled.\n",
0584            translation ? "en" : "dis");
0585     shpnt = scsi_host_alloc(&aha1740_template,
0586                   sizeof(struct aha1740_hostdata));
0587     if(shpnt == NULL)
0588         goto err_release_region;
0589 
0590     shpnt->base = 0;
0591     shpnt->io_port = slotbase;
0592     shpnt->n_io_port = SLOTSIZE;
0593     shpnt->irq = irq_level;
0594     shpnt->dma_channel = 0xff;
0595     host = HOSTDATA(shpnt);
0596     host->edev = edev;
0597     host->translation = translation;
0598     host->ecb_dma_addr = dma_map_single (&edev->dev, host->ecb,
0599                          sizeof (host->ecb),
0600                          DMA_BIDIRECTIONAL);
0601     if (!host->ecb_dma_addr) {
0602         printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n");
0603         goto err_host_put;
0604     }
0605     
0606     DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level));
0607     if (request_irq(irq_level,aha1740_intr_handle,irq_type ? 0 : IRQF_SHARED,
0608             "aha1740",shpnt)) {
0609         printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n",
0610                irq_level);
0611         goto err_unmap;
0612     }
0613 
0614     eisa_set_drvdata (edev, shpnt);
0615 
0616     rc = scsi_add_host (shpnt, dev);
0617     if (rc)
0618         goto err_irq;
0619 
0620     scsi_scan_host (shpnt);
0621     return 0;
0622 
0623  err_irq:
0624     free_irq(irq_level, shpnt);
0625  err_unmap:
0626     dma_unmap_single (&edev->dev, host->ecb_dma_addr,
0627               sizeof (host->ecb), DMA_BIDIRECTIONAL);
0628  err_host_put:
0629     scsi_host_put (shpnt);
0630  err_release_region:
0631     release_region(slotbase, SLOTSIZE);
0632 
0633     return -ENODEV;
0634 }
0635 
0636 static int aha1740_remove (struct device *dev)
0637 {
0638     struct Scsi_Host *shpnt = dev_get_drvdata(dev);
0639     struct aha1740_hostdata *host = HOSTDATA (shpnt);
0640 
0641     scsi_remove_host(shpnt);
0642     
0643     free_irq (shpnt->irq, shpnt);
0644     dma_unmap_single (dev, host->ecb_dma_addr,
0645               sizeof (host->ecb), DMA_BIDIRECTIONAL);
0646     release_region (shpnt->io_port, SLOTSIZE);
0647 
0648     scsi_host_put (shpnt);
0649     
0650     return 0;
0651 }
0652 
0653 static struct eisa_device_id aha1740_ids[] = {
0654     { "ADP0000" },      /* 1740  */
0655     { "ADP0001" },      /* 1740A */
0656     { "ADP0002" },      /* 1742A */
0657     { "ADP0400" },      /* 1744  */
0658     { "" }
0659 };
0660 MODULE_DEVICE_TABLE(eisa, aha1740_ids);
0661 
0662 static struct eisa_driver aha1740_driver = {
0663     .id_table = aha1740_ids,
0664     .driver   = {
0665         .name    = "aha1740",
0666         .probe   = aha1740_probe,
0667         .remove  = aha1740_remove,
0668     },
0669 };
0670 
0671 static __init int aha1740_init (void)
0672 {
0673     return eisa_driver_register (&aha1740_driver);
0674 }
0675 
0676 static __exit void aha1740_exit (void)
0677 {
0678     eisa_driver_unregister (&aha1740_driver);
0679 }
0680 
0681 module_init (aha1740_init);
0682 module_exit (aha1740_exit);
0683 
0684 MODULE_LICENSE("GPL");