|
|
1.1 root 1: /* $Id: aha1740.c,v 1.2 1997/03/24 21:51:17 thomas Exp $
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: *
12: * Modifications to makecode and queuecommand
13: * for proper handling of multiple devices courteously
14: * provided by Michael Weller, March, 1993
15: *
16: * aha1740_makecode may still need even more work
17: * if it doesn't work for your devices, take a look.
18: */
19:
20: #ifdef MODULE
21: #include <linux/module.h>
22: #endif
23:
24: #include <linux/kernel.h>
25: #include <linux/head.h>
26: #include <linux/types.h>
27: #include <linux/string.h>
28: #include <linux/ioport.h>
29: #include <linux/proc_fs.h>
30: #include <linux/sched.h>
31: #include <asm/dma.h>
32:
33: #include <asm/system.h>
34: #include <asm/io.h>
35: #include <linux/blk.h>
36: #include "scsi.h"
37: #include "hosts.h"
38: #include "sd.h"
39:
40: #include "aha1740.h"
41: #include<linux/stat.h>
42:
43: struct proc_dir_entry proc_scsi_aha1740 = {
44: PROC_SCSI_AHA1740, 7, "aha1740",
45: S_IFDIR | S_IRUGO | S_IXUGO, 2
46: };
47:
48: /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
49: IT WORK, THEN:
50: #define DEBUG
51: */
52: #ifdef DEBUG
53: #define DEB(x) x
54: #else
55: #define DEB(x)
56: #endif
57:
58: /*
59: static const char RCSid[] = "$Header: /gd4/gnu/cvsroot/gnumach/i386/i386at/gpl/linux/scsi/aha1740.c,v 1.2 1997/03/24 21:51:17 thomas Exp $";
60: */
61:
62: static unsigned int slot, base;
63: static unsigned char irq_level;
64:
65: static struct ecb ecb[AHA1740_ECBS]; /* One for each queued operation */
66:
67: static int aha1740_last_ecb_used = 0; /* optimization */
68:
69: int aha1740_makecode(unchar *sense, unchar *status)
70: {
71: struct statusword
72: {
73: ushort don:1, /* Command Done - No Error */
74: du:1, /* Data underrun */
75: :1, qf:1, /* Queue full */
76: sc:1, /* Specification Check */
77: dor:1, /* Data overrun */
78: ch:1, /* Chaining Halted */
79: intr:1, /* Interrupt issued */
80: asa:1, /* Additional Status Available */
81: sns:1, /* Sense information Stored */
82: :1, ini:1, /* Initialization Required */
83: me:1, /* Major error or exception */
84: :1, eca:1, /* Extended Contingent alliance */
85: :1;
86: } status_word;
87: int retval = DID_OK;
88:
89: status_word = * (struct statusword *) status;
90: #ifdef DEBUG
91: printk("makecode from %x,%x,%x,%x %x,%x,%x,%x",status[0],status[1],status[2],status[3],
92: sense[0],sense[1],sense[2],sense[3]);
93: #endif
94: if (!status_word.don) /* Anything abnormal was detected */
95: {
96: if ( (status[1]&0x18) || status_word.sc ) /*Additional info available*/
97: {
98: /* Use the supplied info for further diagnostics */
99: switch ( status[2] )
100: {
101: case 0x12:
102: if ( status_word.dor )
103: retval=DID_ERROR; /* It's an Overrun */
104: /* If not overrun, assume underrun and ignore it! */
105: case 0x00: /* No info, assume no error, should not occur */
106: break;
107: case 0x11:
108: case 0x21:
109: retval=DID_TIME_OUT;
110: break;
111: case 0x0a:
112: retval=DID_BAD_TARGET;
113: break;
114: case 0x04:
115: case 0x05:
116: retval=DID_ABORT; /* Either by this driver or the AHA1740
117: itself */
118: break;
119: default:
120: retval=DID_ERROR; /* No further diagnostics possible */
121: }
122: }
123: else
124: { /* Michael suggests, and Brad concurs: */
125: if ( status_word.qf )
126: {
127: retval = DID_TIME_OUT; /* forces a redo */
128: /* I think this specific one should not happen -Brad */
129: printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
130: }
131: else if ( status[0]&0x60 )
132: {
133: retval = DID_ERROR; /* Didn't find a better error */
134: }
135: /* In any other case return DID_OK so for example
136: CONDITION_CHECKS make it through to the appropriate
137: device driver */
138: }
139: }
140: /* Under all circumstances supply the target status -Michael */
141: return status[3] | retval << 16;
142: }
143:
144: int aha1740_test_port(void)
145: {
146: char name[4],tmp;
147:
148: /* Okay, look for the EISA ID's */
149: name[0]= 'A' -1 + ((tmp = inb(HID0)) >> 2); /* First character */
150: name[1]= 'A' -1 + ((tmp & 3) << 3);
151: name[1]+= ((tmp = inb(HID1)) >> 5)&0x7; /* Second Character */
152: name[2]= 'A' -1 + (tmp & 0x1f); /* Third Character */
153: name[3]=0;
154: tmp = inb(HID2);
155: if ( strcmp ( name, HID_MFG ) || inb(HID2) != HID_PRD )
156: return 0; /* Not an Adaptec 174x */
157:
158: /* if ( inb(HID3) != HID_REV )
159: printk("aha1740: Warning; board revision of %d; expected %d\n",
160: inb(HID3),HID_REV); */
161:
162: if ( inb(EBCNTRL) != EBCNTRL_VALUE )
163: {
164: printk("aha1740: Board detected, but EBCNTRL = %x, so disabled it.\n",
165: inb(EBCNTRL));
166: return 0;
167: }
168:
169: /* Try and turn on enhanced mode */
170: tmp = inb (PORTADR);
171: outb (PORTADR, tmp | PORTADDR_ENH);
172: if ( inb(PORTADR) & PORTADDR_ENH )
173: return 1; /* Okay, we're all set */
174:
175: printk("aha1740: Board detected, but not in enhanced mode, so disabled it.\n");
176: return 0;
177: }
178:
179: /* A "high" level interrupt handler */
180: void aha1740_intr_handle(int irq, struct pt_regs * regs)
181: {
182: void (*my_done)(Scsi_Cmnd *);
183: int errstatus, adapstat;
184: int number_serviced;
185: struct ecb *ecbptr;
186: Scsi_Cmnd *SCtmp;
187:
188: number_serviced = 0;
189:
190: while(inb(G2STAT) & G2STAT_INTPEND)
191: {
192: DEB(printk("aha1740_intr top of loop.\n"));
193: adapstat = inb(G2INTST);
194: ecbptr = (struct ecb *) bus_to_virt(inl(MBOXIN0));
195: outb(G2CNTRL_IRST,G2CNTRL); /* interrupt reset */
196:
197: switch ( adapstat & G2INTST_MASK )
198: {
199: case G2INTST_CCBRETRY:
200: case G2INTST_CCBERROR:
201: case G2INTST_CCBGOOD:
202: outb(G2CNTRL_HRDY,G2CNTRL); /* Host Ready -> Mailbox in complete */
203: if (!ecbptr)
204: {
205: printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
206: inb(G2STAT),adapstat,inb(G2INTST),number_serviced++);
207: continue;
208: }
209: SCtmp = ecbptr->SCpnt;
210: if (!SCtmp)
211: {
212: printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
213: inb(G2STAT),adapstat,inb(G2INTST),number_serviced++);
214: continue;
215: }
216: if (SCtmp->host_scribble)
217: scsi_free(SCtmp->host_scribble, 512);
218: /* Fetch the sense data, and tuck it away, in the required slot. The
219: Adaptec automatically fetches it, and there is no guarantee that
220: we will still have it in the cdb when we come back */
221: if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR )
222: {
223: memcpy(SCtmp->sense_buffer, ecbptr->sense,
224: sizeof(SCtmp->sense_buffer));
225: errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
226: }
227: else
228: errstatus = 0;
229: DEB(if (errstatus) printk("aha1740_intr_handle: returning %6x\n", errstatus));
230: SCtmp->result = errstatus;
231: my_done = ecbptr->done;
232: memset(ecbptr,0,sizeof(struct ecb));
233: if ( my_done )
234: my_done(SCtmp);
235: break;
236: case G2INTST_HARDFAIL:
237: printk("aha1740 hardware failure!\n");
238: panic("aha1740.c"); /* Goodbye */
239: case G2INTST_ASNEVENT:
240: printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",adapstat,
241: inb(MBOXIN0),inb(MBOXIN1),inb(MBOXIN2),inb(MBOXIN3)); /* Say What? */
242: outb(G2CNTRL_HRDY,G2CNTRL); /* Host Ready -> Mailbox in complete */
243: break;
244: case G2INTST_CMDGOOD:
245: /* set immediate command success flag here: */
246: break;
247: case G2INTST_CMDERROR:
248: /* Set immediate command failure flag here: */
249: break;
250: }
251: number_serviced++;
252: }
253: }
254:
255: int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
256: {
257: unchar direction;
258: unchar *cmd = (unchar *) SCpnt->cmnd;
259: unchar target = SCpnt->target;
260: unsigned long flags;
261: void *buff = SCpnt->request_buffer;
262: int bufflen = SCpnt->request_bufflen;
263: int ecbno;
264: DEB(int i);
265:
266:
267: if(*cmd == REQUEST_SENSE)
268: {
269: if (bufflen != sizeof(SCpnt->sense_buffer))
270: {
271: printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
272: }
273: SCpnt->result = 0;
274: done(SCpnt);
275: return 0;
276: }
277:
278: #ifdef DEBUG
279: if (*cmd == READ_10 || *cmd == WRITE_10)
280: i = xscsi2int(cmd+2);
281: else if (*cmd == READ_6 || *cmd == WRITE_6)
282: i = scsi2int(cmd+2);
283: else
284: i = -1;
285: printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
286: printk("scsi cmd:");
287: for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
288: printk("\n");
289: #endif
290:
291: /* locate an available ecb */
292:
293: save_flags(flags);
294: cli();
295: ecbno = aha1740_last_ecb_used + 1; /* An optimization */
296: if (ecbno >= AHA1740_ECBS) ecbno = 0;
297:
298: do{
299: if( ! ecb[ecbno].cmdw )
300: break;
301: ecbno++;
302: if (ecbno >= AHA1740_ECBS ) ecbno = 0;
303: } while (ecbno != aha1740_last_ecb_used);
304:
305: if( ecb[ecbno].cmdw )
306: panic("Unable to find empty ecb for aha1740.\n");
307:
308: ecb[ecbno].cmdw = AHA1740CMD_INIT; /* SCSI Initiator Command doubles as reserved flag */
309:
310: aha1740_last_ecb_used = ecbno;
311: restore_flags(flags);
312:
313: #ifdef DEBUG
314: printk("Sending command (%d %x)...",ecbno, done);
315: #endif
316:
317: ecb[ecbno].cdblen = SCpnt->cmd_len; /* SCSI Command Descriptor Block Length */
318:
319: direction = 0;
320: if (*cmd == READ_10 || *cmd == READ_6)
321: direction = 1;
322: else if (*cmd == WRITE_10 || *cmd == WRITE_6)
323: direction = 0;
324:
325: memcpy(ecb[ecbno].cdb, cmd, ecb[ecbno].cdblen);
326:
327: if (SCpnt->use_sg)
328: {
329: struct scatterlist * sgpnt;
330: struct aha1740_chain * cptr;
331: int i;
332: #ifdef DEBUG
333: unsigned char * ptr;
334: #endif
335: ecb[ecbno].sg = 1; /* SCSI Initiator Command w/scatter-gather*/
336: SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
337: sgpnt = (struct scatterlist *) SCpnt->request_buffer;
338: cptr = (struct aha1740_chain *) SCpnt->host_scribble;
339: if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
340: for(i=0; i<SCpnt->use_sg; i++)
341: {
342: cptr[i].dataptr = (long) sgpnt[i].address;
343: cptr[i].datalen = sgpnt[i].length;
344: }
345: ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain);
346: ecb[ecbno].dataptr = (long) cptr;
347: #ifdef DEBUG
348: printk("cptr %x: ",cptr);
349: ptr = (unsigned char *) cptr;
350: for(i=0;i<24;i++) printk("%02x ", ptr[i]);
351: #endif
352: }
353: else
354: {
355: SCpnt->host_scribble = NULL;
356: ecb[ecbno].datalen = bufflen;
357: ecb[ecbno].dataptr = (long) buff;
358: }
359: ecb[ecbno].lun = SCpnt->lun;
360: ecb[ecbno].ses = 1; /* Suppress underrun errors */
361: ecb[ecbno].dir= direction;
362: ecb[ecbno].ars=1; /* Yes, get the sense on an error */
363: ecb[ecbno].senselen = 12;
364: ecb[ecbno].senseptr = (long) ecb[ecbno].sense;
365: ecb[ecbno].statusptr = (long) ecb[ecbno].status;
366: ecb[ecbno].done = done;
367: ecb[ecbno].SCpnt = SCpnt;
368: #ifdef DEBUG
369: {
370: int i;
371: printk("aha1740_command: sending.. ");
372: for (i = 0; i < sizeof(ecb[ecbno])-10; i++)
373: printk("%02x ", ((unchar *)&ecb[ecbno])[i]);
374: }
375: printk("\n");
376: #endif
377: if (done)
378: { /* You may question the code below, which contains potentially
379: non-terminating while loops with interrupts disabled. So did
380: I when I wrote it, but the Adaptec Spec says the card is so fast,
381: that this problem virtually never occurs so I've kept it. We
382: do printk a warning first, so that you'll know if it happens.
383: In practice the only time we've seen this message is when some-
384: thing else is in the driver was broken, like _makecode(), or
385: when a scsi device hung the scsi bus. Even under these conditions,
386: The loop actually only cycled < 3 times (we instrumented it). */
387:
388: DEB(printk("aha1740[%d] critical section\n",ecbno));
389: save_flags(flags);
390: cli();
391: if ( ! (inb(G2STAT) & G2STAT_MBXOUT) )
392: {
393: printk("aha1740[%d]_mbxout wait!\n",ecbno);
394: cli(); /* printk may have done a sti()! */
395: }
396: mb();
397: while ( ! (inb(G2STAT) & G2STAT_MBXOUT) ); /* Oh Well. */
398: outl(virt_to_bus(ecb+ecbno), MBOXOUT0);
399: if ( inb(G2STAT) & G2STAT_BUSY )
400: {
401: printk("aha1740[%d]_attn wait!\n",ecbno);
402: cli();
403: }
404: while ( inb(G2STAT) & G2STAT_BUSY ); /* And Again! */
405: outb(ATTN_START | (target & 7), ATTN); /* Start it up */
406: restore_flags(flags);
407: DEB(printk("aha1740[%d] request queued.\n",ecbno));
408: }
409: else
410: printk("aha1740_queuecommand: done can't be NULL\n");
411:
412: return 0;
413: }
414:
415: static volatile int internal_done_flag = 0;
416: static volatile int internal_done_errcode = 0;
417:
418: static void internal_done(Scsi_Cmnd * SCpnt)
419: {
420: internal_done_errcode = SCpnt->result;
421: ++internal_done_flag;
422: }
423:
424: int aha1740_command(Scsi_Cmnd * SCpnt)
425: {
426: aha1740_queuecommand(SCpnt, internal_done);
427:
428: while (!internal_done_flag);
429: internal_done_flag = 0;
430: return internal_done_errcode;
431: }
432:
433: /* Query the board for its irq_level. Nothing else matters
434: in enhanced mode on an EISA bus. */
435:
436: void aha1740_getconfig(void)
437: {
438: static int intab[] = { 9,10,11,12,0,14,15,0 };
439:
440: irq_level = intab [ inb(INTDEF)&0x7 ];
441: outb(inb(INTDEF) | 0x10, INTDEF);
442: }
443:
444: int aha1740_detect(Scsi_Host_Template * tpnt)
445: {
446: tpnt->proc_dir = &proc_scsi_aha1740;
447:
448: memset(&ecb, 0, sizeof(struct ecb));
449: DEB(printk("aha1740_detect: \n"));
450:
451: for ( slot=MINEISA; slot <= MAXEISA; slot++ )
452: {
453: base = SLOTBASE(slot);
454: /*
455: * The ioports for eisa boards are generally beyond that used in the
456: * check/allocate region code, but this may change at some point,
457: * so we go through the motions.
458: */
459: if(check_region(base, 0x5c)) continue; /* See if in use */
460: if ( aha1740_test_port()) break;
461: }
462: if ( slot > MAXEISA )
463: return 0;
464:
465: aha1740_getconfig();
466:
467: if ( (inb(G2STAT) & (G2STAT_MBXOUT | G2STAT_BUSY) ) != G2STAT_MBXOUT )
468: { /* If the card isn't ready, hard reset it */
469: outb(G2CNTRL_HRST,G2CNTRL);
470: outb(0,G2CNTRL);
471: }
472:
473: printk("Configuring Adaptec at IO:%x, IRQ %d\n",base,
474: irq_level);
475:
476: DEB(printk("aha1740_detect: enable interrupt channel %d\n", irq_level));
477:
478: if (request_irq(irq_level,aha1740_intr_handle, 0, "aha1740"))
479: {
480: printk("Unable to allocate IRQ for adaptec controller.\n");
481: return 0;
482: }
483: request_region(base, 0x5c,"aha1740"); /* Reserve the space that we need to use */
484: return 1;
485: }
486:
487: /* Note: They following two functions do not apply very well to the Adaptec,
488: which basically manages its own affairs quite well without our interference,
489: so I haven't put anything into them. I can faintly imagine someone with a
490: *very* badly behaved SCSI target (perhaps an old tape?) wanting the abort(),
491: but it hasn't happened yet, and doing aborts brings the Adaptec to its
492: knees. I cannot (at this moment in time) think of any reason to reset the
493: card once it's running. So there. */
494:
495: int aha1740_abort(Scsi_Cmnd * SCpnt)
496: {
497: DEB(printk("aha1740_abort called\n"));
498: return SCSI_ABORT_SNOOZE;
499: }
500:
501: /* We do not implement a reset function here, but the upper level code assumes
502: that it will get some kind of response for the command in SCpnt. We must
503: oblige, or the command will hang the scsi system */
504:
505: int aha1740_reset(Scsi_Cmnd * SCpnt)
506: {
507: DEB(printk("aha1740_reset called\n"));
508: return SCSI_RESET_PUNT;
509: }
510:
511: int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip)
512: {
513: int size = disk->capacity;
514: DEB(printk("aha1740_biosparam\n"));
515: ip[0] = 64;
516: ip[1] = 32;
517: ip[2] = size >> 11;
518: /* if (ip[2] >= 1024) ip[2] = 1024; */
519: return 0;
520: }
521:
522: #ifdef MODULE
523: /* Eventually this will go into an include file, but this will be later */
524: Scsi_Host_Template driver_template = AHA1740;
525:
526: #include "scsi_module.c"
527: #endif
528:
529: /* Okay, you made it all the way through. As of this writing, 3/31/93, I'm
530: [email protected] or [email protected]. I'll try to help as time
531: permits if you have any trouble with this driver. Happy Linuxing! */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.