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