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