Linux Audio

Check our new training course

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