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