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