This source file includes following definitions.
- aha1542_stat
- aha1542_out
- aha1542_in
- aha1542_in1
- makecode
- aha1542_test_port
- aha1542_intr_handle
- aha1542_queuecommand
- internal_done
- aha1542_command
- setup_mailboxes
- aha1542_getconfig
- aha1542_mbenable
- aha1542_query
- aha1542_setup
- aha1542_detect
- aha1542_restart
- aha1542_abort
- aha1542_reset
- aha1542_biosparam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #ifdef MODULE
19 #include <linux/autoconf.h>
20 #include <linux/module.h>
21 #endif
22
23 #include <linux/kernel.h>
24 #include <linux/head.h>
25 #include <linux/types.h>
26 #include <linux/string.h>
27 #include <linux/ioport.h>
28 #include <linux/delay.h>
29 #include <linux/sched.h>
30 #include <linux/proc_fs.h>
31 #include <asm/dma.h>
32 #include <asm/system.h>
33 #include <asm/io.h>
34 #include "../block/blk.h"
35 #include "scsi.h"
36 #include "hosts.h"
37
38
39 #include "aha1542.h"
40
41 #include<linux/stat.h>
42
43 struct proc_dir_entry proc_scsi_aha1542 = {
44 PROC_SCSI_AHA1542, 7, "aha1542",
45 S_IFDIR | S_IRUGO | S_IXUGO, 2
46 };
47
48 #ifdef DEBUG
49 #define DEB(x) x
50 #else
51 #define DEB(x)
52 #endif
53
54
55
56
57
58
59
60
61
62 #define MAXBOARDS 2
63
64
65 static unsigned int bases[MAXBOARDS]={0x330, 0x334};
66
67
68 static int setup_called[MAXBOARDS] = {0,0};
69 static int setup_buson[MAXBOARDS] = {0,0};
70 static int setup_busoff[MAXBOARDS] = {0,0};
71 static int setup_dmaspeed[MAXBOARDS] = {-1,-1};
72
73 static char *setup_str[MAXBOARDS] = {(char *)NULL,(char *)NULL};
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 #define DMA_MODE_REG 0xd6
96 #define DMA_MASK_REG 0xd4
97 #define CASCADE 0xc0
98
99 #define BIOS_TRANSLATION_1632 0
100 #define BIOS_TRANSLATION_6432 1
101 #define BIOS_TRANSLATION_25563 2
102
103 struct aha1542_hostdata{
104
105 int bios_translation;
106 int aha1542_last_mbi_used;
107 int aha1542_last_mbo_used;
108 Scsi_Cmnd * SCint[AHA1542_MAILBOXES];
109 struct mailbox mb[2*AHA1542_MAILBOXES];
110 struct ccb ccb[AHA1542_MAILBOXES];
111 };
112
113 #define HOSTDATA(host) ((struct aha1542_hostdata *) &host->hostdata)
114
115 static struct Scsi_Host * aha_host[7] = {NULL,};
116
117
118
119
120 #define WAITnexttimeout 3000000
121
122 static void setup_mailboxes(int base_io, struct Scsi_Host * shpnt);
123 static int aha1542_restart(struct Scsi_Host * shost);
124
125 #define aha1542_intr_reset(base) outb(IRST, CONTROL(base))
126
127 #define WAIT(port, mask, allof, noneof) \
128 { register WAITbits; \
129 register WAITtimeout = WAITnexttimeout; \
130 while (1) { \
131 WAITbits = inb(port) & (mask); \
132 if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
133 break; \
134 if (--WAITtimeout == 0) goto fail; \
135 } \
136 }
137
138
139
140 #define WAITd(port, mask, allof, noneof, timeout) \
141 { register WAITbits; \
142 register WAITtimeout = timeout; \
143 while (1) { \
144 WAITbits = inb(port) & (mask); \
145 if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
146 break; \
147 udelay(1000); \
148 if (--WAITtimeout == 0) goto fail; \
149 } \
150 }
151
152 static void aha1542_stat(void)
153 {
154
155
156 }
157
158
159
160
161
162 static int aha1542_out(unsigned int base, unchar *cmdp, int len)
163 {
164 unsigned long flags = 0;
165
166 save_flags(flags);
167 if(len == 1) {
168 while(1==1){
169 WAIT(STATUS(base), CDF, 0, CDF);
170 cli();
171 if(inb(STATUS(base)) & CDF) {restore_flags(flags); continue;}
172 outb(*cmdp, DATA(base));
173 restore_flags(flags);
174 return 0;
175 }
176 } else {
177 cli();
178 while (len--)
179 {
180 WAIT(STATUS(base), CDF, 0, CDF);
181 outb(*cmdp++, DATA(base));
182 }
183 restore_flags(flags);
184 }
185 return 0;
186 fail:
187 restore_flags(flags);
188 printk("aha1542_out failed(%d): ", len+1); aha1542_stat();
189 return 1;
190 }
191
192
193
194 static int aha1542_in(unsigned int base, unchar *cmdp, int len)
195 {
196 unsigned long flags;
197
198 save_flags(flags);
199 cli();
200 while (len--)
201 {
202 WAIT(STATUS(base), DF, DF, 0);
203 *cmdp++ = inb(DATA(base));
204 }
205 restore_flags(flags);
206 return 0;
207 fail:
208 restore_flags(flags);
209 printk("aha1542_in failed(%d): ", len+1); aha1542_stat();
210 return 1;
211 }
212
213
214
215
216 static int aha1542_in1(unsigned int base, unchar *cmdp, int len)
217 {
218 unsigned long flags;
219
220 save_flags(flags);
221 cli();
222 while (len--)
223 {
224 WAITd(STATUS(base), DF, DF, 0, 100);
225 *cmdp++ = inb(DATA(base));
226 }
227 restore_flags(flags);
228 return 0;
229 fail:
230 restore_flags(flags);
231 return 1;
232 }
233
234 static int makecode(unsigned hosterr, unsigned scsierr)
235 {
236 switch (hosterr) {
237 case 0x0:
238 case 0xa:
239 case 0xb:
240 hosterr = 0;
241 break;
242
243 case 0x11:
244
245 hosterr = DID_TIME_OUT;
246 break;
247
248 case 0x12:
249
250
251
252 case 0x13:
253
254 case 0x15:
255
256
257 case 0x16:
258
259
260 case 0x17:
261
262
263 case 0x18:
264
265
266 case 0x19:
267
268
269
270 case 0x1a:
271
272
273 DEB(printk("Aha1542: %x %x\n", hosterr, scsierr));
274 hosterr = DID_ERROR;
275 break;
276
277 case 0x14:
278
279
280
281 hosterr = DID_RESET;
282 break;
283 default:
284 printk("makecode: unknown hoststatus %x\n", hosterr);
285 break;
286 }
287 return scsierr|(hosterr << 16);
288 }
289
290 static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
291 {
292 int i;
293 unchar inquiry_cmd[] = {CMD_INQUIRY };
294 unchar inquiry_result[4];
295 unchar *cmdp;
296 int len;
297 volatile int debug = 0;
298
299
300 if(inb(STATUS(bse)) == 0xff) return 0;
301
302
303
304
305
306
307 aha1542_intr_reset(bse);
308
309 outb(SRST|IRST, CONTROL(bse));
310
311 i = jiffies + 2;
312 while (i>jiffies);
313
314 debug = 1;
315
316 WAIT(STATUS(bse), STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
317
318 debug = 2;
319
320 if (inb(INTRFLAGS(bse))&INTRMASK) goto fail;
321
322
323
324
325
326 aha1542_out(bse, inquiry_cmd, 1);
327
328 debug = 3;
329 len = 4;
330 cmdp = &inquiry_result[0];
331
332 while (len--)
333 {
334 WAIT(STATUS(bse), DF, DF, 0);
335 *cmdp++ = inb(DATA(bse));
336 }
337
338 debug = 8;
339
340 if (inb(STATUS(bse)) & DF) goto fail;
341
342 debug = 9;
343
344 WAIT(INTRFLAGS(bse), HACC, HACC, 0);
345
346
347 debug = 10;
348
349 outb(IRST, CONTROL(bse));
350
351 debug = 11;
352
353 return debug;
354 fail:
355 return 0;
356 }
357
358
359 static void aha1542_intr_handle(int irq, struct pt_regs *regs)
360 {
361 void (*my_done)(Scsi_Cmnd *) = NULL;
362 int errstatus, mbi, mbo, mbistatus;
363 int number_serviced;
364 unsigned int flags;
365 struct Scsi_Host * shost;
366 Scsi_Cmnd * SCtmp;
367 int flag;
368 int needs_restart;
369 struct mailbox * mb;
370 struct ccb *ccb;
371
372 shost = aha_host[irq - 9];
373 if(!shost) panic("Splunge!");
374
375 mb = HOSTDATA(shost)->mb;
376 ccb = HOSTDATA(shost)->ccb;
377
378 #ifdef DEBUG
379 {
380 flag = inb(INTRFLAGS(shost->io_port));
381 printk("aha1542_intr_handle: ");
382 if (!(flag&ANYINTR)) printk("no interrupt?");
383 if (flag&MBIF) printk("MBIF ");
384 if (flag&MBOA) printk("MBOF ");
385 if (flag&HACC) printk("HACC ");
386 if (flag&SCRD) printk("SCRD ");
387 printk("status %02x\n", inb(STATUS(shost->io_port)));
388 };
389 #endif
390 number_serviced = 0;
391 needs_restart = 0;
392
393 while(1==1){
394 flag = inb(INTRFLAGS(shost->io_port));
395
396
397
398
399
400 if (flag & ~MBIF) {
401 if (flag&MBOA) printk("MBOF ");
402 if (flag&HACC) printk("HACC ");
403 if (flag&SCRD) {
404 needs_restart = 1;
405 printk("SCRD ");
406 }
407 }
408
409 aha1542_intr_reset(shost->io_port);
410
411 save_flags(flags);
412 cli();
413 mbi = HOSTDATA(shost)->aha1542_last_mbi_used + 1;
414 if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
415
416 do{
417 if(mb[mbi].status != 0) break;
418 mbi++;
419 if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
420 } while (mbi != HOSTDATA(shost)->aha1542_last_mbi_used);
421
422 if(mb[mbi].status == 0){
423 restore_flags(flags);
424
425 if (!number_serviced && !needs_restart)
426 printk("aha1542.c: interrupt received, but no mail.\n");
427
428
429 if(needs_restart) aha1542_restart(shost);
430 return;
431 };
432
433 mbo = (scsi2int(mb[mbi].ccbptr) - ((unsigned int) &ccb[0])) / sizeof(struct ccb);
434 mbistatus = mb[mbi].status;
435 mb[mbi].status = 0;
436 HOSTDATA(shost)->aha1542_last_mbi_used = mbi;
437 restore_flags(flags);
438
439 #ifdef DEBUG
440 {
441 if (ccb[mbo].tarstat|ccb[mbo].hastat)
442 printk("aha1542_command: returning %x (status %d)\n",
443 ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);
444 };
445 #endif
446
447 if(mbistatus == 3) continue;
448
449 #ifdef DEBUG
450 printk("...done %d %d\n",mbo, mbi);
451 #endif
452
453 SCtmp = HOSTDATA(shost)->SCint[mbo];
454
455 if (!SCtmp || !SCtmp->scsi_done) {
456 printk("aha1542_intr_handle: Unexpected interrupt\n");
457 printk("tarstat=%x, hastat=%x idlun=%x ccb#=%d \n", ccb[mbo].tarstat,
458 ccb[mbo].hastat, ccb[mbo].idlun, mbo);
459 return;
460 }
461
462 my_done = SCtmp->scsi_done;
463 if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
464
465
466
467
468 if (ccb[mbo].tarstat == 2)
469 memcpy(SCtmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
470 sizeof(SCtmp->sense_buffer));
471
472
473
474
475
476 if (mbistatus != 1)
477
478 errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
479 else
480 errstatus = 0;
481
482 #ifdef DEBUG
483 if(errstatus) printk("(aha1542 error:%x %x %x) ",errstatus,
484 ccb[mbo].hastat, ccb[mbo].tarstat);
485 #endif
486
487 if (ccb[mbo].tarstat == 2) {
488 #ifdef DEBUG
489 int i;
490 #endif
491 DEB(printk("aha1542_intr_handle: sense:"));
492 #ifdef DEBUG
493 for (i = 0; i < 12; i++)
494 printk("%02x ", ccb[mbo].cdb[ccb[mbo].cdblen+i]);
495 printk("\n");
496 #endif
497
498
499
500
501
502
503 }
504 DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus));
505 SCtmp->result = errstatus;
506 HOSTDATA(shost)->SCint[mbo] = NULL;
507
508 my_done(SCtmp);
509 number_serviced++;
510 };
511 }
512
513 int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
514 {
515 unchar ahacmd = CMD_START_SCSI;
516 unchar direction;
517 unchar *cmd = (unchar *) SCpnt->cmnd;
518 unchar target = SCpnt->target;
519 unchar lun = SCpnt->lun;
520 unsigned long flags;
521 void *buff = SCpnt->request_buffer;
522 int bufflen = SCpnt->request_bufflen;
523 int mbo;
524 struct mailbox * mb;
525 struct ccb *ccb;
526
527 DEB(int i);
528
529 mb = HOSTDATA(SCpnt->host)->mb;
530 ccb = HOSTDATA(SCpnt->host)->ccb;
531
532 DEB(if (target > 1) {
533 SCpnt->result = DID_TIME_OUT << 16;
534 done(SCpnt); return 0;});
535
536 if(*cmd == REQUEST_SENSE){
537 #ifndef DEBUG
538 if (bufflen != sizeof(SCpnt->sense_buffer)) {
539 printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
540 };
541 #endif
542 SCpnt->result = 0;
543 done(SCpnt);
544 return 0;
545 };
546
547 #ifdef DEBUG
548 if (*cmd == READ_10 || *cmd == WRITE_10)
549 i = xscsi2int(cmd+2);
550 else if (*cmd == READ_6 || *cmd == WRITE_6)
551 i = scsi2int(cmd+2);
552 else
553 i = -1;
554 if (done)
555 printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
556 else
557 printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
558 aha1542_stat();
559 printk("aha1542_queuecommand: dumping scsi cmd:");
560 for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
561 printk("\n");
562 if (*cmd == WRITE_10 || *cmd == WRITE_6)
563 return 0;
564 #endif
565
566
567
568 save_flags(flags);
569 cli();
570 mbo = HOSTDATA(SCpnt->host)->aha1542_last_mbo_used + 1;
571 if (mbo >= AHA1542_MAILBOXES) mbo = 0;
572
573 do{
574 if(mb[mbo].status == 0 && HOSTDATA(SCpnt->host)->SCint[mbo] == NULL)
575 break;
576 mbo++;
577 if (mbo >= AHA1542_MAILBOXES) mbo = 0;
578 } while (mbo != HOSTDATA(SCpnt->host)->aha1542_last_mbo_used);
579
580 if(mb[mbo].status || HOSTDATA(SCpnt->host)->SCint[mbo])
581 panic("Unable to find empty mailbox for aha1542.\n");
582
583 HOSTDATA(SCpnt->host)->SCint[mbo] = SCpnt;
584
585
586 HOSTDATA(SCpnt->host)->aha1542_last_mbo_used = mbo;
587 restore_flags(flags);
588
589 #ifdef DEBUG
590 printk("Sending command (%d %x)...",mbo, done);
591 #endif
592
593 any2scsi(mb[mbo].ccbptr, &ccb[mbo]);
594
595 memset(&ccb[mbo], 0, sizeof(struct ccb));
596
597 ccb[mbo].cdblen = SCpnt->cmd_len;
598
599 direction = 0;
600 if (*cmd == READ_10 || *cmd == READ_6)
601 direction = 8;
602 else if (*cmd == WRITE_10 || *cmd == WRITE_6)
603 direction = 16;
604
605 memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
606
607 if (SCpnt->use_sg) {
608 struct scatterlist * sgpnt;
609 struct chain * cptr;
610 #ifdef DEBUG
611 unsigned char * ptr;
612 #endif
613 int i;
614 ccb[mbo].op = 2;
615 SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
616 sgpnt = (struct scatterlist *) SCpnt->request_buffer;
617 cptr = (struct chain *) SCpnt->host_scribble;
618 if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n");
619 for(i=0; i<SCpnt->use_sg; i++) {
620 if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 ||
621 (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){
622 unsigned char * ptr;
623 printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i);
624 for(i=0;i<SCpnt->use_sg;i++){
625 printk("%d: %x %x %d\n",i,(unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address,
626 sgpnt[i].length);
627 };
628 printk("cptr %x: ",(unsigned int) cptr);
629 ptr = (unsigned char *) &cptr[i];
630 for(i=0;i<18;i++) printk("%02x ", ptr[i]);
631 panic("Foooooooood fight!");
632 };
633 any2scsi(cptr[i].dataptr, sgpnt[i].address);
634 if(((unsigned int) sgpnt[i].address) & 0xff000000) goto baddma;
635 any2scsi(cptr[i].datalen, sgpnt[i].length);
636 };
637 any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
638 any2scsi(ccb[mbo].dataptr, cptr);
639 #ifdef DEBUG
640 printk("cptr %x: ",cptr);
641 ptr = (unsigned char *) cptr;
642 for(i=0;i<18;i++) printk("%02x ", ptr[i]);
643 #endif
644 } else {
645 ccb[mbo].op = 0;
646 SCpnt->host_scribble = NULL;
647 any2scsi(ccb[mbo].datalen, bufflen);
648 if(((unsigned int) buff & 0xff000000)) goto baddma;
649 any2scsi(ccb[mbo].dataptr, buff);
650 };
651 ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7);
652 ccb[mbo].rsalen = 12;
653 ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
654 ccb[mbo].commlinkid = 0;
655
656 #ifdef DEBUG
657 { int i;
658 printk("aha1542_command: sending.. ");
659 for (i = 0; i < sizeof(ccb[mbo])-10; i++)
660 printk("%02x ", ((unchar *)&ccb[mbo])[i]);
661 };
662 #endif
663
664 if (done) {
665 DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat());
666 SCpnt->scsi_done = done;
667 mb[mbo].status = 1;
668 aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
669 DEB(aha1542_stat());
670 }
671 else
672 printk("aha1542_queuecommand: done can't be NULL\n");
673
674 return 0;
675 baddma:
676 panic("Buffer at address > 16Mb used for 1542B");
677 }
678
679 static void internal_done(Scsi_Cmnd * SCpnt)
680 {
681 SCpnt->SCp.Status++;
682 }
683
684 int aha1542_command(Scsi_Cmnd * SCpnt)
685 {
686 DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
687
688 aha1542_queuecommand(SCpnt, internal_done);
689
690 SCpnt->SCp.Status = 0;
691 while (!SCpnt->SCp.Status)
692 barrier();
693 return SCpnt->result;
694 }
695
696
697 static void setup_mailboxes(int bse, struct Scsi_Host * shpnt)
698 {
699 int i;
700 struct mailbox * mb;
701 struct ccb *ccb;
702
703 unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
704
705 mb = HOSTDATA(shpnt)->mb;
706 ccb = HOSTDATA(shpnt)->ccb;
707
708 for(i=0; i<AHA1542_MAILBOXES; i++){
709 mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0;
710 any2scsi(mb[i].ccbptr, &ccb[i]);
711 };
712 aha1542_intr_reset(bse);
713 any2scsi((cmd+2), mb);
714 aha1542_out(bse, cmd, 5);
715 WAIT(INTRFLAGS(bse), INTRMASK, HACC, 0);
716 while (0) {
717 fail:
718 printk("aha1542_detect: failed setting up mailboxes\n");
719 }
720 aha1542_intr_reset(bse);
721 }
722
723 static int aha1542_getconfig(int base_io, unsigned char * irq_level, unsigned char * dma_chan, unsigned char * scsi_id)
724 {
725 unchar inquiry_cmd[] = {CMD_RETCONF };
726 unchar inquiry_result[3];
727 int i;
728 i = inb(STATUS(base_io));
729 if (i & DF) {
730 i = inb(DATA(base_io));
731 };
732 aha1542_out(base_io, inquiry_cmd, 1);
733 aha1542_in(base_io, inquiry_result, 3);
734 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
735 while (0) {
736 fail:
737 printk("aha1542_detect: query board settings\n");
738 }
739 aha1542_intr_reset(base_io);
740 switch(inquiry_result[0]){
741 case 0x80:
742 *dma_chan = 7;
743 break;
744 case 0x40:
745 *dma_chan = 6;
746 break;
747 case 0x20:
748 *dma_chan = 5;
749 break;
750 case 0x01:
751 printk("DMA priority 0 not available for Adaptec driver\n");
752 return -1;
753 case 0:
754
755
756 *dma_chan = 0xFF;
757 break;
758 default:
759 printk("Unable to determine Adaptec DMA priority. Disabling board\n");
760 return -1;
761 };
762 switch(inquiry_result[1]){
763 case 0x40:
764 *irq_level = 15;
765 break;
766 case 0x20:
767 *irq_level = 14;
768 break;
769 case 0x8:
770 *irq_level = 12;
771 break;
772 case 0x4:
773 *irq_level = 11;
774 break;
775 case 0x2:
776 *irq_level = 10;
777 break;
778 case 0x1:
779 *irq_level = 9;
780 break;
781 default:
782 printk("Unable to determine Adaptec IRQ level. Disabling board\n");
783 return -1;
784 };
785 *scsi_id=inquiry_result[2] & 7;
786 return 0;
787 }
788
789
790
791
792 static int aha1542_mbenable(int base)
793 {
794 static unchar mbenable_cmd[3];
795 static unchar mbenable_result[2];
796 int retval;
797
798 retval = BIOS_TRANSLATION_6432;
799
800 mbenable_cmd[0]=CMD_EXTBIOS;
801 aha1542_out(base,mbenable_cmd,1);
802 if(aha1542_in1(base,mbenable_result,2))
803 return retval;
804 WAITd(INTRFLAGS(base),INTRMASK,HACC,0,100);
805 aha1542_intr_reset(base);
806
807 if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
808 mbenable_cmd[0]=CMD_MBENABLE;
809 mbenable_cmd[1]=0;
810 mbenable_cmd[2]=mbenable_result[1];
811 if(mbenable_result[1] & 1) retval = BIOS_TRANSLATION_25563;
812 aha1542_out(base,mbenable_cmd,3);
813 WAIT(INTRFLAGS(base),INTRMASK,HACC,0);
814 };
815 while(0) {
816 fail:
817 printk("aha1542_mbenable: Mailbox init failed\n");
818 }
819 aha1542_intr_reset(base);
820 return retval;
821 }
822
823
824 static int aha1542_query(int base_io, int * transl)
825 {
826 unchar inquiry_cmd[] = {CMD_INQUIRY };
827 unchar inquiry_result[4];
828 int i;
829 i = inb(STATUS(base_io));
830 if (i & DF) {
831 i = inb(DATA(base_io));
832 };
833 aha1542_out(base_io, inquiry_cmd, 1);
834 aha1542_in(base_io, inquiry_result, 4);
835 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
836 while (0) {
837 fail:
838 printk("aha1542_detect: query card type\n");
839 }
840 aha1542_intr_reset(base_io);
841
842 *transl = BIOS_TRANSLATION_6432;
843
844
845
846
847
848
849
850 if (inquiry_result[0] == 0x43) {
851 printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");
852 return 1;
853 };
854
855
856
857
858 *transl = aha1542_mbenable(base_io);
859
860 return 0;
861 }
862
863
864 void aha1542_setup( char *str, int *ints)
865 {
866 const char *ahausage = "aha1542: usage: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]\n";
867 static int setup_idx = 0;
868 int setup_portbase;
869
870 if(setup_idx >= MAXBOARDS)
871 {
872 printk("aha1542: aha1542_setup called too many times! Bad LILO params ?\n");
873 printk(" Entryline 1: %s\n",setup_str[0]);
874 printk(" Entryline 2: %s\n",setup_str[1]);
875 printk(" This line: %s\n",str);
876 return;
877 }
878 if (ints[0] < 1 || ints[0] > 4)
879 {
880 printk("aha1542: %s\n", str );
881 printk(ahausage);
882 printk("aha1542: Wrong parameters may cause system malfunction.. We try anyway..\n");
883 }
884
885 setup_called[setup_idx]=ints[0];
886 setup_str[setup_idx]=str;
887
888 setup_portbase = ints[0] >= 1 ? ints[1] : 0;
889 setup_buson [setup_idx] = ints[0] >= 2 ? ints[2] : 7;
890 setup_busoff [setup_idx] = ints[0] >= 3 ? ints[3] : 5;
891 if (ints[0] >= 4) {
892 int atbt = -1;
893 switch (ints[4]) {
894 case 5:
895 atbt = 0x00;
896 break;
897 case 6:
898 atbt = 0x04;
899 break;
900 case 7:
901 atbt = 0x01;
902 break;
903 case 8:
904 atbt = 0x02;
905 break;
906 case 10:
907 atbt = 0x03;
908 break;
909 default:
910 printk("aha1542: %s\n", str );
911 printk(ahausage);
912 printk("aha1542: Valid values for DMASPEED are 5-8, 10 MB/s. Using jumper defaults.\n");
913 break;
914 }
915 setup_dmaspeed[setup_idx] = atbt;
916 }
917
918 if (setup_portbase != 0)
919 bases[setup_idx] = setup_portbase;
920
921 ++setup_idx;
922 }
923
924
925 int aha1542_detect(Scsi_Host_Template * tpnt)
926 {
927 unsigned char dma_chan;
928 unsigned char irq_level;
929 unsigned char scsi_id;
930 unsigned long flags;
931 unsigned int base_io;
932 int trans;
933 struct Scsi_Host * shpnt = NULL;
934 int count = 0;
935 int indx;
936
937 DEB(printk("aha1542_detect: \n"));
938
939 tpnt->proc_dir = &proc_scsi_aha1542;
940
941 for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
942 if(bases[indx] != 0 && !check_region(bases[indx], 4)) {
943 shpnt = scsi_register(tpnt,
944 sizeof(struct aha1542_hostdata));
945
946
947
948 if ((unsigned int) shpnt > 0xffffff) {
949 printk("Invalid address for shpnt with 1542.\n");
950 goto unregister;
951 }
952
953 if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
954
955
956 base_io = bases[indx];
957
958
959 {
960 unchar oncmd[] = {CMD_BUSON_TIME, 7};
961 unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
962
963 if(setup_called[indx])
964 {
965 oncmd[1] = setup_buson[indx];
966 offcmd[1] = setup_busoff[indx];
967 }
968
969 aha1542_intr_reset(base_io);
970 aha1542_out(base_io, oncmd, 2);
971 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
972 aha1542_intr_reset(base_io);
973 aha1542_out(base_io, offcmd, 2);
974 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
975 if (setup_dmaspeed[indx] >= 0)
976 {
977 unchar dmacmd[] = {CMD_DMASPEED, 0};
978 dmacmd[1] = setup_dmaspeed[indx];
979 aha1542_intr_reset(base_io);
980 aha1542_out(base_io, dmacmd, 2);
981 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
982 }
983 while (0) {
984 fail:
985 printk("aha1542_detect: setting bus on/off-time failed\n");
986 }
987 aha1542_intr_reset(base_io);
988 }
989 if(aha1542_query(base_io, &trans)) goto unregister;
990
991 if (aha1542_getconfig(base_io, &irq_level, &dma_chan, &scsi_id) == -1) goto unregister;
992
993 printk("Configuring Adaptec (SCSI-ID %d) at IO:%x, IRQ %d", scsi_id, base_io, irq_level);
994 if (dma_chan != 0xFF)
995 printk(", DMA priority %d", dma_chan);
996 printk("\n");
997
998 DEB(aha1542_stat());
999 setup_mailboxes(base_io, shpnt);
1000
1001 DEB(aha1542_stat());
1002
1003 DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
1004 save_flags(flags);
1005 cli();
1006 if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542")) {
1007 printk("Unable to allocate IRQ for adaptec controller.\n");
1008 goto unregister;
1009 }
1010
1011 if (dma_chan != 0xFF) {
1012 if (request_dma(dma_chan,"aha1542")) {
1013 printk("Unable to allocate DMA channel for Adaptec.\n");
1014 free_irq(irq_level);
1015 goto unregister;
1016 }
1017
1018 if (dma_chan >= 5) {
1019 outb((dma_chan - 4) | CASCADE, DMA_MODE_REG);
1020 outb(dma_chan - 4, DMA_MASK_REG);
1021 }
1022 }
1023 aha_host[irq_level - 9] = shpnt;
1024 shpnt->this_id = scsi_id;
1025 shpnt->unique_id = base_io;
1026 shpnt->io_port = base_io;
1027 shpnt->n_io_port = 4;
1028 shpnt->dma_channel = dma_chan;
1029 shpnt->irq = irq_level;
1030 HOSTDATA(shpnt)->bios_translation = trans;
1031 if(trans == 2)
1032 printk("aha1542.c: Using extended bios translation\n");
1033 HOSTDATA(shpnt)->aha1542_last_mbi_used = (2*AHA1542_MAILBOXES - 1);
1034 HOSTDATA(shpnt)->aha1542_last_mbo_used = (AHA1542_MAILBOXES - 1);
1035 memset(HOSTDATA(shpnt)->SCint, 0, sizeof(HOSTDATA(shpnt)->SCint));
1036 restore_flags(flags);
1037 #if 0
1038 DEB(printk(" *** READ CAPACITY ***\n"));
1039
1040 {
1041 unchar buf[8];
1042 static unchar cmd[] = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1043 int i;
1044
1045 for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;
1046 for (i = 0; i < 2; ++i)
1047 if (!aha1542_command(i, cmd, buf, sizeof(buf))) {
1048 printk("aha_detect: LU %d sector_size %d device_size %d\n",
1049 i, xscsi2int(buf+4), xscsi2int(buf));
1050 }
1051 }
1052
1053 DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));
1054
1055 for (i = 0; i < 4; ++i)
1056 {
1057 unsigned char cmd[10];
1058 static buffer[512];
1059
1060 cmd[0] = READ_10;
1061 cmd[1] = 0;
1062 xany2scsi(cmd+2, i);
1063 cmd[6] = 0;
1064 cmd[7] = 0;
1065 cmd[8] = 1;
1066 cmd[9] = 0;
1067 aha1542_command(0, cmd, buffer, 512);
1068 }
1069 #endif
1070 request_region(bases[indx], 4,"aha1542");
1071 count++;
1072 continue;
1073 unregister:
1074 scsi_unregister(shpnt);
1075 continue;
1076
1077 };
1078
1079 return count;
1080 }
1081
1082 static int aha1542_restart(struct Scsi_Host * shost)
1083 {
1084 int i;
1085 int count = 0;
1086 #if 0
1087 unchar ahacmd = CMD_START_SCSI;
1088 #endif
1089
1090 for(i=0; i< AHA1542_MAILBOXES; i++)
1091 if(HOSTDATA(shost)->SCint[i] &&
1092 !(HOSTDATA(shost)->SCint[i]->device->soft_reset))
1093 {
1094 #if 0
1095 HOSTDATA(shost)->mb[i].status = 1;
1096 #endif
1097 count++;
1098 }
1099
1100 printk("Potential to restart %d stalled commands...\n", count);
1101 #if 0
1102
1103 if (count) aha1542_out(shost->io_port, &ahacmd, 1);
1104 #endif
1105 return 0;
1106 }
1107
1108
1109
1110
1111
1112 int aha1542_abort(Scsi_Cmnd * SCpnt)
1113 {
1114 #if 0
1115 unchar ahacmd = CMD_START_SCSI;
1116 unsigned long flags;
1117 struct mailbox * mb;
1118 int mbi, mbo, i;
1119
1120 printk("In aha1542_abort: %x %x\n",
1121 inb(STATUS(SCpnt->host->io_port)),
1122 inb(INTRFLAGS(SCpnt->host->io_port)));
1123
1124 save_flags(flags);
1125 cli();
1126 mb = HOSTDATA(SCpnt->host)->mb;
1127 mbi = HOSTDATA(SCpnt->host)->aha1542_last_mbi_used + 1;
1128 if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
1129
1130 do{
1131 if(mb[mbi].status != 0) break;
1132 mbi++;
1133 if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
1134 } while (mbi != HOSTDATA(SCpnt->host)->aha1542_last_mbi_used);
1135 restore_flags(flags);
1136
1137 if(mb[mbi].status) {
1138 printk("Lost interrupt discovered on irq %d - attempting to recover\n",
1139 SCpnt->host->irq);
1140 aha1542_intr_handle(SCpnt->host->irq, NULL);
1141 return 0;
1142 }
1143
1144
1145
1146
1147 for(i=0; i< AHA1542_MAILBOXES; i++)
1148 if(HOSTDATA(SCpnt->host)->SCint[i])
1149 {
1150 if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
1151 printk("Timed out command pending for %s\n",
1152 kdevname(SCpnt->request.rq_dev));
1153 if (HOSTDATA(SCpnt->host)->mb[i].status) {
1154 printk("OGMB still full - restarting\n");
1155 aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
1156 };
1157 } else
1158 printk("Other pending command %s\n",
1159 kdevname(SCpnt->request.rq_dev));
1160 }
1161
1162 #endif
1163
1164 DEB(printk("aha1542_abort\n"));
1165 #if 0
1166 save_flags(flags);
1167 cli();
1168 for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)
1169 if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]){
1170 mb[mbo].status = 2;
1171 aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
1172 restore_flags(flags);
1173 break;
1174 };
1175 #endif
1176 return SCSI_ABORT_SNOOZE;
1177 }
1178
1179
1180
1181
1182
1183
1184
1185 int aha1542_reset(Scsi_Cmnd * SCpnt)
1186 {
1187 unchar ahacmd = CMD_START_SCSI;
1188 int i;
1189
1190
1191
1192
1193 if( SCpnt->host->suggest_bus_reset )
1194 {
1195
1196
1197
1198
1199
1200
1201 outb(SCRST, CONTROL(SCpnt->host->io_port));
1202
1203
1204
1205
1206
1207
1208 printk("Sent BUS RESET to scsi host %d\n", SCpnt->host->host_no);
1209
1210 for(i=0; i< AHA1542_MAILBOXES; i++)
1211 if(HOSTDATA(SCpnt->host)->SCint[i] != NULL)
1212 {
1213 Scsi_Cmnd * SCtmp;
1214 SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
1215 SCtmp->result = DID_RESET << 16;
1216 if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
1217 printk("Sending DID_RESET for target %d\n", SCpnt->target);
1218 SCtmp->scsi_done(SCpnt);
1219
1220 HOSTDATA(SCpnt->host)->SCint[i] = NULL;
1221 HOSTDATA(SCpnt->host)->mb[i].status = 0;
1222 }
1223
1224
1225
1226
1227
1228 return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);
1229 }
1230 else
1231 {
1232
1233
1234 for(i=0; i< AHA1542_MAILBOXES; i++)
1235 if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt)
1236 {
1237 HOSTDATA(SCpnt->host)->ccb[i].op = 0x81;
1238
1239 aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
1240
1241
1242
1243
1244
1245 printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
1246
1247
1248
1249
1250 for(i=0; i< AHA1542_MAILBOXES; i++)
1251 if(HOSTDATA(SCpnt->host)->SCint[i] &&
1252 HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target)
1253 {
1254 Scsi_Cmnd * SCtmp;
1255 SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
1256 SCtmp->result = DID_RESET << 16;
1257 if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
1258 printk("Sending DID_RESET for target %d\n", SCpnt->target);
1259 SCtmp->scsi_done(SCpnt);
1260
1261 HOSTDATA(SCpnt->host)->SCint[i] = NULL;
1262 HOSTDATA(SCpnt->host)->mb[i].status = 0;
1263 }
1264 return SCSI_RESET_SUCCESS;
1265 }
1266 }
1267
1268
1269
1270 return SCSI_RESET_PUNT;
1271 }
1272
1273 #include "sd.h"
1274
1275 int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int * ip)
1276 {
1277 int translation_algorithm;
1278 int size = disk->capacity;
1279
1280 translation_algorithm = HOSTDATA(disk->device->host)->bios_translation;
1281
1282 if((size>>11) > 1024 && translation_algorithm == 2) {
1283
1284 ip[0] = 255;
1285 ip[1] = 63;
1286 ip[2] = size /255/63;
1287 } else {
1288 ip[0] = 64;
1289 ip[1] = 32;
1290 ip[2] = size >> 11;
1291 };
1292
1293 return 0;
1294 }
1295
1296
1297 #ifdef MODULE
1298
1299 Scsi_Host_Template driver_template = AHA1542;
1300
1301 #include "scsi_module.c"
1302 #endif
1303