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