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