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