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@redhat.com>
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>
55 #include <asm/system.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_proc_info(struct Scsi_Host
*shpnt
, char *buffer
,
110 char **start
, off_t offset
,
111 int length
, int inout
)
114 struct aha1740_hostdata
*host
;
119 host
= HOSTDATA(shpnt
);
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");
131 *start
= buffer
+ offset
;
138 static int aha1740_makecode(unchar
*sense
, unchar
*status
)
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 */
158 status_word
= * (struct statusword
*) status
;
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]);
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] ) {
170 if ( status_word
.dor
)
171 retval
=DID_ERROR
; /* It's an Overrun */
172 /* If not overrun, assume underrun and
174 case 0x00: /* No info, assume no error, should
182 retval
=DID_BAD_TARGET
;
187 /* Either by this driver or the
191 retval
=DID_ERROR
; /* No further
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");
203 if ( status
[0]&0x60 ) {
204 /* Didn't find a better error */
207 /* In any other case return DID_OK so for example
208 CONDITION_CHECKS make it through to the appropriate
212 /* Under all circumstances supply the target status -Michael */
213 return status
[3] | retval
<< 16;
216 static int aha1740_test_port(unsigned int base
)
218 if ( inb(PORTADR(base
)) & PORTADDR_ENH
)
219 return 1; /* Okay, we're all set */
221 printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n");
225 /* A "high" level interrupt handler */
226 static irqreturn_t
aha1740_intr_handle(int irq
, void *dev_id
)
228 struct Scsi_Host
*host
= (struct Scsi_Host
*) dev_id
;
229 void (*my_done
)(Scsi_Cmnd
*);
230 int errstatus
, adapstat
;
237 struct aha1740_sg
*sgptr
;
238 struct eisa_device
*edev
;
241 panic("aha1740.c: Irq from unknown host!\n");
242 spin_lock_irqsave(host
->host_lock
, flags
);
243 base
= host
->io_port
;
245 edev
= HOSTDATA(host
)->edev
;
247 while(inb(G2STAT(base
)) & G2STAT_INTPEND
) {
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 */
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
));
261 printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
262 inb(G2STAT(base
)),adapstat
,
263 inb(G2INTST(base
)), number_serviced
++);
266 SCtmp
= ecbptr
->SCpnt
;
268 printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
269 inb(G2STAT(base
)),adapstat
,
270 inb(G2INTST(base
)), number_serviced
++);
273 sgptr
= (struct aha1740_sg
*) SCtmp
->host_scribble
;
274 scsi_dma_unmap(SCtmp
);
276 /* Free the sg block */
277 dma_free_coherent (&edev
->dev
,
278 sizeof (struct aha1740_sg
),
279 SCtmp
->host_scribble
,
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 sizeof(SCtmp
->sense_buffer
));
290 errstatus
= aha1740_makecode(ecbptr
->sense
,ecbptr
->status
);
294 printk("aha1740_intr_handle: returning %6x\n",
296 SCtmp
->result
= errstatus
;
297 my_done
= ecbptr
->done
;
298 memset(ecbptr
,0,sizeof(struct ecb
));
303 case G2INTST_HARDFAIL
:
304 printk(KERN_ALERT
"aha1740 hardware failure!\n");
305 panic("aha1740.c"); /* Goodbye */
307 case G2INTST_ASNEVENT
:
308 printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
313 inb(MBOXIN3(base
))); /* Say What? */
314 /* Host Ready -> Mailbox in complete */
315 outb(G2CNTRL_HRDY
,G2CNTRL(base
));
318 case G2INTST_CMDGOOD
:
319 /* set immediate command success flag here: */
322 case G2INTST_CMDERROR
:
323 /* Set immediate command failure flag here: */
329 spin_unlock_irqrestore(host
->host_lock
, flags
);
330 return IRQ_RETVAL(handled
);
333 static int aha1740_queuecommand(Scsi_Cmnd
* SCpnt
, void (*done
)(Scsi_Cmnd
*))
336 unchar
*cmd
= (unchar
*) SCpnt
->cmnd
;
337 unchar target
= scmd_id(SCpnt
);
338 struct aha1740_hostdata
*host
= HOSTDATA(SCpnt
->device
->host
);
341 struct aha1740_sg
*sgptr
;
345 if(*cmd
== REQUEST_SENSE
) {
352 if (*cmd
== READ_10
|| *cmd
== WRITE_10
)
353 i
= xscsi2int(cmd
+2);
354 else if (*cmd
== READ_6
|| *cmd
== WRITE_6
)
358 printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ",
359 target
, *cmd
, i
, bufflen
);
361 for (i
= 0; i
< SCpnt
->cmd_len
; i
++) printk("%02x ", cmd
[i
]);
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
)
371 if (!host
->ecb
[ecbno
].cmdw
)
374 if (ecbno
>= AHA1740_ECBS
)
376 } while (ecbno
!= host
->last_ecb_used
);
378 if (host
->ecb
[ecbno
].cmdw
)
379 panic("Unable to find empty ecb for aha1740.\n");
381 host
->ecb
[ecbno
].cmdw
= AHA1740CMD_INIT
; /* SCSI Initiator Command
382 doubles as reserved flag */
384 host
->last_ecb_used
= ecbno
;
385 spin_unlock_irqrestore(SCpnt
->device
->host
->host_lock
, flags
);
388 printk("Sending command (%d %x)...", ecbno
, done
);
391 host
->ecb
[ecbno
].cdblen
= SCpnt
->cmd_len
; /* SCSI Command
396 if (*cmd
== READ_10
|| *cmd
== READ_6
)
398 else if (*cmd
== WRITE_10
|| *cmd
== WRITE_6
)
401 memcpy(host
->ecb
[ecbno
].cdb
, cmd
, SCpnt
->cmd_len
);
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");
410 sgptr
= (struct aha1740_sg
*) SCpnt
->host_scribble
;
411 sgptr
->sg_dma_addr
= sg_dma
;
413 nseg
= scsi_dma_map(SCpnt
);
416 struct scatterlist
*sg
;
417 struct aha1740_chain
* cptr
;
419 DEB(unsigned char * ptr
);
421 host
->ecb
[ecbno
].sg
= 1; /* SCSI Initiator Command
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
);
428 host
->ecb
[ecbno
].datalen
= nseg
* sizeof(struct aha1740_chain
);
429 host
->ecb
[ecbno
].dataptr
= sg_dma
;
431 printk("cptr %x: ",cptr
);
432 ptr
= (unsigned char *) cptr
;
433 for(i
=0;i
<24;i
++) printk("%02x ", ptr
[i
]);
436 host
->ecb
[ecbno
].datalen
= 0;
437 host
->ecb
[ecbno
].dataptr
= 0;
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
;
453 printk("aha1740_command: sending.. ");
454 for (i
= 0; i
< sizeof(host
->ecb
[ecbno
]) - 10; i
++)
455 printk("%02x ", ((unchar
*)&host
->ecb
[ecbno
])[i
]);
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 todays 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). */
472 #define LOOPCNT_WARN 10 /* excessive mbxout wait -> syslog-msg */
473 #define LOOPCNT_MAX 1000000 /* mbxout deadlock -> panic() after ~ 2 sec. */
475 unsigned int base
= SCpnt
->device
->host
->io_port
;
476 DEB(printk("aha1740[%d] critical section\n",ecbno
));
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
);
484 if (loopcnt
== LOOPCNT_MAX
)
485 panic("aha1740.c: mbxout busy!\n");
487 outl (ecb_cpu_to_dma (SCpnt
->device
->host
, host
->ecb
+ ecbno
),
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
);
494 if (loopcnt
== LOOPCNT_MAX
)
495 panic("aha1740.c: attn wait failed!\n");
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
));
501 printk(KERN_ALERT
"aha1740_queuecommand: done can't be NULL\n");
505 /* Query the board for its irq_level and irq_type. Nothing else matters
506 in enhanced mode on an EISA bus. */
508 static void aha1740_getconfig(unsigned int base
, unsigned int *irq_level
,
509 unsigned int *irq_type
,
510 unsigned int *translation
)
512 static int intab
[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
514 *irq_level
= intab
[inb(INTDEF(base
)) & 0x7];
515 *irq_type
= (inb(INTDEF(base
)) & 0x8) >> 3;
516 *translation
= inb(RESV1(base
)) & 0x1;
517 outb(inb(INTDEF(base
)) | 0x10, INTDEF(base
));
520 static int aha1740_biosparam(struct scsi_device
*sdev
,
521 struct block_device
*dev
,
522 sector_t capacity
, int* ip
)
525 int extended
= HOSTDATA(sdev
->host
)->translation
;
527 DEB(printk("aha1740_biosparam\n"));
528 if (extended
&& (ip
[2] > 1024)) {
531 ip
[2] = size
/ (255 * 63);
540 static int aha1740_eh_abort_handler (Scsi_Cmnd
*dummy
)
544 * The AHA1740 has firmware handled abort/reset handling. The "head in
545 * sand" kernel code is correct for once 8)
547 * So we define a dummy handler just to keep the kernel SCSI code as
548 * quiet as possible...
554 static struct scsi_host_template aha1740_template
= {
555 .module
= THIS_MODULE
,
556 .proc_name
= "aha1740",
557 .proc_info
= aha1740_proc_info
,
558 .name
= "Adaptec 174x (EISA)",
559 .queuecommand
= aha1740_queuecommand
,
560 .bios_param
= aha1740_biosparam
,
561 .can_queue
= AHA1740_ECBS
,
563 .sg_tablesize
= AHA1740_SCATTER
,
564 .cmd_per_lun
= AHA1740_CMDLUN
,
565 .use_clustering
= ENABLE_CLUSTERING
,
566 .use_sg_chaining
= ENABLE_SG_CHAINING
,
567 .eh_abort_handler
= aha1740_eh_abort_handler
,
570 static int aha1740_probe (struct device
*dev
)
573 unsigned int irq_level
, irq_type
, translation
;
574 struct Scsi_Host
*shpnt
;
575 struct aha1740_hostdata
*host
;
576 struct eisa_device
*edev
= to_eisa_device (dev
);
578 DEB(printk("aha1740_probe: \n"));
580 slotbase
= edev
->base_addr
+ EISA_VENDOR_ID_OFFSET
;
581 if (!request_region(slotbase
, SLOTSIZE
, "aha1740")) /* See if in use */
583 if (!aha1740_test_port(slotbase
))
584 goto err_release_region
;
585 aha1740_getconfig(slotbase
,&irq_level
,&irq_type
,&translation
);
586 if ((inb(G2STAT(slotbase
)) &
587 (G2STAT_MBXOUT
|G2STAT_BUSY
)) != G2STAT_MBXOUT
) {
588 /* If the card isn't ready, hard reset it */
589 outb(G2CNTRL_HRST
, G2CNTRL(slotbase
));
590 outb(0, G2CNTRL(slotbase
));
592 printk(KERN_INFO
"Configuring slot %d at IO:%x, IRQ %u (%s)\n",
593 edev
->slot
, slotbase
, irq_level
, irq_type
? "edge" : "level");
594 printk(KERN_INFO
"aha174x: Extended translation %sabled.\n",
595 translation
? "en" : "dis");
596 shpnt
= scsi_host_alloc(&aha1740_template
,
597 sizeof(struct aha1740_hostdata
));
599 goto err_release_region
;
602 shpnt
->io_port
= slotbase
;
603 shpnt
->n_io_port
= SLOTSIZE
;
604 shpnt
->irq
= irq_level
;
605 shpnt
->dma_channel
= 0xff;
606 host
= HOSTDATA(shpnt
);
608 host
->translation
= translation
;
609 host
->ecb_dma_addr
= dma_map_single (&edev
->dev
, host
->ecb
,
612 if (!host
->ecb_dma_addr
) {
613 printk (KERN_ERR
"aha1740_probe: Couldn't map ECB, giving up\n");
614 scsi_unregister (shpnt
);
618 DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level
));
619 if (request_irq(irq_level
,aha1740_intr_handle
,irq_type
? 0 : IRQF_SHARED
,
621 printk(KERN_ERR
"aha1740_probe: Unable to allocate IRQ %d.\n",
626 eisa_set_drvdata (edev
, shpnt
);
628 rc
= scsi_add_host (shpnt
, dev
);
632 scsi_scan_host (shpnt
);
636 free_irq(irq_level
, shpnt
);
638 dma_unmap_single (&edev
->dev
, host
->ecb_dma_addr
,
639 sizeof (host
->ecb
), DMA_BIDIRECTIONAL
);
641 scsi_host_put (shpnt
);
643 release_region(slotbase
, SLOTSIZE
);
648 static __devexit
int aha1740_remove (struct device
*dev
)
650 struct Scsi_Host
*shpnt
= dev
->driver_data
;
651 struct aha1740_hostdata
*host
= HOSTDATA (shpnt
);
653 scsi_remove_host(shpnt
);
655 free_irq (shpnt
->irq
, shpnt
);
656 dma_unmap_single (dev
, host
->ecb_dma_addr
,
657 sizeof (host
->ecb
), DMA_BIDIRECTIONAL
);
658 release_region (shpnt
->io_port
, SLOTSIZE
);
660 scsi_host_put (shpnt
);
665 static struct eisa_device_id aha1740_ids
[] = {
666 { "ADP0000" }, /* 1740 */
667 { "ADP0001" }, /* 1740A */
668 { "ADP0002" }, /* 1742A */
669 { "ADP0400" }, /* 1744 */
672 MODULE_DEVICE_TABLE(eisa
, aha1740_ids
);
674 static struct eisa_driver aha1740_driver
= {
675 .id_table
= aha1740_ids
,
678 .probe
= aha1740_probe
,
679 .remove
= __devexit_p (aha1740_remove
),
683 static __init
int aha1740_init (void)
685 return eisa_driver_register (&aha1740_driver
);
688 static __exit
void aha1740_exit (void)
690 eisa_driver_unregister (&aha1740_driver
);
693 module_init (aha1740_init
);
694 module_exit (aha1740_exit
);
696 MODULE_LICENSE("GPL");