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