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