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 panic("aha1542.c");
464 };
465 #endif
466 SCpnt->result = 0;
467 done(SCpnt);
468 return 0;
469 };
470
471 #ifdef DEBUG
472 if (*cmd == READ_10 || *cmd == WRITE_10)
473 i = xscsi2int(cmd+2);
474 else if (*cmd == READ_6 || *cmd == WRITE_6)
475 i = scsi2int(cmd+2);
476 else
477 i = -1;
478 if (done)
479 printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
480 else
481 printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
482 aha1542_stat();
483 printk("aha1542_queuecommand: dumping scsi cmd:");
484 for (i = 0; i < (COMMAND_SIZE(*cmd)); i++) printk("%02x ", cmd[i]);
485 printk("\n");
486 if (*cmd == WRITE_10 || *cmd == WRITE_6)
487 return 0;
488 #endif
489
490
491
492 cli();
493 mbo = HOSTDATA(SCpnt->host)->aha1542_last_mbo_used + 1;
494 if (mbo >= AHA1542_MAILBOXES) mbo = 0;
495
496 do{
497 if(mb[mbo].status == 0 && HOSTDATA(SCpnt->host)->SCint[mbo] == NULL)
498 break;
499 mbo++;
500 if (mbo >= AHA1542_MAILBOXES) mbo = 0;
501 } while (mbo != HOSTDATA(SCpnt->host)->aha1542_last_mbo_used);
502
503 if(mb[mbo].status || HOSTDATA(SCpnt->host)->SCint[mbo])
504 panic("Unable to find empty mailbox for aha1542.\n");
505
506 HOSTDATA(SCpnt->host)->SCint[mbo] = SCpnt;
507
508
509 HOSTDATA(SCpnt->host)->aha1542_last_mbo_used = mbo;
510 sti();
511
512 #ifdef DEBUG
513 printk("Sending command (%d %x)...",mbo, done);
514 #endif
515
516 any2scsi(mb[mbo].ccbptr, &ccb[mbo]);
517
518 memset(&ccb[mbo], 0, sizeof(struct ccb));
519
520 ccb[mbo].cdblen = COMMAND_SIZE(*cmd);
521
522 direction = 0;
523 if (*cmd == READ_10 || *cmd == READ_6)
524 direction = 8;
525 else if (*cmd == WRITE_10 || *cmd == WRITE_6)
526 direction = 16;
527
528 memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
529
530 if (SCpnt->use_sg) {
531 struct scatterlist * sgpnt;
532 struct chain * cptr;
533 #ifdef DEBUG
534 unsigned char * ptr;
535 #endif
536 int i;
537 ccb[mbo].op = 2;
538 SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
539 sgpnt = (struct scatterlist *) SCpnt->request_buffer;
540 cptr = (struct chain *) SCpnt->host_scribble;
541 if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n");
542 for(i=0; i<SCpnt->use_sg; i++) {
543 if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 ||
544 (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){
545 unsigned char * ptr;
546 printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i);
547 for(i=0;i<SCpnt->use_sg;i++){
548 printk("%d: %x %x %d\n",i,(unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address,
549 sgpnt[i].length);
550 };
551 printk("cptr %x: ",(unsigned int) cptr);
552 ptr = (unsigned char *) &cptr[i];
553 for(i=0;i<18;i++) printk("%02x ", ptr[i]);
554 panic("Foooooooood fight!");
555 };
556 any2scsi(cptr[i].dataptr, sgpnt[i].address);
557 if(((unsigned int) sgpnt[i].address) & 0xff000000) goto baddma;
558 any2scsi(cptr[i].datalen, sgpnt[i].length);
559 };
560 any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
561 if(((unsigned int) buff & 0xff000000)) goto baddma;
562 any2scsi(ccb[mbo].dataptr, cptr);
563 #ifdef DEBUG
564 printk("cptr %x: ",cptr);
565 ptr = (unsigned char *) cptr;
566 for(i=0;i<18;i++) printk("%02x ", ptr[i]);
567 #endif
568 } else {
569 ccb[mbo].op = 0;
570 SCpnt->host_scribble = NULL;
571 any2scsi(ccb[mbo].datalen, bufflen);
572 any2scsi(ccb[mbo].dataptr, buff);
573 };
574 ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7);
575 ccb[mbo].rsalen = 12;
576 ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
577 ccb[mbo].commlinkid = 0;
578
579 #ifdef DEBUGd
580 { int i;
581 printk("aha1542_command: sending.. ");
582 for (i = 0; i < sizeof(ccb[mbo])-10; i++)
583 printk("%02x ", ((unchar *)&ccb[mbo])[i]);
584 };
585 #endif
586
587 if (done) {
588 DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat());
589 SCpnt->scsi_done = done;
590 mb[mbo].status = 1;
591 aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
592 DEB(aha1542_stat());
593 }
594 else
595 printk("aha1542_queuecommand: done can't be NULL\n");
596
597 return 0;
598 baddma:
599 panic("Buffer at address > 16Mb used for 1542B");
600 }
601
602 static void internal_done(Scsi_Cmnd * SCpnt)
603 {
604 SCpnt->SCp.Status++;
605 }
606
607 int aha1542_command(Scsi_Cmnd * SCpnt)
608 {
609 DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
610
611 aha1542_queuecommand(SCpnt, internal_done);
612
613 SCpnt->SCp.Status = 0;
614 while (!SCpnt->SCp.Status);
615 return SCpnt->result;
616 }
617
618
619 static void setup_mailboxes(int bse, struct Scsi_Host * shpnt)
620 {
621 int i;
622 struct mailbox * mb;
623 struct ccb *ccb;
624
625 unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
626
627 mb = HOSTDATA(shpnt)->mb;
628 ccb = HOSTDATA(shpnt)->ccb;
629
630 for(i=0; i<AHA1542_MAILBOXES; i++){
631 mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0;
632 any2scsi(mb[i].ccbptr, &ccb[i]);
633 };
634 aha1542_intr_reset(bse);
635 any2scsi((cmd+2), mb);
636 aha1542_out(bse, cmd, 5);
637 WAIT(INTRFLAGS(bse), INTRMASK, HACC, 0);
638 while (0) {
639 fail:
640 printk("aha1542_detect: failed setting up mailboxes\n");
641 }
642 aha1542_intr_reset(bse);
643 }
644
645 static int aha1542_getconfig(int base_io, unsigned char * irq_level, unsigned char * dma_chan)
646 {
647 unchar inquiry_cmd[] = {CMD_RETCONF };
648 unchar inquiry_result[3];
649 int i;
650 i = inb(STATUS(base_io));
651 if (i & DF) {
652 i = inb(DATA(base_io));
653 };
654 aha1542_out(base_io, inquiry_cmd, 1);
655 aha1542_in(base_io, inquiry_result, 3);
656 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
657 while (0) {
658 fail:
659 printk("aha1542_detect: query board settings\n");
660 }
661 aha1542_intr_reset(base_io);
662 switch(inquiry_result[0]){
663 case 0x80:
664 *dma_chan = 7;
665 break;
666 case 0x40:
667 *dma_chan = 6;
668 break;
669 case 0x20:
670 *dma_chan = 5;
671 break;
672 case 0x01:
673 printk("DMA priority 0 not available for Adaptec driver\n");
674 return -1;
675 case 0:
676
677
678 *dma_chan = 0xFF;
679 break;
680 default:
681 printk("Unable to determine Adaptec DMA priority. Disabling board\n");
682 return -1;
683 };
684 switch(inquiry_result[1]){
685 case 0x40:
686 *irq_level = 15;
687 break;
688 case 0x20:
689 *irq_level = 14;
690 break;
691 case 0x8:
692 *irq_level = 12;
693 break;
694 case 0x4:
695 *irq_level = 11;
696 break;
697 case 0x2:
698 *irq_level = 10;
699 break;
700 case 0x1:
701 *irq_level = 9;
702 break;
703 default:
704 printk("Unable to determine Adaptec IRQ level. Disabling board\n");
705 return -1;
706 };
707 return 0;
708 }
709
710
711
712
713 static int aha1542_mbenable(int base)
714 {
715 static unchar mbenable_cmd[3];
716 static unchar mbenable_result[2];
717 int retval;
718
719 retval = BIOS_TRANSLATION_6432;
720
721 mbenable_cmd[0]=CMD_EXTBIOS;
722 aha1542_out(base,mbenable_cmd,1);
723 aha1542_in(base,mbenable_result,2);
724 WAIT(INTRFLAGS(base),INTRMASK,HACC,0);
725 aha1542_intr_reset(base);
726
727 if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
728 mbenable_cmd[0]=CMD_MBENABLE;
729 mbenable_cmd[1]=0;
730 mbenable_cmd[2]=mbenable_result[1];
731 if(mbenable_result[1] & 1) retval = BIOS_TRANSLATION_25563;
732 aha1542_out(base,mbenable_cmd,3);
733 WAIT(INTRFLAGS(base),INTRMASK,HACC,0);
734 };
735 while(0) {
736 fail:
737 printk("aha1542_mbenable: Mailbox init failed\n");
738 }
739 aha1542_intr_reset(base);
740 return retval;
741 }
742
743
744 static int aha1542_query(int base_io, int * transl)
745 {
746 unchar inquiry_cmd[] = {CMD_INQUIRY };
747 unchar inquiry_result[4];
748 int i;
749 i = inb(STATUS(base_io));
750 if (i & DF) {
751 i = inb(DATA(base_io));
752 };
753 aha1542_out(base_io, inquiry_cmd, 1);
754 aha1542_in(base_io, inquiry_result, 4);
755 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
756 while (0) {
757 fail:
758 printk("aha1542_detect: query card type\n");
759 }
760 aha1542_intr_reset(base_io);
761
762 *transl = BIOS_TRANSLATION_6432;
763
764
765
766
767
768
769
770 if (inquiry_result[0] == 0x43) {
771 printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");
772 return 1;
773 };
774
775
776 if (inquiry_result[0] == 0x44 || inquiry_result[0] == 0x45)
777 {
778 *transl = aha1542_mbenable(base_io);
779 };
780 return 0;
781 }
782
783
784
785 int aha1542_detect(int hostnum)
786 {
787 unsigned char dma_chan;
788 unsigned char irq_level;
789 unsigned int base_io;
790 int trans;
791 struct Scsi_Host * shpnt = NULL;
792 int count = 0;
793 int indx;
794
795 DEB(printk("aha1542_detect: \n"));
796
797 for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
798 if(!check_region(bases[indx], 4)) {
799 shpnt = scsi_register(hostnum,
800 sizeof(struct aha1542_hostdata));
801
802 if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
803
804
805 base_io = bases[indx];
806
807
808 {
809 unchar oncmd[] = {CMD_BUSON_TIME, 7};
810 unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
811
812 aha1542_intr_reset(base_io);
813 aha1542_out(base_io, oncmd, 2);
814 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
815 aha1542_intr_reset(base_io);
816 aha1542_out(base_io, offcmd, 2);
817 WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
818 while (0) {
819 fail:
820 printk("aha1542_detect: setting bus on/off-time failed\n");
821 }
822 aha1542_intr_reset(base_io);
823 }
824 if(aha1542_query(base_io, &trans)) goto unregister;
825
826 if (aha1542_getconfig(base_io, &irq_level, &dma_chan) == -1) goto unregister;
827
828 printk("Configuring Adaptec at IO:%x, IRQ %d",base_io, irq_level);
829 if (dma_chan != 0xFF)
830 printk(", DMA priority %d", dma_chan);
831 printk("\n");
832
833 DEB(aha1542_stat());
834 setup_mailboxes(base_io, shpnt);
835
836 DEB(aha1542_stat());
837
838 DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
839 cli();
840 if (request_irq(irq_level,aha1542_intr_handle)) {
841 printk("Unable to allocate IRQ for adaptec controller.\n");
842 goto unregister;
843 }
844
845 if (dma_chan != 0xFF) {
846 if (request_dma(dma_chan)) {
847 printk("Unable to allocate DMA channel for Adaptec.\n");
848 free_irq(irq_level);
849 goto unregister;
850 }
851
852 if (dma_chan >= 5) {
853 outb((dma_chan - 4) | CASCADE, DMA_MODE_REG);
854 outb(dma_chan - 4, DMA_MASK_REG);
855 }
856 }
857 aha_host[irq_level - 9] = shpnt;
858 shpnt->io_port = base_io;
859 shpnt->dma_channel = dma_chan;
860 shpnt->irq = irq_level;
861 HOSTDATA(shpnt)->bios_translation = trans;
862 if(trans == 2)
863 printk("aha1542.c: Using extended bios translation\n");
864 HOSTDATA(shpnt)->aha1542_last_mbi_used = (2*AHA1542_MAILBOXES - 1);
865 HOSTDATA(shpnt)->aha1542_last_mbo_used = (AHA1542_MAILBOXES - 1);
866 memset(HOSTDATA(shpnt)->SCint, 0, sizeof(HOSTDATA(shpnt)->SCint));
867 sti();
868 #if 0
869 DEB(printk(" *** READ CAPACITY ***\n"));
870
871 {
872 unchar buf[8];
873 static unchar cmd[] = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
874 int i;
875
876 for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;
877 for (i = 0; i < 2; ++i)
878 if (!aha1542_command(i, cmd, buf, sizeof(buf))) {
879 printk("aha_detect: LU %d sector_size %d device_size %d\n",
880 i, xscsi2int(buf+4), xscsi2int(buf));
881 }
882 }
883
884 DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));
885
886 for (i = 0; i < 4; ++i)
887 {
888 unsigned char cmd[10];
889 static buffer[512];
890
891 cmd[0] = READ_10;
892 cmd[1] = 0;
893 xany2scsi(cmd+2, i);
894 cmd[6] = 0;
895 cmd[7] = 0;
896 cmd[8] = 1;
897 cmd[9] = 0;
898 aha1542_command(0, cmd, buffer, 512);
899 }
900 #endif
901 snarf_region(bases[indx], 4);
902 count++;
903 continue;
904 unregister:
905 scsi_unregister(shpnt, sizeof(struct aha1542_hostdata));
906 continue;
907
908 };
909 return count;
910 }
911
912 static int aha1542_restart(struct Scsi_Host * shost)
913 {
914 int i;
915 int count = 0;
916 #if 0
917 unchar ahacmd = CMD_START_SCSI;
918 #endif
919
920 for(i=0; i< AHA1542_MAILBOXES; i++)
921 if(HOSTDATA(shost)->SCint[i] &&
922 !(HOSTDATA(shost)->SCint[i]->device->soft_reset))
923 {
924 #if 0
925 HOSTDATA(shost)->mb[i].status = 1;
926 #endif
927 count++;
928 }
929
930 printk("Potential to restart %d stalled commands...\n", count);
931 #if 0
932
933 if (count) aha1542_out(shost->io_port, &ahacmd, 1);
934 #endif
935 return 0;
936 }
937
938
939
940
941
942 int aha1542_abort(Scsi_Cmnd * SCpnt)
943 {
944 #if 0
945 int intval[3];
946 unchar ahacmd = CMD_START_SCSI;
947 struct mailbox * mb;
948 int mbi, mbo, i;
949
950 printk("In aha1542_abort: %x %x\n",
951 inb(STATUS(SCpnt->host->io_port)),
952 inb(INTRFLAGS(SCpnt->host->io_port)));
953
954 cli();
955 mb = HOSTDATA(SCpnt->host)->mb;
956 mbi = HOSTDATA(SCpnt->host)->aha1542_last_mbi_used + 1;
957 if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
958
959 do{
960 if(mb[mbi].status != 0) break;
961 mbi++;
962 if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
963 } while (mbi != HOSTDATA(SCpnt->host)->aha1542_last_mbi_used);
964 sti();
965
966 if(mb[mbi].status) {
967 printk("Lost interrupt discovered on irq %d - attempting to recover\n",
968 SCpnt->host->irq);
969 intval[0] = SCpnt->host->irq;
970 aha1542_intr_handle((int) &intval[2]);
971 return 0;
972 }
973
974
975
976
977 for(i=0; i< AHA1542_MAILBOXES; i++)
978 if(HOSTDATA(SCpnt->host)->SCint[i])
979 {
980 if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
981 printk("Timed out command pending for %4.4x\n", SCpnt->request.dev);
982 if (HOSTDATA(SCpnt->host)->mb[i].status) {
983 printk("OGMB still full - restarting\n");
984 aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
985 };
986 } else
987 printk("Other pending command %4.4x\n", SCpnt->request.dev);
988 }
989
990 #endif
991
992 DEB(printk("aha1542_abort\n"));
993 #if 0
994 cli();
995 for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)
996 if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]){
997 mb[mbo].status = 2;
998 aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
999 sti();
1000 break;
1001 };
1002 #endif
1003 return SCSI_ABORT_SNOOZE;
1004 }
1005
1006
1007
1008
1009
1010
1011
1012 int aha1542_reset(Scsi_Cmnd * SCpnt)
1013 {
1014 unchar ahacmd = CMD_START_SCSI;
1015 int i;
1016
1017 DEB(printk("aha1542_reset called\n"));
1018 #if 0
1019
1020 outb(SCRST, CONTROL(SCpnt->host->io_port));
1021 #else
1022
1023
1024 for(i=0; i< AHA1542_MAILBOXES; i++)
1025 if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt)
1026 {
1027 HOSTDATA(SCpnt->host)->ccb[i].op = 0x81;
1028
1029 aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
1030
1031
1032
1033
1034
1035 printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
1036
1037
1038
1039
1040 #if 1
1041 for(i=0; i< AHA1542_MAILBOXES; i++)
1042 if(HOSTDATA(SCpnt->host)->SCint[i] &&
1043 HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target)
1044 {
1045 Scsi_Cmnd * SCtmp;
1046 SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
1047 SCtmp->result = DID_RESET << 16;
1048 if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
1049 printk("Sending DID_RESET for target %d\n", SCpnt->target);
1050 SCtmp->scsi_done(SCpnt);
1051
1052 HOSTDATA(SCpnt->host)->SCint[i] = NULL;
1053 }
1054 return SCSI_RESET_SUCCESS;
1055 #else
1056 return SCSI_RESET_PENDING;
1057 #endif
1058 }
1059
1060 #endif
1061 return SCSI_RESET_PENDING;
1062 }
1063
1064 #ifdef CONFIG_BLK_DEV_SD
1065 #include "sd.h"
1066 #endif
1067
1068 int aha1542_biosparam(int size, int dev, int * ip)
1069 {
1070 int translation_algorithm;
1071 #ifdef CONFIG_BLK_DEV_SD
1072 Scsi_Device *disk;
1073
1074 disk = rscsi_disks[MINOR(dev) >> 4].device;
1075 translation_algorithm = HOSTDATA(disk->host)->bios_translation;
1076
1077 if((size>>11) > 1024 && translation_algorithm == 2) {
1078
1079 ip[0] = 255;
1080 ip[1] = 63;
1081 ip[2] = size /255/63;
1082 } else {
1083 ip[0] = 64;
1084 ip[1] = 32;
1085 ip[2] = size >> 11;
1086 };
1087
1088 #endif
1089 return 0;
1090 }