Loading...
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");
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_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
138static 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
216static 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 */
226static 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,
289 SCSI_SENSE_BUFFERSIZE);
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
333static int aha1740_queuecommand_lck(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
334{
335 unchar direction;
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
505static 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
510static 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
522static 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
542static 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
556static 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
571static 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),
612 DMA_BIDIRECTIONAL);
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
649static __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
666static struct eisa_device_id aha1740_ids[] = {
667 { "ADP0000" }, /* 1740 */
668 { "ADP0001" }, /* 1740A */
669 { "ADP0002" }, /* 1742A */
670 { "ADP0400" }, /* 1744 */
671 { "" }
672};
673MODULE_DEVICE_TABLE(eisa, aha1740_ids);
674
675static 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
684static __init int aha1740_init (void)
685{
686 return eisa_driver_register (&aha1740_driver);
687}
688
689static __exit void aha1740_exit (void)
690{
691 eisa_driver_unregister (&aha1740_driver);
692}
693
694module_init (aha1740_init);
695module_exit (aha1740_exit);
696
697MODULE_LICENSE("GPL");