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_proc_info(struct Scsi_Host * shpnt,char * buffer,char ** start,off_t offset,int length,int inout)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 
aha1740_makecode(unchar * sense,unchar * status)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 
aha1740_test_port(unsigned int base)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 */
aha1740_intr_handle(int irq,void * dev_id)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 
aha1740_queuecommand_lck(Scsi_Cmnd * SCpnt,void (* done)(Scsi_Cmnd *))333 static int aha1740_queuecommand_lck(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 today's 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 
DEF_SCSI_QCMD(aha1740_queuecommand)505 static DEF_SCSI_QCMD(aha1740_queuecommand)
506 
507 /* Query the board for its irq_level and irq_type.  Nothing else matters
508    in enhanced mode on an EISA bus. */
509 
510 static void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
511 			      unsigned int *irq_type,
512 			      unsigned int *translation)
513 {
514 	static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
515 
516 	*irq_level = intab[inb(INTDEF(base)) & 0x7];
517 	*irq_type  = (inb(INTDEF(base)) & 0x8) >> 3;
518 	*translation = inb(RESV1(base)) & 0x1;
519 	outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
520 }
521 
aha1740_biosparam(struct scsi_device * sdev,struct block_device * dev,sector_t capacity,int * ip)522 static int aha1740_biosparam(struct scsi_device *sdev,
523 			     struct block_device *dev,
524 			     sector_t capacity, int* ip)
525 {
526 	int size = capacity;
527 	int extended = HOSTDATA(sdev->host)->translation;
528 
529 	DEB(printk("aha1740_biosparam\n"));
530 	if (extended && (ip[2] > 1024))	{
531 		ip[0] = 255;
532 		ip[1] = 63;
533 		ip[2] = size / (255 * 63);
534 	} else {
535 		ip[0] = 64;
536 		ip[1] = 32;
537 		ip[2] = size >> 11;
538 	}
539 	return 0;
540 }
541 
aha1740_eh_abort_handler(Scsi_Cmnd * dummy)542 static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy)
543 {
544 /*
545  * From Alan Cox :
546  * The AHA1740 has firmware handled abort/reset handling. The "head in
547  * sand" kernel code is correct for once 8)
548  *
549  * So we define a dummy handler just to keep the kernel SCSI code as
550  * quiet as possible...
551  */
552 
553 	return 0;
554 }
555 
556 static struct scsi_host_template aha1740_template = {
557 	.module           = THIS_MODULE,
558 	.proc_name        = "aha1740",
559 	.proc_info        = aha1740_proc_info,
560 	.name             = "Adaptec 174x (EISA)",
561 	.queuecommand     = aha1740_queuecommand,
562 	.bios_param       = aha1740_biosparam,
563 	.can_queue        = AHA1740_ECBS,
564 	.this_id          = 7,
565 	.sg_tablesize     = AHA1740_SCATTER,
566 	.cmd_per_lun      = AHA1740_CMDLUN,
567 	.use_clustering   = ENABLE_CLUSTERING,
568 	.eh_abort_handler = aha1740_eh_abort_handler,
569 };
570 
aha1740_probe(struct device * dev)571 static int aha1740_probe (struct device *dev)
572 {
573 	int slotbase, rc;
574 	unsigned int irq_level, irq_type, translation;
575 	struct Scsi_Host *shpnt;
576 	struct aha1740_hostdata *host;
577 	struct eisa_device *edev = to_eisa_device (dev);
578 
579 	DEB(printk("aha1740_probe: \n"));
580 
581 	slotbase = edev->base_addr + EISA_VENDOR_ID_OFFSET;
582 	if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */
583 		return -EBUSY;
584 	if (!aha1740_test_port(slotbase))
585 		goto err_release_region;
586 	aha1740_getconfig(slotbase,&irq_level,&irq_type,&translation);
587 	if ((inb(G2STAT(slotbase)) &
588 	     (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) {
589 		/* If the card isn't ready, hard reset it */
590 		outb(G2CNTRL_HRST, G2CNTRL(slotbase));
591 		outb(0, G2CNTRL(slotbase));
592 	}
593 	printk(KERN_INFO "Configuring slot %d at IO:%x, IRQ %u (%s)\n",
594 	       edev->slot, slotbase, irq_level, irq_type ? "edge" : "level");
595 	printk(KERN_INFO "aha174x: Extended translation %sabled.\n",
596 	       translation ? "en" : "dis");
597 	shpnt = scsi_host_alloc(&aha1740_template,
598 			      sizeof(struct aha1740_hostdata));
599 	if(shpnt == NULL)
600 		goto err_release_region;
601 
602 	shpnt->base = 0;
603 	shpnt->io_port = slotbase;
604 	shpnt->n_io_port = SLOTSIZE;
605 	shpnt->irq = irq_level;
606 	shpnt->dma_channel = 0xff;
607 	host = HOSTDATA(shpnt);
608 	host->edev = edev;
609 	host->translation = translation;
610 	host->ecb_dma_addr = dma_map_single (&edev->dev, host->ecb,
611 					     sizeof (host->ecb),
612 					     DMA_BIDIRECTIONAL);
613 	if (!host->ecb_dma_addr) {
614 		printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n");
615 		scsi_unregister (shpnt);
616 		goto err_host_put;
617 	}
618 
619 	DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level));
620 	if (request_irq(irq_level,aha1740_intr_handle,irq_type ? 0 : IRQF_SHARED,
621 			"aha1740",shpnt)) {
622 		printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n",
623 		       irq_level);
624 		goto err_unmap;
625 	}
626 
627 	eisa_set_drvdata (edev, shpnt);
628 
629 	rc = scsi_add_host (shpnt, dev);
630 	if (rc)
631 		goto err_irq;
632 
633 	scsi_scan_host (shpnt);
634 	return 0;
635 
636  err_irq:
637  	free_irq(irq_level, shpnt);
638  err_unmap:
639 	dma_unmap_single (&edev->dev, host->ecb_dma_addr,
640 			  sizeof (host->ecb), DMA_BIDIRECTIONAL);
641  err_host_put:
642 	scsi_host_put (shpnt);
643  err_release_region:
644 	release_region(slotbase, SLOTSIZE);
645 
646 	return -ENODEV;
647 }
648 
aha1740_remove(struct device * dev)649 static __devexit int aha1740_remove (struct device *dev)
650 {
651 	struct Scsi_Host *shpnt = dev_get_drvdata(dev);
652 	struct aha1740_hostdata *host = HOSTDATA (shpnt);
653 
654 	scsi_remove_host(shpnt);
655 
656 	free_irq (shpnt->irq, shpnt);
657 	dma_unmap_single (dev, host->ecb_dma_addr,
658 			  sizeof (host->ecb), DMA_BIDIRECTIONAL);
659 	release_region (shpnt->io_port, SLOTSIZE);
660 
661 	scsi_host_put (shpnt);
662 
663 	return 0;
664 }
665 
666 static struct eisa_device_id aha1740_ids[] = {
667 	{ "ADP0000" },		/* 1740  */
668 	{ "ADP0001" },		/* 1740A */
669 	{ "ADP0002" },		/* 1742A */
670 	{ "ADP0400" },		/* 1744  */
671 	{ "" }
672 };
673 MODULE_DEVICE_TABLE(eisa, aha1740_ids);
674 
675 static struct eisa_driver aha1740_driver = {
676 	.id_table = aha1740_ids,
677 	.driver   = {
678 		.name    = "aha1740",
679 		.probe   = aha1740_probe,
680 		.remove  = __devexit_p (aha1740_remove),
681 	},
682 };
683 
aha1740_init(void)684 static __init int aha1740_init (void)
685 {
686 	return eisa_driver_register (&aha1740_driver);
687 }
688 
aha1740_exit(void)689 static __exit void aha1740_exit (void)
690 {
691 	eisa_driver_unregister (&aha1740_driver);
692 }
693 
694 module_init (aha1740_init);
695 module_exit (aha1740_exit);
696 
697 MODULE_LICENSE("GPL");
698