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