cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

aha1740.c (19523B)


      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
     76struct 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
     84struct 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
     92static 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
    103static 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
    113static 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
    123static 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
    202static 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 */
    212static 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
    322static 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
    495static 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
    500static 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
    512static 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
    532static 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
    546static 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
    559static 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
    636static 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
    653static struct eisa_device_id aha1740_ids[] = {
    654	{ "ADP0000" },		/* 1740  */
    655	{ "ADP0001" },		/* 1740A */
    656	{ "ADP0002" },		/* 1742A */
    657	{ "ADP0400" },		/* 1744  */
    658	{ "" }
    659};
    660MODULE_DEVICE_TABLE(eisa, aha1740_ids);
    661
    662static 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
    671static __init int aha1740_init (void)
    672{
    673	return eisa_driver_register (&aha1740_driver);
    674}
    675
    676static __exit void aha1740_exit (void)
    677{
    678	eisa_driver_unregister (&aha1740_driver);
    679}
    680
    681module_init (aha1740_init);
    682module_exit (aha1740_exit);
    683
    684MODULE_LICENSE("GPL");