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