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