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