* better
[mascara-docs.git] / i386 / linux-2.3.21 / drivers / scsi / aha1740.c
blob96812a0ec9f0c0fda3cec542913777afa79eb50b
1 /* $Id$
2 * 1993/03/31
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
12 * Modifications to makecode and queuecommand
13 * for proper handling of multiple devices courteously
14 * provided by Michael Weller, March, 1993
16 * Multiple adapter support, extended translation detection,
17 * update to current scsi subsystem changes, proc fs support,
18 * working (!) module support based on patches from Andreas Arens,
19 * by Andreas Degert <ad@papyrus.hamburg.com>, 2/1997
21 * aha1740_makecode may still need even more work
22 * if it doesn't work for your devices, take a look.
25 #ifdef MODULE
26 #include <linux/module.h>
27 #endif
29 #include <linux/kernel.h>
30 #include <linux/types.h>
31 #include <linux/string.h>
32 #include <linux/ioport.h>
33 #include <linux/proc_fs.h>
34 #include <linux/sched.h>
35 #include <asm/dma.h>
37 #include <asm/system.h>
38 #include <asm/io.h>
39 #include <linux/blk.h>
40 #include "scsi.h"
41 #include "hosts.h"
42 #include "sd.h"
44 #include "aha1740.h"
45 #include<linux/stat.h>
47 struct proc_dir_entry proc_scsi_aha1740 = {
48 PROC_SCSI_AHA1740, 7, "aha1740",
49 S_IFDIR | S_IRUGO | S_IXUGO, 2
52 /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
53 IT WORK, THEN:
54 #define DEBUG
56 #ifdef DEBUG
57 #define DEB(x) x
58 #else
59 #define DEB(x)
60 #endif
63 static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/aha1740.c,v 1.1 1992/07/24 06:27:38 root Exp root $";
66 struct aha1740_hostdata {
67 unsigned int slot;
68 unsigned int translation;
69 unsigned int last_ecb_used;
70 struct ecb ecb[AHA1740_ECBS];
73 #define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata)
75 /* One for each IRQ level (9-15) */
76 static struct Scsi_Host * aha_host[8] = {NULL, };
78 int aha1740_proc_info(char *buffer, char **start, off_t offset,
79 int length, int hostno, int inout)
81 int len;
82 struct Scsi_Host * shpnt;
83 struct aha1740_hostdata *host;
85 if (inout)
86 return(-ENOSYS);
88 for (len = 0; len < 8; len++) {
89 shpnt = aha_host[len];
90 if (shpnt && shpnt->host_no == hostno)
91 break;
93 host = HOSTDATA(shpnt);
95 len = sprintf(buffer, "aha174x at IO:%lx, IRQ %d, SLOT %d.\n"
96 "Extended translation %sabled.\n",
97 shpnt->io_port, shpnt->irq, host->slot,
98 host->translation ? "en" : "dis");
100 if (offset > len) {
101 *start = buffer;
102 return 0;
105 *start = buffer + offset;
106 len -= offset;
107 if (len > length)
108 len = length;
109 return len;
113 int aha1740_makecode(unchar *sense, unchar *status)
115 struct statusword
117 ushort don:1, /* Command Done - No Error */
118 du:1, /* Data underrun */
119 :1, qf:1, /* Queue full */
120 sc:1, /* Specification Check */
121 dor:1, /* Data overrun */
122 ch:1, /* Chaining Halted */
123 intr:1, /* Interrupt issued */
124 asa:1, /* Additional Status Available */
125 sns:1, /* Sense information Stored */
126 :1, ini:1, /* Initialization Required */
127 me:1, /* Major error or exception */
128 :1, eca:1, /* Extended Contingent alliance */
130 } status_word;
131 int retval = DID_OK;
133 status_word = * (struct statusword *) status;
134 #ifdef DEBUG
135 printk("makecode from %x,%x,%x,%x %x,%x,%x,%x",
136 status[0], status[1], status[2], status[3],
137 sense[0], sense[1], sense[2], sense[3]);
138 #endif
139 if (!status_word.don) /* Anything abnormal was detected */
141 if ( (status[1]&0x18) || status_word.sc ) /*Additional info available*/
143 /* Use the supplied info for further diagnostics */
144 switch ( status[2] )
146 case 0x12:
147 if ( status_word.dor )
148 retval=DID_ERROR; /* It's an Overrun */
149 /* If not overrun, assume underrun and ignore it! */
150 case 0x00: /* No info, assume no error, should not occur */
151 break;
152 case 0x11:
153 case 0x21:
154 retval=DID_TIME_OUT;
155 break;
156 case 0x0a:
157 retval=DID_BAD_TARGET;
158 break;
159 case 0x04:
160 case 0x05:
161 retval=DID_ABORT;
162 /* Either by this driver or the AHA1740 itself */
163 break;
164 default:
165 retval=DID_ERROR; /* No further diagnostics possible */
168 else
169 { /* Michael suggests, and Brad concurs: */
170 if ( status_word.qf )
172 retval = DID_TIME_OUT; /* forces a redo */
173 /* I think this specific one should not happen -Brad */
174 printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
176 else if ( status[0]&0x60 )
178 retval = DID_ERROR; /* Didn't find a better error */
180 /* In any other case return DID_OK so for example
181 CONDITION_CHECKS make it through to the appropriate
182 device driver */
185 /* Under all circumstances supply the target status -Michael */
186 return status[3] | retval << 16;
189 int aha1740_test_port(unsigned int base)
191 char name[4], tmp;
193 /* Okay, look for the EISA ID's */
194 name[0]= 'A' -1 + ((tmp = inb(HID0(base))) >> 2); /* First character */
195 name[1]= 'A' -1 + ((tmp & 3) << 3);
196 name[1]+= ((tmp = inb(HID1(base))) >> 5)&0x7; /* Second Character */
197 name[2]= 'A' -1 + (tmp & 0x1f); /* Third Character */
198 name[3]=0;
199 tmp = inb(HID2(base));
200 if ( strcmp ( name, HID_MFG ) || inb(HID2(base)) != HID_PRD )
201 return 0; /* Not an Adaptec 174x */
203 /* if ( inb(HID3(base)) != HID_REV )
204 printk("aha174x: Warning; board revision of %d; expected %d\n",
205 inb(HID3(base)),HID_REV); */
207 if ( inb(EBCNTRL(base)) != EBCNTRL_VALUE )
209 printk("aha174x: Board detected, but EBCNTRL = %x, so disabled it.\n",
210 inb(EBCNTRL(base)));
211 return 0;
214 if ( inb(PORTADR(base)) & PORTADDR_ENH )
215 return 1; /* Okay, we're all set */
217 printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n");
218 return 0;
221 /* A "high" level interrupt handler */
222 void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
224 void (*my_done)(Scsi_Cmnd *);
225 int errstatus, adapstat;
226 int number_serviced;
227 struct ecb *ecbptr;
228 Scsi_Cmnd *SCtmp;
229 unsigned int base;
230 unsigned long flags;
232 spin_lock_irqsave(&io_request_lock, flags);
234 if (!aha_host[irq - 9])
235 panic("aha1740.c: Irq from unknown host!\n");
236 base = aha_host[irq - 9]->io_port;
237 number_serviced = 0;
239 while(inb(G2STAT(base)) & G2STAT_INTPEND)
241 DEB(printk("aha1740_intr top of loop.\n"));
242 adapstat = inb(G2INTST(base));
243 ecbptr = (struct ecb *) bus_to_virt(inl(MBOXIN0(base)));
244 outb(G2CNTRL_IRST,G2CNTRL(base)); /* interrupt reset */
246 switch ( adapstat & G2INTST_MASK )
248 case G2INTST_CCBRETRY:
249 case G2INTST_CCBERROR:
250 case G2INTST_CCBGOOD:
251 /* Host Ready -> Mailbox in complete */
252 outb(G2CNTRL_HRDY,G2CNTRL(base));
253 if (!ecbptr)
255 printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
256 inb(G2STAT(base)),adapstat,
257 inb(G2INTST(base)), number_serviced++);
258 continue;
260 SCtmp = ecbptr->SCpnt;
261 if (!SCtmp)
263 printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
264 inb(G2STAT(base)),adapstat,
265 inb(G2INTST(base)), number_serviced++);
266 continue;
268 if (SCtmp->host_scribble)
269 scsi_free(SCtmp->host_scribble, 512);
270 /* Fetch the sense data, and tuck it away, in the required slot.
271 The Adaptec automatically fetches it, and there is no
272 guarantee that we will still have it in the cdb when we come
273 back */
274 if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR )
276 memcpy(SCtmp->sense_buffer, ecbptr->sense,
277 sizeof(SCtmp->sense_buffer));
278 errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
280 else
281 errstatus = 0;
282 DEB(if (errstatus) printk("aha1740_intr_handle: returning %6x\n",
283 errstatus));
284 SCtmp->result = errstatus;
285 my_done = ecbptr->done;
286 memset(ecbptr,0,sizeof(struct ecb));
287 if ( my_done )
288 my_done(SCtmp);
289 break;
290 case G2INTST_HARDFAIL:
291 printk(KERN_ALERT "aha1740 hardware failure!\n");
292 panic("aha1740.c"); /* Goodbye */
293 case G2INTST_ASNEVENT:
294 printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
295 adapstat, inb(MBOXIN0(base)), inb(MBOXIN1(base)),
296 inb(MBOXIN2(base)), inb(MBOXIN3(base))); /* Say What? */
297 /* Host Ready -> Mailbox in complete */
298 outb(G2CNTRL_HRDY,G2CNTRL(base));
299 break;
300 case G2INTST_CMDGOOD:
301 /* set immediate command success flag here: */
302 break;
303 case G2INTST_CMDERROR:
304 /* Set immediate command failure flag here: */
305 break;
307 number_serviced++;
310 spin_unlock_irqrestore(&io_request_lock, flags);
313 int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
315 unchar direction;
316 unchar *cmd = (unchar *) SCpnt->cmnd;
317 unchar target = SCpnt->target;
318 struct aha1740_hostdata *host = HOSTDATA(SCpnt->host);
319 unsigned long flags;
320 void *buff = SCpnt->request_buffer;
321 int bufflen = SCpnt->request_bufflen;
322 int ecbno;
323 DEB(int i);
325 if(*cmd == REQUEST_SENSE)
327 if (bufflen != sizeof(SCpnt->sense_buffer))
329 printk("Wrong buffer length supplied for request sense (%d)\n",
330 bufflen);
332 SCpnt->result = 0;
333 done(SCpnt);
334 return 0;
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
351 /* locate an available ecb */
352 save_flags(flags);
353 cli();
354 ecbno = host->last_ecb_used + 1; /* An optimization */
355 if (ecbno >= AHA1740_ECBS)
356 ecbno = 0;
357 do {
358 if (!host->ecb[ecbno].cmdw)
359 break;
360 ecbno++;
361 if (ecbno >= AHA1740_ECBS)
362 ecbno = 0;
363 } while (ecbno != host->last_ecb_used);
365 if (host->ecb[ecbno].cmdw)
366 panic("Unable to find empty ecb for aha1740.\n");
368 host->ecb[ecbno].cmdw = AHA1740CMD_INIT; /* SCSI Initiator Command
369 doubles as reserved flag */
371 host->last_ecb_used = ecbno;
372 restore_flags(flags);
374 #ifdef DEBUG
375 printk("Sending command (%d %x)...", ecbno, done);
376 #endif
378 host->ecb[ecbno].cdblen = SCpnt->cmd_len; /* SCSI Command Descriptor Block Length */
380 direction = 0;
381 if (*cmd == READ_10 || *cmd == READ_6)
382 direction = 1;
383 else if (*cmd == WRITE_10 || *cmd == WRITE_6)
384 direction = 0;
386 memcpy(host->ecb[ecbno].cdb, cmd, SCpnt->cmd_len);
388 if (SCpnt->use_sg)
390 struct scatterlist * sgpnt;
391 struct aha1740_chain * cptr;
392 int i;
393 DEB(unsigned char * ptr);
395 host->ecb[ecbno].sg = 1; /* SCSI Initiator Command w/scatter-gather*/
396 SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
397 sgpnt = (struct scatterlist *) SCpnt->request_buffer;
398 cptr = (struct aha1740_chain *) SCpnt->host_scribble;
399 if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
400 for(i=0; i<SCpnt->use_sg; i++)
402 cptr[i].datalen = sgpnt[i].length;
403 cptr[i].dataptr = virt_to_bus(sgpnt[i].address);
405 host->ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain);
406 host->ecb[ecbno].dataptr = virt_to_bus(cptr);
407 #ifdef DEBUG
408 printk("cptr %x: ",cptr);
409 ptr = (unsigned char *) cptr;
410 for(i=0;i<24;i++) printk("%02x ", ptr[i]);
411 #endif
413 else
415 SCpnt->host_scribble = NULL;
416 host->ecb[ecbno].datalen = bufflen;
417 host->ecb[ecbno].dataptr = virt_to_bus(buff);
419 host->ecb[ecbno].lun = SCpnt->lun;
420 host->ecb[ecbno].ses = 1; /* Suppress underrun errors */
421 host->ecb[ecbno].dir = direction;
422 host->ecb[ecbno].ars = 1; /* Yes, get the sense on an error */
423 host->ecb[ecbno].senselen = 12;
424 host->ecb[ecbno].senseptr = virt_to_bus(host->ecb[ecbno].sense);
425 host->ecb[ecbno].statusptr = virt_to_bus(host->ecb[ecbno].status);
426 host->ecb[ecbno].done = done;
427 host->ecb[ecbno].SCpnt = SCpnt;
428 #ifdef DEBUG
430 int i;
431 printk("aha1740_command: sending.. ");
432 for (i = 0; i < sizeof(host->ecb[ecbno]) - 10; i++)
433 printk("%02x ", ((unchar *)&host->ecb[ecbno])[i]);
435 printk("\n");
436 #endif
437 if (done)
438 { /* The Adaptec Spec says the card is so fast that the loops will
439 only be executed once in the code below. Even if this was true
440 with the fastest processors when the spec was written, it doesn't
441 seem to be true with todays fast processors. We print a warning
442 if the code is executed more often than LOOPCNT_WARN. If this
443 happens, it should be investigated. If the count reaches
444 LOOPCNT_MAX, we assume something is broken; since there is no
445 way to return an error (the return value is ignored by the
446 mid-level scsi layer) we have to panic (and maybe that's the
447 best thing we can do then anyhow). */
449 #define LOOPCNT_WARN 10 /* excessive mbxout wait -> syslog-msg */
450 #define LOOPCNT_MAX 1000000 /* mbxout deadlock -> panic() after ~ 2 sec. */
451 int loopcnt;
452 unsigned int base = SCpnt->host->io_port;
453 DEB(printk("aha1740[%d] critical section\n",ecbno));
454 save_flags(flags);
455 cli();
456 for (loopcnt = 0; ; loopcnt++) {
457 if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
458 if (loopcnt == LOOPCNT_WARN) {
459 printk("aha1740[%d]_mbxout wait!\n",ecbno);
460 cli(); /* printk may have done a sti()! */
462 if (loopcnt == LOOPCNT_MAX)
463 panic("aha1740.c: mbxout busy!\n");
465 outl(virt_to_bus(host->ecb + ecbno), MBOXOUT0(base));
466 for (loopcnt = 0; ; loopcnt++) {
467 if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break;
468 if (loopcnt == LOOPCNT_WARN) {
469 printk("aha1740[%d]_attn wait!\n",ecbno);
470 cli();
472 if (loopcnt == LOOPCNT_MAX)
473 panic("aha1740.c: attn wait failed!\n");
475 outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
476 restore_flags(flags);
477 DEB(printk("aha1740[%d] request queued.\n",ecbno));
479 else
480 printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
481 return 0;
484 static void internal_done(Scsi_Cmnd * SCpnt)
486 SCpnt->SCp.Status++;
489 int aha1740_command(Scsi_Cmnd * SCpnt)
491 aha1740_queuecommand(SCpnt, internal_done);
492 SCpnt->SCp.Status = 0;
493 while (!SCpnt->SCp.Status)
494 barrier();
495 return SCpnt->result;
498 /* Query the board for its irq_level. Nothing else matters
499 in enhanced mode on an EISA bus. */
501 void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
502 unsigned int *translation)
504 static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
506 *irq_level = intab[inb(INTDEF(base)) & 0x7];
507 *translation = inb(RESV1(base)) & 0x1;
508 outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
511 int aha1740_detect(Scsi_Host_Template * tpnt)
513 int count = 0, slot;
515 DEB(printk("aha1740_detect: \n"));
517 for ( slot=MINEISA; slot <= MAXEISA; slot++ )
519 int slotbase;
520 unsigned int irq_level, translation;
521 struct Scsi_Host *shpnt;
522 struct aha1740_hostdata *host;
523 slotbase = SLOTBASE(slot);
525 * The ioports for eisa boards are generally beyond that used in the
526 * check/allocate region code, but this may change at some point,
527 * so we go through the motions.
529 if (check_region(slotbase, SLOTSIZE)) /* See if in use */
530 continue;
531 if (!aha1740_test_port(slotbase))
532 continue;
533 aha1740_getconfig(slotbase,&irq_level,&translation);
534 if ((inb(G2STAT(slotbase)) &
535 (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT)
536 { /* If the card isn't ready, hard reset it */
537 outb(G2CNTRL_HRST, G2CNTRL(slotbase));
538 outb(0, G2CNTRL(slotbase));
540 printk("Configuring aha174x at IO:%x, IRQ %d\n", slotbase, irq_level);
541 printk("aha174x: Extended translation %sabled.\n",
542 translation ? "en" : "dis");
543 DEB(printk("aha1740_detect: enable interrupt channel %d\n",irq_level));
544 if (request_irq(irq_level,aha1740_intr_handle,0,"aha1740",NULL)) {
545 printk("Unable to allocate IRQ for adaptec controller.\n");
546 continue;
548 shpnt = scsi_register(tpnt, sizeof(struct aha1740_hostdata));
549 request_region(slotbase, SLOTSIZE, "aha1740");
550 shpnt->base = 0;
551 shpnt->io_port = slotbase;
552 shpnt->n_io_port = SLOTSIZE;
553 shpnt->irq = irq_level;
554 shpnt->dma_channel = 0xff;
555 host = HOSTDATA(shpnt);
556 host->slot = slot;
557 host->translation = translation;
558 aha_host[irq_level - 9] = shpnt;
559 count++;
561 return count;
564 /* Note: They following two functions do not apply very well to the Adaptec,
565 which basically manages its own affairs quite well without our interference,
566 so I haven't put anything into them. I can faintly imagine someone with a
567 *very* badly behaved SCSI target (perhaps an old tape?) wanting the abort(),
568 but it hasn't happened yet, and doing aborts brings the Adaptec to its
569 knees. I cannot (at this moment in time) think of any reason to reset the
570 card once it's running. So there. */
572 int aha1740_abort(Scsi_Cmnd * SCpnt)
574 DEB(printk("aha1740_abort called\n"));
575 return SCSI_ABORT_SNOOZE;
578 /* We do not implement a reset function here, but the upper level code assumes
579 that it will get some kind of response for the command in SCpnt. We must
580 oblige, or the command will hang the scsi system */
582 int aha1740_reset(Scsi_Cmnd * SCpnt, unsigned int ignored)
584 DEB(printk("aha1740_reset called\n"));
585 return SCSI_RESET_PUNT;
588 int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip)
590 int size = disk->capacity;
591 int extended = HOSTDATA(disk->device->host)->translation;
593 DEB(printk("aha1740_biosparam\n"));
594 if (extended && (ip[2] > 1024))
596 ip[0] = 255;
597 ip[1] = 63;
598 ip[2] = size / (255 * 63);
600 else
602 ip[0] = 64;
603 ip[1] = 32;
604 ip[2] = size >> 11;
606 return 0;
609 #ifdef MODULE
610 /* Eventually this will go into an include file, but this will be later */
611 Scsi_Host_Template driver_template = AHA1740;
613 #include "scsi_module.c"
614 #endif
616 /* Okay, you made it all the way through. As of this writing, 3/31/93, I'm
617 brad@saturn.gaylord.com or brad@bradpc.gaylord.com. I'll try to help as time
618 permits if you have any trouble with this driver. Happy Linuxing! */