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