Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
aha1740.c
Go to the documentation of this file.
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
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 <[email protected]>, 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 <[email protected]>
26  *
27  * Converted to EISA and generic DMA APIs by Marc Zyngier
28  * <[email protected]>, 4/2003.
29  *
30  * Shared interrupt support added by Rask Ingemann Lambertsen
31  * <[email protected]>, 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 
73  struct eisa_device *edev;
74  unsigned int translation;
75  unsigned int last_ecb_used;
77  struct ecb ecb[AHA1740_ECBS];
78 };
79 
80 struct aha1740_sg {
84 };
85 
86 #define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata)
87 
88 static inline struct ecb *ecb_dma_to_cpu (struct Scsi_Host *host,
90 {
91  struct aha1740_hostdata *hdata = HOSTDATA (host);
93 
94  offset = dma - hdata->ecb_dma_addr;
95 
96  return (struct ecb *)(((char *) hdata->ecb) + (unsigned int) offset);
97 }
98 
99 static inline dma_addr_t ecb_cpu_to_dma (struct Scsi_Host *host, void *cpu)
100 {
101  struct aha1740_hostdata *hdata = HOSTDATA (host);
103 
104  offset = (char *) cpu - (char *) hdata->ecb;
105 
106  return hdata->ecb_dma_addr + offset;
107 }
108 
109 static 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 
138 static 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 
216 static 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 */
226 static 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,
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 
333 static int aha1740_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
334 {
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 
505 static 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 
510 static 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 
522 static 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 
542 static 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 
556 static 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 
571 static 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),
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 
649 static __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 
666 static struct eisa_device_id aha1740_ids[] = {
667  { "ADP0000" }, /* 1740 */
668  { "ADP0001" }, /* 1740A */
669  { "ADP0002" }, /* 1742A */
670  { "ADP0400" }, /* 1744 */
671  { "" }
672 };
673 MODULE_DEVICE_TABLE(eisa, aha1740_ids);
674 
675 static 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 
684 static __init int aha1740_init (void)
685 {
686  return eisa_driver_register (&aha1740_driver);
687 }
688 
689 static __exit void aha1740_exit (void)
690 {
691  eisa_driver_unregister (&aha1740_driver);
692 }
693 
694 module_init (aha1740_init);
695 module_exit (aha1740_exit);
696 
697 MODULE_LICENSE("GPL");