Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / 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(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 todays 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 /* Query the board for its irq_level and irq_type.  Nothing else matters
507    in enhanced mode on an EISA bus. */
508
509 static void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
510                               unsigned int *irq_type,
511                               unsigned int *translation)
512 {
513         static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
514
515         *irq_level = intab[inb(INTDEF(base)) & 0x7];
516         *irq_type  = (inb(INTDEF(base)) & 0x8) >> 3;
517         *translation = inb(RESV1(base)) & 0x1;
518         outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
519 }
520
521 static int aha1740_biosparam(struct scsi_device *sdev,
522                              struct block_device *dev,
523                              sector_t capacity, int* ip)
524 {
525         int size = capacity;
526         int extended = HOSTDATA(sdev->host)->translation;
527
528         DEB(printk("aha1740_biosparam\n"));
529         if (extended && (ip[2] > 1024)) {
530                 ip[0] = 255;
531                 ip[1] = 63;
532                 ip[2] = size / (255 * 63);
533         } else {
534                 ip[0] = 64;
535                 ip[1] = 32;
536                 ip[2] = size >> 11;
537         }
538         return 0;
539 }
540
541 static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy)
542 {
543 /*
544  * From Alan Cox :
545  * The AHA1740 has firmware handled abort/reset handling. The "head in
546  * sand" kernel code is correct for once 8)
547  *
548  * So we define a dummy handler just to keep the kernel SCSI code as
549  * quiet as possible...
550  */
551
552         return 0;
553 }
554
555 static struct scsi_host_template aha1740_template = {
556         .module           = THIS_MODULE,
557         .proc_name        = "aha1740",
558         .proc_info        = aha1740_proc_info,
559         .name             = "Adaptec 174x (EISA)",
560         .queuecommand     = aha1740_queuecommand,
561         .bios_param       = aha1740_biosparam,
562         .can_queue        = AHA1740_ECBS,
563         .this_id          = 7,
564         .sg_tablesize     = AHA1740_SCATTER,
565         .cmd_per_lun      = AHA1740_CMDLUN,
566         .use_clustering   = ENABLE_CLUSTERING,
567         .eh_abort_handler = aha1740_eh_abort_handler,
568 };
569
570 static int aha1740_probe (struct device *dev)
571 {
572         int slotbase, rc;
573         unsigned int irq_level, irq_type, translation;
574         struct Scsi_Host *shpnt;
575         struct aha1740_hostdata *host;
576         struct eisa_device *edev = to_eisa_device (dev);
577
578         DEB(printk("aha1740_probe: \n"));
579         
580         slotbase = edev->base_addr + EISA_VENDOR_ID_OFFSET;
581         if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */
582                 return -EBUSY;
583         if (!aha1740_test_port(slotbase))
584                 goto err_release_region;
585         aha1740_getconfig(slotbase,&irq_level,&irq_type,&translation);
586         if ((inb(G2STAT(slotbase)) &
587              (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) {
588                 /* If the card isn't ready, hard reset it */
589                 outb(G2CNTRL_HRST, G2CNTRL(slotbase));
590                 outb(0, G2CNTRL(slotbase));
591         }
592         printk(KERN_INFO "Configuring slot %d at IO:%x, IRQ %u (%s)\n",
593                edev->slot, slotbase, irq_level, irq_type ? "edge" : "level");
594         printk(KERN_INFO "aha174x: Extended translation %sabled.\n",
595                translation ? "en" : "dis");
596         shpnt = scsi_host_alloc(&aha1740_template,
597                               sizeof(struct aha1740_hostdata));
598         if(shpnt == NULL)
599                 goto err_release_region;
600
601         shpnt->base = 0;
602         shpnt->io_port = slotbase;
603         shpnt->n_io_port = SLOTSIZE;
604         shpnt->irq = irq_level;
605         shpnt->dma_channel = 0xff;
606         host = HOSTDATA(shpnt);
607         host->edev = edev;
608         host->translation = translation;
609         host->ecb_dma_addr = dma_map_single (&edev->dev, host->ecb,
610                                              sizeof (host->ecb),
611                                              DMA_BIDIRECTIONAL);
612         if (!host->ecb_dma_addr) {
613                 printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n");
614                 scsi_unregister (shpnt);
615                 goto err_host_put;
616         }
617         
618         DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level));
619         if (request_irq(irq_level,aha1740_intr_handle,irq_type ? 0 : IRQF_SHARED,
620                         "aha1740",shpnt)) {
621                 printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n",
622                        irq_level);
623                 goto err_unmap;
624         }
625
626         eisa_set_drvdata (edev, shpnt);
627
628         rc = scsi_add_host (shpnt, dev);
629         if (rc)
630                 goto err_irq;
631
632         scsi_scan_host (shpnt);
633         return 0;
634
635  err_irq:
636         free_irq(irq_level, shpnt);
637  err_unmap:
638         dma_unmap_single (&edev->dev, host->ecb_dma_addr,
639                           sizeof (host->ecb), DMA_BIDIRECTIONAL);
640  err_host_put:
641         scsi_host_put (shpnt);
642  err_release_region:
643         release_region(slotbase, SLOTSIZE);
644
645         return -ENODEV;
646 }
647
648 static __devexit int aha1740_remove (struct device *dev)
649 {
650         struct Scsi_Host *shpnt = dev_get_drvdata(dev);
651         struct aha1740_hostdata *host = HOSTDATA (shpnt);
652
653         scsi_remove_host(shpnt);
654         
655         free_irq (shpnt->irq, shpnt);
656         dma_unmap_single (dev, host->ecb_dma_addr,
657                           sizeof (host->ecb), DMA_BIDIRECTIONAL);
658         release_region (shpnt->io_port, SLOTSIZE);
659
660         scsi_host_put (shpnt);
661         
662         return 0;
663 }
664
665 static struct eisa_device_id aha1740_ids[] = {
666         { "ADP0000" },          /* 1740  */
667         { "ADP0001" },          /* 1740A */
668         { "ADP0002" },          /* 1742A */
669         { "ADP0400" },          /* 1744  */
670         { "" }
671 };
672 MODULE_DEVICE_TABLE(eisa, aha1740_ids);
673
674 static struct eisa_driver aha1740_driver = {
675         .id_table = aha1740_ids,
676         .driver   = {
677                 .name    = "aha1740",
678                 .probe   = aha1740_probe,
679                 .remove  = __devexit_p (aha1740_remove),
680         },
681 };
682
683 static __init int aha1740_init (void)
684 {
685         return eisa_driver_register (&aha1740_driver);
686 }
687
688 static __exit void aha1740_exit (void)
689 {
690         eisa_driver_unregister (&aha1740_driver);
691 }
692
693 module_init (aha1740_init);
694 module_exit (aha1740_exit);
695
696 MODULE_LICENSE("GPL");