OSDN Git Service

Linux-2.6.12-rc2
[linux-kernel-docs/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@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                                        struct pt_regs *regs)
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                         if (SCtmp->use_sg) {
276                                 /* We used scatter-gather.
277                                    Do the unmapping dance. */
278                                 dma_unmap_sg (&edev->dev,
279                                               (struct scatterlist *) SCtmp->request_buffer,
280                                               SCtmp->use_sg,
281                                               SCtmp->sc_data_direction);
282                         } else {
283                                 dma_unmap_single (&edev->dev,
284                                                   sgptr->buf_dma_addr,
285                                                   SCtmp->request_bufflen,
286                                                   DMA_BIDIRECTIONAL);
287                         }
288             
289                         /* Free the sg block */
290                         dma_free_coherent (&edev->dev,
291                                            sizeof (struct aha1740_sg),
292                                            SCtmp->host_scribble,
293                                            sgptr->sg_dma_addr);
294             
295                         /* Fetch the sense data, and tuck it away, in
296                            the required slot.  The Adaptec
297                            automatically fetches it, and there is no
298                            guarantee that we will still have it in the
299                            cdb when we come back */
300                         if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR ) {
301                                 memcpy(SCtmp->sense_buffer, ecbptr->sense, 
302                                        sizeof(SCtmp->sense_buffer));
303                                 errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
304                         } else
305                                 errstatus = 0;
306                         DEB(if (errstatus)
307                             printk("aha1740_intr_handle: returning %6x\n",
308                                    errstatus));
309                         SCtmp->result = errstatus;
310                         my_done = ecbptr->done;
311                         memset(ecbptr,0,sizeof(struct ecb)); 
312                         if ( my_done )
313                                 my_done(SCtmp);
314                         break;
315                         
316                 case    G2INTST_HARDFAIL:
317                         printk(KERN_ALERT "aha1740 hardware failure!\n");
318                         panic("aha1740.c");     /* Goodbye */
319                         
320                 case    G2INTST_ASNEVENT:
321                         printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
322                                adapstat,
323                                inb(MBOXIN0(base)),
324                                inb(MBOXIN1(base)),
325                                inb(MBOXIN2(base)),
326                                inb(MBOXIN3(base))); /* Say What? */
327                         /* Host Ready -> Mailbox in complete */
328                         outb(G2CNTRL_HRDY,G2CNTRL(base));
329                         break;
330                         
331                 case    G2INTST_CMDGOOD:
332                         /* set immediate command success flag here: */
333                         break;
334                         
335                 case    G2INTST_CMDERROR:
336                         /* Set immediate command failure flag here: */
337                         break;
338                 }
339                 number_serviced++;
340         }
341
342         spin_unlock_irqrestore(host->host_lock, flags);
343         return IRQ_RETVAL(handled);
344 }
345
346 static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
347 {
348         unchar direction;
349         unchar *cmd = (unchar *) SCpnt->cmnd;
350         unchar target = SCpnt->device->id;
351         struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host);
352         unsigned long flags;
353         void *buff = SCpnt->request_buffer;
354         int bufflen = SCpnt->request_bufflen;
355         dma_addr_t sg_dma;
356         struct aha1740_sg *sgptr;
357         int ecbno;
358         DEB(int i);
359
360         if(*cmd == REQUEST_SENSE) {
361                 SCpnt->result = 0;
362                 done(SCpnt); 
363                 return 0;
364         }
365
366 #ifdef DEBUG
367         if (*cmd == READ_10 || *cmd == WRITE_10)
368                 i = xscsi2int(cmd+2);
369         else if (*cmd == READ_6 || *cmd == WRITE_6)
370                 i = scsi2int(cmd+2);
371         else
372                 i = -1;
373         printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ",
374                target, *cmd, i, bufflen);
375         printk("scsi cmd:");
376         for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
377         printk("\n");
378 #endif
379
380         /* locate an available ecb */
381         spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
382         ecbno = host->last_ecb_used + 1; /* An optimization */
383         if (ecbno >= AHA1740_ECBS)
384                 ecbno = 0;
385         do {
386                 if (!host->ecb[ecbno].cmdw)
387                         break;
388                 ecbno++;
389                 if (ecbno >= AHA1740_ECBS)
390                         ecbno = 0;
391         } while (ecbno != host->last_ecb_used);
392
393         if (host->ecb[ecbno].cmdw)
394                 panic("Unable to find empty ecb for aha1740.\n");
395
396         host->ecb[ecbno].cmdw = AHA1740CMD_INIT; /* SCSI Initiator Command
397                                                     doubles as reserved flag */
398
399         host->last_ecb_used = ecbno;    
400         spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
401
402 #ifdef DEBUG
403         printk("Sending command (%d %x)...", ecbno, done);
404 #endif
405
406         host->ecb[ecbno].cdblen = SCpnt->cmd_len; /* SCSI Command
407                                                    * Descriptor Block
408                                                    * Length */
409
410         direction = 0;
411         if (*cmd == READ_10 || *cmd == READ_6)
412                 direction = 1;
413         else if (*cmd == WRITE_10 || *cmd == WRITE_6)
414                 direction = 0;
415
416         memcpy(host->ecb[ecbno].cdb, cmd, SCpnt->cmd_len);
417
418         SCpnt->host_scribble = dma_alloc_coherent (&host->edev->dev,
419                                                    sizeof (struct aha1740_sg),
420                                                    &sg_dma, GFP_ATOMIC);
421         if(SCpnt->host_scribble == NULL) {
422                 printk(KERN_WARNING "aha1740: out of memory in queuecommand!\n");
423                 return 1;
424         }
425         sgptr = (struct aha1740_sg *) SCpnt->host_scribble;
426         sgptr->sg_dma_addr = sg_dma;
427     
428         if (SCpnt->use_sg) {
429                 struct scatterlist * sgpnt;
430                 struct aha1740_chain * cptr;
431                 int i, count;
432                 DEB(unsigned char * ptr);
433
434                 host->ecb[ecbno].sg = 1;  /* SCSI Initiator Command
435                                            * w/scatter-gather*/
436                 sgpnt = (struct scatterlist *) SCpnt->request_buffer;
437                 cptr = sgptr->sg_chain;
438                 count = dma_map_sg (&host->edev->dev, sgpnt, SCpnt->use_sg,
439                                     SCpnt->sc_data_direction);
440                 for(i=0; i < count; i++) {
441                         cptr[i].datalen = sg_dma_len (sgpnt + i);
442                         cptr[i].dataptr = sg_dma_address (sgpnt + i);
443                 }
444                 host->ecb[ecbno].datalen = count*sizeof(struct aha1740_chain);
445                 host->ecb[ecbno].dataptr = sg_dma;
446 #ifdef DEBUG
447                 printk("cptr %x: ",cptr);
448                 ptr = (unsigned char *) cptr;
449                 for(i=0;i<24;i++) printk("%02x ", ptr[i]);
450 #endif
451         } else {
452                 host->ecb[ecbno].datalen = bufflen;
453                 sgptr->buf_dma_addr =  dma_map_single (&host->edev->dev,
454                                                        buff, bufflen,
455                                                        DMA_BIDIRECTIONAL);
456                 host->ecb[ecbno].dataptr = sgptr->buf_dma_addr;
457         }
458         host->ecb[ecbno].lun = SCpnt->device->lun;
459         host->ecb[ecbno].ses = 1; /* Suppress underrun errors */
460         host->ecb[ecbno].dir = direction;
461         host->ecb[ecbno].ars = 1; /* Yes, get the sense on an error */
462         host->ecb[ecbno].senselen = 12;
463         host->ecb[ecbno].senseptr = ecb_cpu_to_dma (SCpnt->device->host,
464                                                     host->ecb[ecbno].sense);
465         host->ecb[ecbno].statusptr = ecb_cpu_to_dma (SCpnt->device->host,
466                                                      host->ecb[ecbno].status);
467         host->ecb[ecbno].done = done;
468         host->ecb[ecbno].SCpnt = SCpnt;
469 #ifdef DEBUG
470         {
471                 int i;
472                 printk("aha1740_command: sending.. ");
473                 for (i = 0; i < sizeof(host->ecb[ecbno]) - 10; i++)
474                         printk("%02x ", ((unchar *)&host->ecb[ecbno])[i]);
475         }
476         printk("\n");
477 #endif
478         if (done) {
479         /* The Adaptec Spec says the card is so fast that the loops
480            will only be executed once in the code below. Even if this
481            was true with the fastest processors when the spec was
482            written, it doesn't seem to be true with todays fast
483            processors. We print a warning if the code is executed more
484            often than LOOPCNT_WARN. If this happens, it should be
485            investigated. If the count reaches LOOPCNT_MAX, we assume
486            something is broken; since there is no way to return an
487            error (the return value is ignored by the mid-level scsi
488            layer) we have to panic (and maybe that's the best thing we
489            can do then anyhow). */
490
491 #define LOOPCNT_WARN 10         /* excessive mbxout wait -> syslog-msg */
492 #define LOOPCNT_MAX 1000000     /* mbxout deadlock -> panic() after ~ 2 sec. */
493                 int loopcnt;
494                 unsigned int base = SCpnt->device->host->io_port;
495                 DEB(printk("aha1740[%d] critical section\n",ecbno));
496
497                 spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
498                 for (loopcnt = 0; ; loopcnt++) {
499                         if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
500                         if (loopcnt == LOOPCNT_WARN) {
501                                 printk("aha1740[%d]_mbxout wait!\n",ecbno);
502                         }
503                         if (loopcnt == LOOPCNT_MAX)
504                                 panic("aha1740.c: mbxout busy!\n");
505                 }
506                 outl (ecb_cpu_to_dma (SCpnt->device->host, host->ecb + ecbno),
507                       MBOXOUT0(base));
508                 for (loopcnt = 0; ; loopcnt++) {
509                         if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break;
510                         if (loopcnt == LOOPCNT_WARN) {
511                                 printk("aha1740[%d]_attn wait!\n",ecbno);
512                         }
513                         if (loopcnt == LOOPCNT_MAX)
514                                 panic("aha1740.c: attn wait failed!\n");
515                 }
516                 outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
517                 spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
518                 DEB(printk("aha1740[%d] request queued.\n",ecbno));
519         } else
520                 printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
521         return 0;
522 }
523
524 /* Query the board for its irq_level and irq_type.  Nothing else matters
525    in enhanced mode on an EISA bus. */
526
527 static void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
528                               unsigned int *irq_type,
529                               unsigned int *translation)
530 {
531         static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
532
533         *irq_level = intab[inb(INTDEF(base)) & 0x7];
534         *irq_type  = (inb(INTDEF(base)) & 0x8) >> 3;
535         *translation = inb(RESV1(base)) & 0x1;
536         outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
537 }
538
539 static int aha1740_biosparam(struct scsi_device *sdev,
540                              struct block_device *dev,
541                              sector_t capacity, int* ip)
542 {
543         int size = capacity;
544         int extended = HOSTDATA(sdev->host)->translation;
545
546         DEB(printk("aha1740_biosparam\n"));
547         if (extended && (ip[2] > 1024)) {
548                 ip[0] = 255;
549                 ip[1] = 63;
550                 ip[2] = size / (255 * 63);
551         } else {
552                 ip[0] = 64;
553                 ip[1] = 32;
554                 ip[2] = size >> 11;
555         }
556         return 0;
557 }
558
559 static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy)
560 {
561 /*
562  * From Alan Cox :
563  * The AHA1740 has firmware handled abort/reset handling. The "head in
564  * sand" kernel code is correct for once 8)
565  *
566  * So we define a dummy handler just to keep the kernel SCSI code as
567  * quiet as possible...
568  */
569
570         return 0;
571 }
572
573 static Scsi_Host_Template aha1740_template = {
574         .module           = THIS_MODULE,
575         .proc_name        = "aha1740",
576         .proc_info        = aha1740_proc_info,
577         .name             = "Adaptec 174x (EISA)",
578         .queuecommand     = aha1740_queuecommand,
579         .bios_param       = aha1740_biosparam,
580         .can_queue        = AHA1740_ECBS,
581         .this_id          = 7,
582         .sg_tablesize     = AHA1740_SCATTER,
583         .cmd_per_lun      = AHA1740_CMDLUN,
584         .use_clustering   = ENABLE_CLUSTERING,
585         .eh_abort_handler = aha1740_eh_abort_handler,
586 };
587
588 static int aha1740_probe (struct device *dev)
589 {
590         int slotbase;
591         unsigned int irq_level, irq_type, translation;
592         struct Scsi_Host *shpnt;
593         struct aha1740_hostdata *host;
594         struct eisa_device *edev = to_eisa_device (dev);
595
596         DEB(printk("aha1740_probe: \n"));
597         
598         slotbase = edev->base_addr + EISA_VENDOR_ID_OFFSET;
599         if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */
600                 return -EBUSY;
601         if (!aha1740_test_port(slotbase))
602                 goto err_release_region;
603         aha1740_getconfig(slotbase,&irq_level,&irq_type,&translation);
604         if ((inb(G2STAT(slotbase)) &
605              (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) {
606                 /* If the card isn't ready, hard reset it */
607                 outb(G2CNTRL_HRST, G2CNTRL(slotbase));
608                 outb(0, G2CNTRL(slotbase));
609         }
610         printk(KERN_INFO "Configuring slot %d at IO:%x, IRQ %u (%s)\n",
611                edev->slot, slotbase, irq_level, irq_type ? "edge" : "level");
612         printk(KERN_INFO "aha174x: Extended translation %sabled.\n",
613                translation ? "en" : "dis");
614         shpnt = scsi_host_alloc(&aha1740_template,
615                               sizeof(struct aha1740_hostdata));
616         if(shpnt == NULL)
617                 goto err_release_region;
618
619         shpnt->base = 0;
620         shpnt->io_port = slotbase;
621         shpnt->n_io_port = SLOTSIZE;
622         shpnt->irq = irq_level;
623         shpnt->dma_channel = 0xff;
624         host = HOSTDATA(shpnt);
625         host->edev = edev;
626         host->translation = translation;
627         host->ecb_dma_addr = dma_map_single (&edev->dev, host->ecb,
628                                              sizeof (host->ecb),
629                                              DMA_BIDIRECTIONAL);
630         if (!host->ecb_dma_addr) {
631                 printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n");
632                 scsi_unregister (shpnt);
633                 goto err_host_put;
634         }
635         
636         DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level));
637         if (request_irq(irq_level,aha1740_intr_handle,irq_type ? 0 : SA_SHIRQ,
638                         "aha1740",shpnt)) {
639                 printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n",
640                        irq_level);
641                 goto err_unmap;
642         }
643
644         eisa_set_drvdata (edev, shpnt);
645         scsi_add_host (shpnt, dev); /* XXX handle failure */
646         scsi_scan_host (shpnt);
647         return 0;
648
649  err_unmap:
650         dma_unmap_single (&edev->dev, host->ecb_dma_addr,
651                           sizeof (host->ecb), DMA_BIDIRECTIONAL);
652  err_host_put:
653         scsi_host_put (shpnt);
654  err_release_region:
655         release_region(slotbase, SLOTSIZE);
656
657         return -ENODEV;
658 }
659
660 static __devexit int aha1740_remove (struct device *dev)
661 {
662         struct Scsi_Host *shpnt = dev->driver_data;
663         struct aha1740_hostdata *host = HOSTDATA (shpnt);
664
665         scsi_remove_host(shpnt);
666         
667         free_irq (shpnt->irq, shpnt);
668         dma_unmap_single (dev, host->ecb_dma_addr,
669                           sizeof (host->ecb), DMA_BIDIRECTIONAL);
670         release_region (shpnt->io_port, SLOTSIZE);
671
672         scsi_host_put (shpnt);
673         
674         return 0;
675 }
676
677 static struct eisa_device_id aha1740_ids[] = {
678         { "ADP0000" },          /* 1740  */
679         { "ADP0001" },          /* 1740A */
680         { "ADP0002" },          /* 1742A */
681         { "ADP0400" },          /* 1744  */
682         { "" }
683 };
684
685 static struct eisa_driver aha1740_driver = {
686         .id_table = aha1740_ids,
687         .driver   = {
688                 .name    = "aha1740",
689                 .probe   = aha1740_probe,
690                 .remove  = __devexit_p (aha1740_remove),
691         },
692 };
693
694 static __init int aha1740_init (void)
695 {
696         return eisa_driver_register (&aha1740_driver);
697 }
698
699 static __exit void aha1740_exit (void)
700 {
701         eisa_driver_unregister (&aha1740_driver);
702 }
703
704 module_init (aha1740_init);
705 module_exit (aha1740_exit);
706
707 MODULE_LICENSE("GPL");