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