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