3 * linux/kernel/aha1740.c
5 * Based loosely on aha1542.c which is
6 * Copyright (C) 1992 Tommy Thorn and
7 * Modified by Eric Youngdale
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.
13 * Modifications to makecode and queuecommand
14 * for proper handling of multiple devices courteously
15 * provided by Michael Weller, March, 1993
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
22 * aha1740_makecode may still need even more work
23 * if it doesn't work for your devices, take a look.
25 * Reworked for new_eh and new locking by Alan Cox <alan@lxorguk.ukuu.org.uk>
27 * Converted to EISA and generic DMA APIs by Marc Zyngier
28 * <maz@wild-wind.fr.eu.org>, 4/2003.
30 * Shared interrupt support added by Rask Ingemann Lambertsen
31 * <rask@sygehus.dk>, 10/2003
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.
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>
59 #include <scsi/scsi_host.h>
62 /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
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
];
81 struct aha1740_chain sg_chain
[AHA1740_SCATTER
];
82 dma_addr_t sg_dma_addr
;
83 dma_addr_t buf_dma_addr
;
86 #define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata)
88 static inline struct ecb
*ecb_dma_to_cpu (struct Scsi_Host
*host
,
91 struct aha1740_hostdata
*hdata
= HOSTDATA (host
);
94 offset
= dma
- hdata
->ecb_dma_addr
;
96 return (struct ecb
*)(((char *) hdata
->ecb
) + (unsigned int) offset
);
99 static inline dma_addr_t
ecb_cpu_to_dma (struct Scsi_Host
*host
, void *cpu
)
101 struct aha1740_hostdata
*hdata
= HOSTDATA (host
);
104 offset
= (char *) cpu
- (char *) hdata
->ecb
;
106 return hdata
->ecb_dma_addr
+ offset
;
109 static int aha1740_show_info(struct seq_file
*m
, struct Scsi_Host
*shpnt
)
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");
119 static int aha1740_makecode(unchar
*sense
, unchar
*status
)
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 */
139 status_word
= * (struct statusword
*) status
;
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]);
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] ) {
151 if ( status_word
.dor
)
152 retval
=DID_ERROR
; /* It's an Overrun */
153 /* If not overrun, assume underrun and
155 case 0x00: /* No info, assume no error, should
163 retval
=DID_BAD_TARGET
;
168 /* Either by this driver or the
172 retval
=DID_ERROR
; /* No further
177 /* Michael suggests, and Brad concurs: */
178 if ( status_word
.qf
) {
179 retval
= DID_TIME_OUT
; /* forces a redo */
180 /* I think this specific one should
181 * not happen -Brad */
182 printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
184 if ( status
[0]&0x60 ) {
185 /* Didn't find a better error */
188 /* In any other case return DID_OK so for example
189 CONDITION_CHECKS make it through to the appropriate
193 /* Under all circumstances supply the target status -Michael */
194 return status
[3] | retval
<< 16;
197 static int aha1740_test_port(unsigned int base
)
199 if ( inb(PORTADR(base
)) & PORTADDR_ENH
)
200 return 1; /* Okay, we're all set */
202 printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n");
206 /* A "high" level interrupt handler */
207 static irqreturn_t
aha1740_intr_handle(int irq
, void *dev_id
)
209 struct Scsi_Host
*host
= (struct Scsi_Host
*) dev_id
;
210 void (*my_done
)(struct scsi_cmnd
*);
211 int errstatus
, adapstat
;
214 struct scsi_cmnd
*SCtmp
;
218 struct aha1740_sg
*sgptr
;
219 struct eisa_device
*edev
;
222 panic("aha1740.c: Irq from unknown host!\n");
223 spin_lock_irqsave(host
->host_lock
, flags
);
224 base
= host
->io_port
;
226 edev
= HOSTDATA(host
)->edev
;
228 while(inb(G2STAT(base
)) & G2STAT_INTPEND
) {
230 DEB(printk("aha1740_intr top of loop.\n"));
231 adapstat
= inb(G2INTST(base
));
232 ecbptr
= ecb_dma_to_cpu (host
, inl(MBOXIN0(base
)));
233 outb(G2CNTRL_IRST
,G2CNTRL(base
)); /* interrupt reset */
235 switch ( adapstat
& G2INTST_MASK
) {
236 case G2INTST_CCBRETRY
:
237 case G2INTST_CCBERROR
:
238 case G2INTST_CCBGOOD
:
239 /* Host Ready -> Mailbox in complete */
240 outb(G2CNTRL_HRDY
,G2CNTRL(base
));
242 printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
243 inb(G2STAT(base
)),adapstat
,
244 inb(G2INTST(base
)), number_serviced
++);
247 SCtmp
= ecbptr
->SCpnt
;
249 printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
250 inb(G2STAT(base
)),adapstat
,
251 inb(G2INTST(base
)), number_serviced
++);
254 sgptr
= (struct aha1740_sg
*) SCtmp
->host_scribble
;
255 scsi_dma_unmap(SCtmp
);
257 /* Free the sg block */
258 dma_free_coherent (&edev
->dev
,
259 sizeof (struct aha1740_sg
),
260 SCtmp
->host_scribble
,
263 /* Fetch the sense data, and tuck it away, in
264 the required slot. The Adaptec
265 automatically fetches it, and there is no
266 guarantee that we will still have it in the
267 cdb when we come back */
268 if ( (adapstat
& G2INTST_MASK
) == G2INTST_CCBERROR
) {
269 memcpy(SCtmp
->sense_buffer
, ecbptr
->sense
,
270 SCSI_SENSE_BUFFERSIZE
);
271 errstatus
= aha1740_makecode(ecbptr
->sense
,ecbptr
->status
);
275 printk("aha1740_intr_handle: returning %6x\n",
277 SCtmp
->result
= errstatus
;
278 my_done
= ecbptr
->done
;
279 memset(ecbptr
,0,sizeof(struct ecb
));
284 case G2INTST_HARDFAIL
:
285 printk(KERN_ALERT
"aha1740 hardware failure!\n");
286 panic("aha1740.c"); /* Goodbye */
288 case G2INTST_ASNEVENT
:
289 printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
294 inb(MBOXIN3(base
))); /* Say What? */
295 /* Host Ready -> Mailbox in complete */
296 outb(G2CNTRL_HRDY
,G2CNTRL(base
));
299 case G2INTST_CMDGOOD
:
300 /* set immediate command success flag here: */
303 case G2INTST_CMDERROR
:
304 /* Set immediate command failure flag here: */
310 spin_unlock_irqrestore(host
->host_lock
, flags
);
311 return IRQ_RETVAL(handled
);
314 static int aha1740_queuecommand_lck(struct scsi_cmnd
* SCpnt
,
315 void (*done
)(struct scsi_cmnd
*))
318 unchar
*cmd
= (unchar
*) SCpnt
->cmnd
;
319 unchar target
= scmd_id(SCpnt
);
320 struct aha1740_hostdata
*host
= HOSTDATA(SCpnt
->device
->host
);
323 struct aha1740_sg
*sgptr
;
327 if(*cmd
== REQUEST_SENSE
) {
334 if (*cmd
== READ_10
|| *cmd
== WRITE_10
)
335 i
= xscsi2int(cmd
+2);
336 else if (*cmd
== READ_6
|| *cmd
== WRITE_6
)
340 printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ",
341 target
, *cmd
, i
, bufflen
);
343 for (i
= 0; i
< SCpnt
->cmd_len
; i
++) printk("%02x ", cmd
[i
]);
347 /* locate an available ecb */
348 spin_lock_irqsave(SCpnt
->device
->host
->host_lock
, flags
);
349 ecbno
= host
->last_ecb_used
+ 1; /* An optimization */
350 if (ecbno
>= AHA1740_ECBS
)
353 if (!host
->ecb
[ecbno
].cmdw
)
356 if (ecbno
>= AHA1740_ECBS
)
358 } while (ecbno
!= host
->last_ecb_used
);
360 if (host
->ecb
[ecbno
].cmdw
)
361 panic("Unable to find empty ecb for aha1740.\n");
363 host
->ecb
[ecbno
].cmdw
= AHA1740CMD_INIT
; /* SCSI Initiator Command
364 doubles as reserved flag */
366 host
->last_ecb_used
= ecbno
;
367 spin_unlock_irqrestore(SCpnt
->device
->host
->host_lock
, flags
);
370 printk("Sending command (%d %x)...", ecbno
, done
);
373 host
->ecb
[ecbno
].cdblen
= SCpnt
->cmd_len
; /* SCSI Command
378 if (*cmd
== READ_10
|| *cmd
== READ_6
)
380 else if (*cmd
== WRITE_10
|| *cmd
== WRITE_6
)
383 memcpy(host
->ecb
[ecbno
].cdb
, cmd
, SCpnt
->cmd_len
);
385 SCpnt
->host_scribble
= dma_alloc_coherent (&host
->edev
->dev
,
386 sizeof (struct aha1740_sg
),
387 &sg_dma
, GFP_ATOMIC
);
388 if(SCpnt
->host_scribble
== NULL
) {
389 printk(KERN_WARNING
"aha1740: out of memory in queuecommand!\n");
392 sgptr
= (struct aha1740_sg
*) SCpnt
->host_scribble
;
393 sgptr
->sg_dma_addr
= sg_dma
;
395 nseg
= scsi_dma_map(SCpnt
);
398 struct scatterlist
*sg
;
399 struct aha1740_chain
* cptr
;
401 DEB(unsigned char * ptr
);
403 host
->ecb
[ecbno
].sg
= 1; /* SCSI Initiator Command
405 cptr
= sgptr
->sg_chain
;
406 scsi_for_each_sg(SCpnt
, sg
, nseg
, i
) {
407 cptr
[i
].datalen
= sg_dma_len (sg
);
408 cptr
[i
].dataptr
= sg_dma_address (sg
);
410 host
->ecb
[ecbno
].datalen
= nseg
* sizeof(struct aha1740_chain
);
411 host
->ecb
[ecbno
].dataptr
= sg_dma
;
413 printk("cptr %x: ",cptr
);
414 ptr
= (unsigned char *) cptr
;
415 for(i
=0;i
<24;i
++) printk("%02x ", ptr
[i
]);
418 host
->ecb
[ecbno
].datalen
= 0;
419 host
->ecb
[ecbno
].dataptr
= 0;
421 host
->ecb
[ecbno
].lun
= SCpnt
->device
->lun
;
422 host
->ecb
[ecbno
].ses
= 1; /* Suppress underrun errors */
423 host
->ecb
[ecbno
].dir
= direction
;
424 host
->ecb
[ecbno
].ars
= 1; /* Yes, get the sense on an error */
425 host
->ecb
[ecbno
].senselen
= 12;
426 host
->ecb
[ecbno
].senseptr
= ecb_cpu_to_dma (SCpnt
->device
->host
,
427 host
->ecb
[ecbno
].sense
);
428 host
->ecb
[ecbno
].statusptr
= ecb_cpu_to_dma (SCpnt
->device
->host
,
429 host
->ecb
[ecbno
].status
);
430 host
->ecb
[ecbno
].done
= done
;
431 host
->ecb
[ecbno
].SCpnt
= SCpnt
;
435 printk("aha1740_command: sending.. ");
436 for (i
= 0; i
< sizeof(host
->ecb
[ecbno
]) - 10; i
++)
437 printk("%02x ", ((unchar
*)&host
->ecb
[ecbno
])[i
]);
442 /* The Adaptec Spec says the card is so fast that the loops
443 will only be executed once in the code below. Even if this
444 was true with the fastest processors when the spec was
445 written, it doesn't seem to be true with today's fast
446 processors. We print a warning if the code is executed more
447 often than LOOPCNT_WARN. If this happens, it should be
448 investigated. If the count reaches LOOPCNT_MAX, we assume
449 something is broken; since there is no way to return an
450 error (the return value is ignored by the mid-level scsi
451 layer) we have to panic (and maybe that's the best thing we
452 can do then anyhow). */
454 #define LOOPCNT_WARN 10 /* excessive mbxout wait -> syslog-msg */
455 #define LOOPCNT_MAX 1000000 /* mbxout deadlock -> panic() after ~ 2 sec. */
457 unsigned int base
= SCpnt
->device
->host
->io_port
;
458 DEB(printk("aha1740[%d] critical section\n",ecbno
));
460 spin_lock_irqsave(SCpnt
->device
->host
->host_lock
, flags
);
461 for (loopcnt
= 0; ; loopcnt
++) {
462 if (inb(G2STAT(base
)) & G2STAT_MBXOUT
) break;
463 if (loopcnt
== LOOPCNT_WARN
) {
464 printk("aha1740[%d]_mbxout wait!\n",ecbno
);
466 if (loopcnt
== LOOPCNT_MAX
)
467 panic("aha1740.c: mbxout busy!\n");
469 outl (ecb_cpu_to_dma (SCpnt
->device
->host
, host
->ecb
+ ecbno
),
471 for (loopcnt
= 0; ; loopcnt
++) {
472 if (! (inb(G2STAT(base
)) & G2STAT_BUSY
)) break;
473 if (loopcnt
== LOOPCNT_WARN
) {
474 printk("aha1740[%d]_attn wait!\n",ecbno
);
476 if (loopcnt
== LOOPCNT_MAX
)
477 panic("aha1740.c: attn wait failed!\n");
479 outb(ATTN_START
| (target
& 7), ATTN(base
)); /* Start it up */
480 spin_unlock_irqrestore(SCpnt
->device
->host
->host_lock
, flags
);
481 DEB(printk("aha1740[%d] request queued.\n",ecbno
));
483 printk(KERN_ALERT
"aha1740_queuecommand: done can't be NULL\n");
487 static DEF_SCSI_QCMD(aha1740_queuecommand
)
489 /* Query the board for its irq_level and irq_type. Nothing else matters
490 in enhanced mode on an EISA bus. */
492 static void aha1740_getconfig(unsigned int base
, unsigned int *irq_level
,
493 unsigned int *irq_type
,
494 unsigned int *translation
)
496 static int intab
[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
498 *irq_level
= intab
[inb(INTDEF(base
)) & 0x7];
499 *irq_type
= (inb(INTDEF(base
)) & 0x8) >> 3;
500 *translation
= inb(RESV1(base
)) & 0x1;
501 outb(inb(INTDEF(base
)) | 0x10, INTDEF(base
));
504 static int aha1740_biosparam(struct scsi_device
*sdev
,
505 struct block_device
*dev
,
506 sector_t capacity
, int* ip
)
509 int extended
= HOSTDATA(sdev
->host
)->translation
;
511 DEB(printk("aha1740_biosparam\n"));
512 if (extended
&& (ip
[2] > 1024)) {
515 ip
[2] = size
/ (255 * 63);
524 static int aha1740_eh_abort_handler (struct scsi_cmnd
*dummy
)
528 * The AHA1740 has firmware handled abort/reset handling. The "head in
529 * sand" kernel code is correct for once 8)
531 * So we define a dummy handler just to keep the kernel SCSI code as
532 * quiet as possible...
538 static struct scsi_host_template aha1740_template
= {
539 .module
= THIS_MODULE
,
540 .proc_name
= "aha1740",
541 .show_info
= aha1740_show_info
,
542 .name
= "Adaptec 174x (EISA)",
543 .queuecommand
= aha1740_queuecommand
,
544 .bios_param
= aha1740_biosparam
,
545 .can_queue
= AHA1740_ECBS
,
547 .sg_tablesize
= AHA1740_SCATTER
,
548 .use_clustering
= ENABLE_CLUSTERING
,
549 .eh_abort_handler
= aha1740_eh_abort_handler
,
552 static int aha1740_probe (struct device
*dev
)
555 unsigned int irq_level
, irq_type
, translation
;
556 struct Scsi_Host
*shpnt
;
557 struct aha1740_hostdata
*host
;
558 struct eisa_device
*edev
= to_eisa_device (dev
);
560 DEB(printk("aha1740_probe: \n"));
562 slotbase
= edev
->base_addr
+ EISA_VENDOR_ID_OFFSET
;
563 if (!request_region(slotbase
, SLOTSIZE
, "aha1740")) /* See if in use */
565 if (!aha1740_test_port(slotbase
))
566 goto err_release_region
;
567 aha1740_getconfig(slotbase
,&irq_level
,&irq_type
,&translation
);
568 if ((inb(G2STAT(slotbase
)) &
569 (G2STAT_MBXOUT
|G2STAT_BUSY
)) != G2STAT_MBXOUT
) {
570 /* If the card isn't ready, hard reset it */
571 outb(G2CNTRL_HRST
, G2CNTRL(slotbase
));
572 outb(0, G2CNTRL(slotbase
));
574 printk(KERN_INFO
"Configuring slot %d at IO:%x, IRQ %u (%s)\n",
575 edev
->slot
, slotbase
, irq_level
, irq_type
? "edge" : "level");
576 printk(KERN_INFO
"aha174x: Extended translation %sabled.\n",
577 translation
? "en" : "dis");
578 shpnt
= scsi_host_alloc(&aha1740_template
,
579 sizeof(struct aha1740_hostdata
));
581 goto err_release_region
;
584 shpnt
->io_port
= slotbase
;
585 shpnt
->n_io_port
= SLOTSIZE
;
586 shpnt
->irq
= irq_level
;
587 shpnt
->dma_channel
= 0xff;
588 host
= HOSTDATA(shpnt
);
590 host
->translation
= translation
;
591 host
->ecb_dma_addr
= dma_map_single (&edev
->dev
, host
->ecb
,
594 if (!host
->ecb_dma_addr
) {
595 printk (KERN_ERR
"aha1740_probe: Couldn't map ECB, giving up\n");
596 scsi_host_put (shpnt
);
600 DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level
));
601 if (request_irq(irq_level
,aha1740_intr_handle
,irq_type
? 0 : IRQF_SHARED
,
603 printk(KERN_ERR
"aha1740_probe: Unable to allocate IRQ %d.\n",
608 eisa_set_drvdata (edev
, shpnt
);
610 rc
= scsi_add_host (shpnt
, dev
);
614 scsi_scan_host (shpnt
);
618 free_irq(irq_level
, shpnt
);
620 dma_unmap_single (&edev
->dev
, host
->ecb_dma_addr
,
621 sizeof (host
->ecb
), DMA_BIDIRECTIONAL
);
623 scsi_host_put (shpnt
);
625 release_region(slotbase
, SLOTSIZE
);
630 static int aha1740_remove (struct device
*dev
)
632 struct Scsi_Host
*shpnt
= dev_get_drvdata(dev
);
633 struct aha1740_hostdata
*host
= HOSTDATA (shpnt
);
635 scsi_remove_host(shpnt
);
637 free_irq (shpnt
->irq
, shpnt
);
638 dma_unmap_single (dev
, host
->ecb_dma_addr
,
639 sizeof (host
->ecb
), DMA_BIDIRECTIONAL
);
640 release_region (shpnt
->io_port
, SLOTSIZE
);
642 scsi_host_put (shpnt
);
647 static struct eisa_device_id aha1740_ids
[] = {
648 { "ADP0000" }, /* 1740 */
649 { "ADP0001" }, /* 1740A */
650 { "ADP0002" }, /* 1742A */
651 { "ADP0400" }, /* 1744 */
654 MODULE_DEVICE_TABLE(eisa
, aha1740_ids
);
656 static struct eisa_driver aha1740_driver
= {
657 .id_table
= aha1740_ids
,
660 .probe
= aha1740_probe
,
661 .remove
= aha1740_remove
,
665 static __init
int aha1740_init (void)
667 return eisa_driver_register (&aha1740_driver
);
670 static __exit
void aha1740_exit (void)
672 eisa_driver_unregister (&aha1740_driver
);
675 module_init (aha1740_init
);
676 module_exit (aha1740_exit
);
678 MODULE_LICENSE("GPL");