This source file includes following definitions.
- wait
- buslogic_prefix
- buslogic_stat
- buslogic_out
- buslogic_in
- buslogic_in_fast
- makecode
- test_port
- buslogic_info
- buslogic_interrupt
- buslogic_queuecommand
- internal_done
- buslogic_command
- setup_mailboxes
- getconfig
- get_translation
- buslogic_query
- buslogic_detect
- restart
- buslogic_abort
- buslogic_reset
- buslogic_biosparam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #include <linux/string.h>
65 #include <linux/sched.h>
66 #include <linux/kernel.h>
67 #include <linux/head.h>
68 #include <linux/types.h>
69 #include <linux/ioport.h>
70 #include <linux/delay.h>
71
72 #include <asm/io.h>
73 #include <asm/system.h>
74 #include <asm/dma.h>
75
76 #include "../block/blk.h"
77 #include "scsi.h"
78 #include "hosts.h"
79 #include "sd.h"
80 #define BUSLOGIC_PRIVATE_H
81 #include "buslogic.h"
82
83 #ifndef BUSLOGIC_DEBUG
84 # define BUSLOGIC_DEBUG UD_ABORT
85 #endif
86
87 #define BUSLOGIC_VERSION "1.00"
88
89
90
91 #define WAITNEXTTIMEOUT 3000000
92
93
94
95
96
97
98
99 #define BUSLOGIC_SG_MALLOC 512
100
101
102 #define BUSLOGIC_MAX_SG (BUSLOGIC_SG_MALLOC / sizeof (struct chain))
103
104
105
106 #define DMA_MODE_REG 0xD6
107 #define DMA_MASK_REG 0xD4
108 #define CASCADE 0xC0
109
110 #define BUSLOGIC_MAILBOXES 16
111
112
113
114
115
116
117
118
119
120 static const unsigned int bases[] = {
121 #ifdef BUSLOGIC_PORT_OVERRIDE
122 BUSLOGIC_PORT_OVERRIDE
123 #else
124 0x330, 0x334,
125 #endif
126 };
127
128 #define BIOS_TRANSLATION_DEFAULT 0
129 #define BIOS_TRANSLATION_BIG 1
130
131 struct hostdata {
132 unsigned char bus_type;
133 int bios_translation;
134 size_t last_mbi_used;
135 size_t last_mbo_used;
136 Scsi_Cmnd *sc[BUSLOGIC_MAILBOXES];
137 struct mailbox mb[2 * BUSLOGIC_MAILBOXES];
138 struct ccb ccbs[BUSLOGIC_MAILBOXES];
139 };
140
141 #define HOSTDATA(host) ((struct hostdata *)&(host)->hostdata)
142
143
144 static struct Scsi_Host *host[7] = { NULL, };
145
146 static int setup_mailboxes(unsigned int base, struct Scsi_Host *shpnt);
147 static int restart(struct Scsi_Host *shpnt);
148
149 #define INTR_RESET(base) outb(RINT, CONTROL(base))
150
151 #define buslogic_printk buslogic_prefix(),printk
152
153 #define CHECK(cond) if (cond) ; else goto fail
154
155 #define WAIT(port, mask, allof, noneof) \
156 CHECK(wait(port, mask, allof, noneof, WAITNEXTTIMEOUT, FALSE))
157 #define WAIT_WHILE(port, mask) WAIT(port, mask, 0, mask)
158 #define WAIT_UNTIL(port, mask) WAIT(port, mask, mask, 0)
159 #define WAIT_FAST(port, mask, allof, noneof) \
160 CHECK(wait(port, mask, allof, noneof, 100, TRUE))
161 #define WAIT_WHILE_FAST(port, mask) WAIT_FAST(port, mask, 0, mask)
162 #define WAIT_UNTIL_FAST(port, mask) WAIT_FAST(port, mask, mask, 0)
163
164
165
166 static __inline__ int wait(unsigned short port, unsigned char mask,
167 unsigned char allof, unsigned char noneof,
168 unsigned int timeout, int delay)
169 {
170 int bits;
171
172 for (;;) {
173 bits = inb(port) & mask;
174 if ((bits & allof) == allof && (bits & noneof) == 0)
175 return TRUE;
176 if (delay)
177 udelay(1000);
178 if (--timeout == 0)
179 return FALSE;
180 }
181 }
182
183 static void buslogic_prefix(void)
184 {
185 printk("BusLogic SCSI: ");
186 }
187
188 #if BUSLOGIC_DEBUG
189 static void buslogic_stat(unsigned int base)
190 {
191 int s = inb(STATUS(base)), i = inb(INTERRUPT(base));
192
193 printk("status=%02X intrflags=%02X\n", s, i);
194 }
195 #else
196 # define buslogic_stat(base)
197 #endif
198
199
200
201
202
203 static int buslogic_out(unsigned int base, const unsigned char *cmdp,
204 size_t len)
205 {
206 if (len == 1) {
207 for (;;) {
208 WAIT_WHILE(STATUS(base), CPRBSY);
209 cli();
210 if (!(inb(STATUS(base)) & CPRBSY)) {
211 outb(*cmdp, COMMAND_PARAMETER(base));
212 sti();
213 return FALSE;
214 }
215 sti();
216 }
217 } else {
218 cli();
219 while (len--) {
220 WAIT_WHILE(STATUS(base), CPRBSY);
221 outb(*cmdp++, COMMAND_PARAMETER(base));
222 }
223 sti();
224 }
225 return FALSE;
226 fail:
227 sti();
228 buslogic_printk("buslogic_out failed(%u): ", len + 1);
229 buslogic_stat(base);
230 return TRUE;
231 }
232
233
234
235 static int buslogic_in(unsigned int base, unsigned char *cmdp, size_t len)
236 {
237 cli();
238 while (len--) {
239 WAIT_UNTIL(STATUS(base), DIRRDY);
240 *cmdp++ = inb(DATA_IN(base));
241 }
242 sti();
243 return FALSE;
244 fail:
245 sti();
246 buslogic_printk("buslogic_in failed(%u): ", len + 1);
247 buslogic_stat(base);
248 return TRUE;
249 }
250
251 #if 0
252
253
254
255 static int buslogic_in_fast(unsigned int base, unsigned char *cmdp, size_t len)
256 {
257 cli();
258 while (len--) {
259 WAIT_UNTIL_FAST(STATUS(base), DIRRDY);
260 *cmdp++ = inb(DATA_IN(base));
261 }
262 sti();
263 return FALSE;
264 fail:
265 sti();
266 return TRUE;
267 }
268 #endif
269
270 static unsigned int makecode(unsigned int hosterr, unsigned int scsierr)
271 {
272 switch (hosterr) {
273 case 0x00:
274 case 0x0A:
275
276 case 0x0B:
277
278 hosterr = DID_OK;
279 break;
280
281 case 0x11:
282
283
284 hosterr = DID_TIME_OUT;
285 break;
286
287 case 0x14:
288
289
290
291
292 hosterr = DID_RESET;
293 break;
294
295 case 0x12:
296
297
298
299 case 0x13:
300
301 case 0x15:
302
303
304 case 0x16:
305
306
307 case 0x17:
308
309
310
311 case 0x18:
312
313 case 0x19:
314
315
316
317 case 0x1A:
318
319
320
321 case 0x1B:
322 case 0x1C:
323
324 case 0x20:
325 case 0x21:
326
327
328 case 0x22:
329 case 0x23:
330 #if BUSLOGIC_DEBUG
331 buslogic_printk("%X %X\n", hosterr, scsierr);
332 #endif
333 hosterr = DID_ERROR;
334 break;
335
336 default:
337 buslogic_printk("makecode: unknown hoststatus %X\n", hosterr);
338 break;
339 }
340 return (hosterr << 16) | scsierr;
341 }
342
343 static int test_port(unsigned int base, struct Scsi_Host *shpnt)
344 {
345 unsigned int i;
346 unsigned char inquiry_cmd[] = { CMD_INQUIRY };
347 unsigned char inquiry_result[4];
348 unsigned char *cmdp;
349 int len;
350 volatile int debug = 0;
351
352
353 if (inb(STATUS(base)) == 0xFF)
354 return TRUE;
355
356
357
358
359 #if BUSLOGIC_DEBUG
360 buslogic_printk("test_port called\n");
361 #endif
362
363
364 INTR_RESET(base);
365
366 outb(RSOFT | RINT, CONTROL(base));
367
368
369 i = jiffies + 2;
370 while (i > jiffies);
371
372 debug = 1;
373
374 WAIT(STATUS(base), STATMASK, INREQ | HARDY,
375 DACT | DFAIL | CMDINV | DIRRDY | CPRBSY);
376
377 debug = 2;
378
379 if (inb(INTERRUPT(base)) & INTRMASK)
380 goto fail;
381
382
383
384 buslogic_out(base, inquiry_cmd, 1);
385
386 debug = 3;
387 len = 4;
388 cmdp = &inquiry_result[0];
389 while (len--) {
390 WAIT(STATUS(base), DIRRDY, DIRRDY, 0);
391 *cmdp++ = inb(DATA_IN(base));
392 }
393
394 debug = 4;
395
396 if (inb(STATUS(base)) & DIRRDY)
397 goto fail;
398
399 debug = 5;
400
401 WAIT_UNTIL(INTERRUPT(base), CMDC);
402
403
404
405 debug = 6;
406
407 outb(RINT, CONTROL(base));
408
409 debug = 7;
410
411 return FALSE;
412 fail:
413 return TRUE;
414 }
415
416 const char *buslogic_info(void)
417 {
418 return "BusLogic SCSI Driver version " BUSLOGIC_VERSION;
419 }
420
421
422 static void buslogic_interrupt(int junk)
423 {
424 void (*my_done)(Scsi_Cmnd *) = NULL;
425 int errstatus, mbistatus = MBX_NOT_IN_USE, number_serviced, found;
426 size_t mbi, mbo = 0;
427 struct Scsi_Host *shpnt;
428 Scsi_Cmnd *sctmp;
429 int irqno, base, flag;
430 int needs_restart;
431 struct mailbox *mb;
432 struct ccb *ccb;
433
434
435 irqno = ((int *)junk)[-2];
436
437 shpnt = host[irqno - 9];
438 if (!shpnt)
439 panic("buslogic.c: NULL SCSI host entry");
440
441 mb = HOSTDATA(shpnt)->mb;
442 ccb = HOSTDATA(shpnt)->ccbs;
443 base = shpnt->io_port;
444
445 #if BUSLOGIC_DEBUG
446 flag = inb(INTERRUPT(base));
447
448 buslogic_printk("buslogic_interrupt: ");
449 if (!(flag & INTV))
450 printk("no interrupt? ");
451 if (flag & IMBL)
452 printk("IMBL ");
453 if (flag & MBOR)
454 printk("MBOR ");
455 if (flag & CMDC)
456 printk("CMDC ");
457 if (flag & RSTS)
458 printk("RSTS ");
459 printk("status %02X\n", inb(STATUS(base)));
460 #endif
461
462 number_serviced = 0;
463 needs_restart = 0;
464
465 for (;;) {
466 flag = inb(INTERRUPT(base));
467
468
469
470
471
472 if (flag & ~IMBL) {
473 if (flag & MBOR)
474 printk("MBOR ");
475 if (flag & CMDC)
476 printk("CMDC ");
477 if (flag & RSTS) {
478 needs_restart = 1;
479 printk("RSTS ");
480 }
481 }
482
483 INTR_RESET(base);
484
485 cli();
486
487 mbi = HOSTDATA(shpnt)->last_mbi_used + 1;
488 if (mbi >= 2 * BUSLOGIC_MAILBOXES)
489 mbi = BUSLOGIC_MAILBOXES;
490
491
492
493
494 found = FALSE;
495 do {
496 if (mb[mbi].status != MBX_NOT_IN_USE) {
497 found = TRUE;
498 break;
499 }
500 mbi++;
501 if (mbi >= 2 * BUSLOGIC_MAILBOXES)
502 mbi = BUSLOGIC_MAILBOXES;
503 } while (mbi != HOSTDATA(shpnt)->last_mbi_used);
504
505 if (found) {
506 mbo = (struct ccb *)mb[mbi].ccbptr - ccb;
507 mbistatus = mb[mbi].status;
508 mb[mbi].status = MBX_NOT_IN_USE;
509 HOSTDATA(shpnt)->last_mbi_used = mbi;
510 }
511
512 sti();
513
514 if (!found) {
515
516 if (!number_serviced && !needs_restart)
517 buslogic_printk("interrupt received, but no mail.\n");
518
519
520 if (needs_restart)
521 restart(shpnt);
522 return;
523 }
524
525 #if BUSLOGIC_DEBUG
526 if (ccb[mbo].tarstat || ccb[mbo].hastat)
527 buslogic_printk("buslogic_interrupt: returning %08X (status %d)\n",
528 ((int)ccb[mbo].hastat << 16) | ccb[mbo].tarstat,
529 mb[mbi].status);
530 #endif
531
532 if (mbistatus == MBX_COMPLETION_NOT_FOUND)
533 continue;
534
535 #if BUSLOGIC_DEBUG
536 buslogic_printk("...done %u %u\n", mbo, mbi);
537 #endif
538
539 sctmp = HOSTDATA(shpnt)->sc[mbo];
540
541 if (!sctmp || !sctmp->scsi_done) {
542 buslogic_printk("buslogic_interrupt: Unexpected interrupt\n");
543 buslogic_printk("tarstat=%02X, hastat=%02X id=%d lun=%d ccb#=%d\n",
544 ccb[mbo].tarstat, ccb[mbo].hastat,
545 ccb[mbo].id, ccb[mbo].lun, mbo);
546 return;
547 }
548
549 my_done = sctmp->scsi_done;
550 if (sctmp->host_scribble)
551 scsi_free(sctmp->host_scribble, BUSLOGIC_SG_MALLOC);
552
553 #if 0
554
555
556
557 if (ccb[mbo].tarstat == 2)
558 memcpy(sctmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
559 sizeof sctmp->sense_buffer);
560 #endif
561
562
563 if (mbistatus != MBX_COMPLETION_OK)
564
565 errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
566 else
567 errstatus = 0;
568
569 #if BUSLOGIC_DEBUG
570 if (errstatus)
571 buslogic_printk("error: %08X %04X %04X\n",
572 errstatus, ccb[mbo].hastat, ccb[mbo].tarstat);
573
574 if (status_byte(ccb[mbo].tarstat) == CHECK_CONDITION) {
575 size_t i;
576
577 buslogic_printk("buslogic_interrupt: sense:");
578 for (i = 0; i < sizeof sctmp->sense_buffer; i++)
579 printk(" %02X", sctmp->sense_buffer[i]);
580 printk("\n");
581 }
582
583 if (errstatus)
584 buslogic_printk("buslogic_interrupt: returning %08X\n", errstatus);
585 #endif
586
587 sctmp->result = errstatus;
588 HOSTDATA(shpnt)->sc[mbo] = NULL;
589
590
591
592 my_done(sctmp);
593 number_serviced++;
594 }
595 }
596
597 int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
598 {
599 static const unsigned char buscmd[] = { CMD_START_SCSI };
600 unsigned char direction;
601 unsigned char *cmd = (unsigned char *)scpnt->cmnd;
602 unsigned char target = scpnt->target;
603 unsigned char lun = scpnt->lun;
604 void *buff = scpnt->request_buffer;
605 int bufflen = scpnt->request_bufflen;
606 int mbo;
607 struct mailbox *mb;
608 struct ccb *ccb;
609
610 #if BUSLOGIC_DEBUG
611 if (target > 1) {
612 scpnt->result = DID_TIME_OUT << 16;
613 done(scpnt);
614 return 0;
615 }
616 #endif
617
618 if (*cmd == REQUEST_SENSE) {
619 #ifndef DEBUG
620 if (bufflen != sizeof scpnt->sense_buffer) {
621 buslogic_printk("Wrong buffer length supplied for request sense"
622 " (%d)\n",
623 bufflen);
624 }
625 #endif
626 scpnt->result = 0;
627 done(scpnt);
628 return 0;
629 }
630
631 #if BUSLOGIC_DEBUG
632 {
633 int i;
634
635 if (*cmd == READ_10 || *cmd == WRITE_10
636 || *cmd == READ_6 || *cmd == WRITE_6)
637 i = *(int *)(cmd + 2);
638 else
639 i = -1;
640 buslogic_printk("buslogic_queuecommand:"
641 " dev %d cmd %02X pos %d len %d ",
642 target, *cmd, i, bufflen);
643 buslogic_stat(scpnt->host->io_port);
644 buslogic_printk("buslogic_queuecommand: dumping scsi cmd:");
645 for (i = 0; i < (COMMAND_SIZE(*cmd)); i++)
646 printk(" %02X", cmd[i]);
647 printk("\n");
648 if (*cmd == WRITE_10 || *cmd == WRITE_6)
649 return 0;
650 }
651 #endif
652
653 mb = HOSTDATA(scpnt->host)->mb;
654 ccb = HOSTDATA(scpnt->host)->ccbs;
655
656
657
658
659 cli();
660
661 mbo = HOSTDATA(scpnt->host)->last_mbo_used + 1;
662 if (mbo >= BUSLOGIC_MAILBOXES)
663 mbo = 0;
664
665 do {
666 if (mb[mbo].status == MBX_NOT_IN_USE
667 && HOSTDATA(scpnt->host)->sc[mbo] == NULL)
668 break;
669 mbo++;
670 if (mbo >= BUSLOGIC_MAILBOXES)
671 mbo = 0;
672 } while (mbo != HOSTDATA(scpnt->host)->last_mbo_used);
673
674 if (mb[mbo].status != MBX_NOT_IN_USE
675 || HOSTDATA(scpnt->host)->sc[mbo]) {
676
677
678 panic("buslogic.c: unable to find empty mailbox");
679 }
680
681 HOSTDATA(scpnt->host)->sc[mbo] = scpnt;
682
683
684
685 HOSTDATA(scpnt->host)->last_mbo_used = mbo;
686
687 sti();
688
689 #if BUSLOGIC_DEBUG
690 buslogic_printk("sending command (%d %08X)...", mbo, done);
691 #endif
692
693
694 mb[mbo].ccbptr = &ccb[mbo];
695
696 memset(&ccb[mbo], 0, sizeof (struct ccb));
697
698 ccb[mbo].cdblen = COMMAND_SIZE(*cmd);
699
700
701 direction = 0;
702 if (*cmd == READ_10 || *cmd == READ_6)
703 direction = 8;
704 else if (*cmd == WRITE_10 || *cmd == WRITE_6)
705 direction = 16;
706
707 memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
708
709 if (scpnt->use_sg) {
710 struct scatterlist *sgpnt;
711 struct chain *cptr;
712 size_t i;
713
714 ccb[mbo].op = CCB_OP_INIT_SG;
715
716 scpnt->host_scribble
717 = (unsigned char *)scsi_malloc(BUSLOGIC_SG_MALLOC);
718 if (scpnt->host_scribble == NULL)
719 panic("buslogic.c: unable to allocate DMA memory");
720 sgpnt = (struct scatterlist *)scpnt->request_buffer;
721 cptr = (struct chain *)scpnt->host_scribble;
722 if (scpnt->use_sg > scpnt->host->sg_tablesize) {
723 buslogic_printk("buslogic_queuecommand: bad segment list,"
724 " %d > %d\n",
725 scpnt->use_sg, scpnt->host->sg_tablesize);
726 panic("buslogic.c: bad segment list");
727 }
728 for (i = 0; i < scpnt->use_sg; i++) {
729 cptr[i].dataptr = sgpnt[i].address;
730 cptr[i].datalen = sgpnt[i].length;
731 }
732 ccb[mbo].datalen = scpnt->use_sg * sizeof (struct chain);
733 ccb[mbo].dataptr = cptr;
734 #if BUSLOGIC_DEBUG
735 {
736 unsigned char *ptr;
737
738 buslogic_printk("cptr %08X:", cptr);
739 ptr = (unsigned char *)cptr;
740 for (i = 0; i < 18; i++)
741 printk(" %02X", ptr[i]);
742 printk("\n");
743 }
744 #endif
745 } else {
746 ccb[mbo].op = CCB_OP_INIT;
747 scpnt->host_scribble = NULL;
748 ccb[mbo].datalen = bufflen;
749 ccb[mbo].dataptr = buff;
750 }
751 ccb[mbo].id = target;
752 ccb[mbo].lun = lun;
753 ccb[mbo].dir = direction;
754 ccb[mbo].rsalen = sizeof scpnt->sense_buffer;
755 ccb[mbo].senseptr = scpnt->sense_buffer;
756 ccb[mbo].linkptr = NULL;
757 ccb[mbo].commlinkid = 0;
758
759 #if BUSLOGIC_DEBUG
760 {
761 size_t i;
762
763 buslogic_printk("buslogic_queuecommand: sending...");
764 for (i = 0; i < sizeof ccb[mbo] - 10; i++)
765 printk(" %02X", ((unsigned char *)&ccb[mbo])[i]);
766 printk("\n");
767 }
768 #endif
769
770 if (done) {
771 #if BUSLOGIC_DEBUG
772 buslogic_printk("buslogic_queuecommand: now waiting for interrupt: ");
773 buslogic_stat(scpnt->host->io_port);
774 #endif
775 scpnt->scsi_done = done;
776 mb[mbo].status = MBX_ACTION_START;
777
778 buslogic_out(scpnt->host->io_port, buscmd, sizeof buscmd);
779 #if BUSLOGIC_DEBUG
780 buslogic_stat(scpnt->host->io_port);
781 #endif
782 } else
783 buslogic_printk("buslogic_queuecommand: done can't be NULL\n");
784
785 return 0;
786 }
787
788 #if 0
789 static void internal_done(Scsi_Cmnd *scpnt)
790 {
791 scpnt->SCp.Status++;
792 }
793
794 int buslogic_command(Scsi_Cmnd *scpnt)
795 {
796 #if BUSLOGIC_DEBUG
797 buslogic_printk("buslogic_command: ..calling buslogic_queuecommand\n");
798 #endif
799
800 buslogic_queuecommand(scpnt, internal_done);
801
802 scpnt->SCp.Status = 0;
803 while (!scpnt->SCp.Status)
804 continue;
805 return scpnt->result;
806 }
807 #endif
808
809
810 static int setup_mailboxes(unsigned int base, struct Scsi_Host *shpnt)
811 {
812 size_t i;
813 int ok = FALSE;
814 struct mailbox *mb = HOSTDATA(shpnt)->mb;
815 struct ccb *ccb = HOSTDATA(shpnt)->ccbs;
816 struct {
817 unsigned char cmd, count;
818 void *base PACKED;
819 } cmd = { CMD_INITEXTMB, BUSLOGIC_MAILBOXES, mb };
820
821 for (i = 0; i < BUSLOGIC_MAILBOXES; i++) {
822 mb[i].status = mb[BUSLOGIC_MAILBOXES + i].status = MBX_NOT_IN_USE;
823 mb[i].ccbptr = &ccb[i];
824 }
825 INTR_RESET(base);
826
827
828 if (buslogic_out(base, (unsigned char *)&cmd, sizeof cmd))
829 goto must_be_adaptec;
830
831
832
833
834 WAIT_UNTIL(STATUS(base), HARDY);
835 if (inb(STATUS(base)) & CMDINV)
836 goto must_be_adaptec;
837
838 WAIT_UNTIL(INTERRUPT(base), CMDC);
839 while (0) {
840 fail:
841 buslogic_printk("buslogic_detect: failed setting up mailboxes\n");
842 }
843 ok = TRUE;
844 must_be_adaptec:
845 INTR_RESET(base);
846 if (!ok)
847 printk("- must be Adaptec\n");
848
849 return ok;
850 }
851
852 static int getconfig(unsigned int base, unsigned char *irq,
853 unsigned char *dma, unsigned char *id,
854 unsigned char *bus_type, unsigned short *max_sg)
855 {
856 unsigned char inquiry_cmd[2];
857 unsigned char inquiry_result[4];
858 int i;
859
860 i = inb(STATUS(base));
861 if (i & DIRRDY)
862 i = inb(DATA_IN(base));
863 inquiry_cmd[0] = CMD_RETCONF;
864 buslogic_out(base, inquiry_cmd, 1);
865 buslogic_in(base, inquiry_result, 3);
866 WAIT_UNTIL(INTERRUPT(base), CMDC);
867 INTR_RESET(base);
868
869 *dma = inquiry_result[0];
870 switch (inquiry_result[1]) {
871 case 0x01:
872 *irq = 9;
873 break;
874 case 0x02:
875 *irq = 10;
876 break;
877 case 0x04:
878 *irq = 11;
879 break;
880 case 0x08:
881 *irq = 12;
882 break;
883 case 0x20:
884 *irq = 14;
885 break;
886 case 0x40:
887 *irq = 15;
888 break;
889 default:
890 buslogic_printk("Unable to determine BusLogic IRQ level."
891 " Disabling board.\n");
892 return TRUE;
893 }
894 *id = inquiry_result[2] & 0x7;
895
896 inquiry_cmd[0] = CMD_INQEXTSETUP;
897 inquiry_cmd[1] = 4;
898 if (buslogic_out(base, inquiry_cmd, 2)
899 || buslogic_in(base, inquiry_result, 4))
900 return TRUE;
901 WAIT_UNTIL(INTERRUPT(base), CMDC);
902 INTR_RESET(base);
903
904 #ifdef BUSLOGIC_BUS_TYPE_OVERRIDE
905 *bus_type = BUS_TYPE_OVERRIDE;
906 #else
907 *bus_type = inquiry_result[0];
908 #endif
909 CHECK(*bus_type == 'A' || *bus_type == 'E' || *bus_type == 'M');
910 #ifdef BUSLOGIC_BUS_TYPE_OVERRIDE
911 if (inquiry_result[0] != BUS_TYPE_OVERRIDE)
912 buslogic_printk("Overriding bus type %c with %c\n",
913 inquiry_result[0], BUS_TYPE_OVERRIDE);
914 #endif
915 *max_sg = (inquiry_result[3] << 8) | inquiry_result[2];
916
917
918
919
920
921 if (*bus_type == 'A')
922 switch (*dma) {
923 case 0:
924 *dma = 0;
925 break;
926 case 0x20:
927 *dma = 5;
928 break;
929 case 0x40:
930 *dma = 6;
931 break;
932 case 0x80:
933 *dma = 7;
934 break;
935 default:
936 buslogic_printk("Unable to determine BusLogic DMA channel."
937 " Disabling board.\n");
938 return TRUE;
939 }
940 else
941 *dma = 0;
942
943 while (0) {
944 fail:
945 buslogic_printk("buslogic_detect: query board settings\n");
946 return TRUE;
947 }
948
949 return FALSE;
950 }
951
952 static int get_translation(unsigned int base)
953 {
954
955
956
957
958
959
960 return BIOS_TRANSLATION_BIG;
961 }
962
963
964 static int buslogic_query(unsigned int base, int *trans)
965 {
966 static const unsigned char inquiry_cmd[] = { CMD_INQUIRY };
967 unsigned char inquiry_result[4];
968 int i;
969
970 i = inb(STATUS(base));
971 if (i & DIRRDY)
972 i = inb(DATA_IN(base));
973 buslogic_out(base, inquiry_cmd, sizeof inquiry_cmd);
974 buslogic_in(base, inquiry_result, 4);
975 WAIT_UNTIL(INTERRUPT(base), CMDC);
976 INTR_RESET(base);
977
978 #if 1
979 buslogic_printk("Inquiry Bytes: %02X %02X %02X %02X\n",
980 inquiry_result[0], inquiry_result[1],
981 inquiry_result[2], inquiry_result[3]);
982 #endif
983
984 while (0) {
985 fail:
986 buslogic_printk("buslogic_query: query board settings\n");
987 return TRUE;
988 }
989
990 *trans = get_translation(base);
991
992 return FALSE;
993 }
994
995
996 int buslogic_detect(Scsi_Host_Template *tpnt)
997 {
998 unsigned char dma;
999 unsigned char irq;
1000 unsigned int base = 0;
1001 unsigned char id;
1002 unsigned char bus_type;
1003 unsigned short max_sg;
1004 int trans;
1005 struct Scsi_Host *shpnt = NULL;
1006 int count = 0;
1007 int indx;
1008
1009 #if BUSLOGIC_DEBUG
1010 buslogic_printk("buslogic_detect:\n");
1011 #endif
1012
1013 for (indx = 0; indx < ARRAY_SIZE(bases); indx++)
1014 if (!check_region(bases[indx], 3)) {
1015 shpnt = scsi_register(tpnt, sizeof (struct hostdata));
1016
1017 base = bases[indx];
1018
1019 if (test_port(base, shpnt))
1020 goto unregister;
1021
1022
1023 {
1024
1025 static const unsigned char oncmd[] = { CMD_BUSON_TIME, 7 };
1026 static const unsigned char offcmd[] = { CMD_BUSOFF_TIME, 5 };
1027
1028 INTR_RESET(base);
1029 buslogic_out(base, oncmd, sizeof oncmd);
1030 WAIT_UNTIL(INTERRUPT(base), CMDC);
1031
1032
1033
1034 INTR_RESET(base);
1035 buslogic_out(base, offcmd, sizeof offcmd);
1036 WAIT_UNTIL(INTERRUPT(base), CMDC);
1037 while (0) {
1038 fail:
1039 buslogic_printk("buslogic_detect:"
1040 " setting bus on/off-time failed\n");
1041 }
1042 INTR_RESET(base);
1043 }
1044
1045 if (buslogic_query(base, &trans))
1046 goto unregister;
1047
1048 if (getconfig(base, &irq, &dma, &id, &bus_type, &max_sg))
1049 goto unregister;
1050
1051 #if BUSLOGIC_DEBUG
1052 buslogic_stat(base);
1053 #endif
1054
1055
1056 if (!setup_mailboxes(base, shpnt))
1057 goto unregister;
1058
1059 printk("Configuring BusLogic %s HA at port 0x%03X, IRQ %u",
1060 (bus_type == 'A' ? "ISA"
1061 : (bus_type == 'E' ? "EISA/VESA" : "MCA")),
1062 base, irq);
1063 if (dma != 0)
1064 printk(", DMA %u", dma);
1065 printk(", ID %u\n", id);
1066
1067 #if BUSLOGIC_DEBUG
1068 buslogic_stat(base);
1069 #endif
1070
1071 #if BUSLOGIC_DEBUG
1072 buslogic_printk("buslogic_detect: enable interrupt channel %d\n",
1073 irq);
1074 #endif
1075
1076 cli();
1077 if (request_irq(irq, buslogic_interrupt, 0, "buslogic")) {
1078 buslogic_printk("Unable to allocate IRQ for "
1079 "BusLogic controller.\n");
1080 sti();
1081 goto unregister;
1082 }
1083
1084 if (dma) {
1085 if (request_dma(dma,"buslogic")) {
1086 buslogic_printk("Unable to allocate DMA channel for "
1087 "BusLogic controller.\n");
1088 free_irq(irq);
1089 sti();
1090 goto unregister;
1091 }
1092
1093 if (dma >= 5) {
1094 outb((dma - 4) | CASCADE, DMA_MODE_REG);
1095 outb(dma - 4, DMA_MASK_REG);
1096 }
1097 }
1098
1099 host[irq - 9] = shpnt;
1100 shpnt->this_id = id;
1101 #ifdef CONFIG_NO_BUGGY_BUSLOGIC
1102
1103 shpnt->unchecked_isa_dma = (bus_type == 'A');
1104 #else
1105
1106
1107 shpnt->unchecked_isa_dma = 1;
1108 #endif
1109 shpnt->sg_tablesize = max_sg;
1110 if (shpnt->sg_tablesize > BUSLOGIC_MAX_SG)
1111 shpnt->sg_tablesize = BUSLOGIC_MAX_SG;
1112
1113
1114 shpnt->hostt->can_queue = BUSLOGIC_MAILBOXES;
1115
1116
1117 shpnt->base = NULL;
1118 shpnt->io_port = base;
1119 shpnt->dma_channel = dma;
1120 shpnt->irq = irq;
1121 HOSTDATA(shpnt)->bios_translation = trans;
1122 if (trans == BIOS_TRANSLATION_BIG)
1123 buslogic_printk("Using extended bios translation.\n");
1124 HOSTDATA(shpnt)->last_mbi_used = 2 * BUSLOGIC_MAILBOXES - 1;
1125 HOSTDATA(shpnt)->last_mbo_used = BUSLOGIC_MAILBOXES - 1;
1126 memset(HOSTDATA(shpnt)->sc, 0, sizeof HOSTDATA(shpnt)->sc);
1127 sti();
1128
1129 #if 0
1130 {
1131 unsigned char buf[8];
1132 unsigned char cmd[]
1133 = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1134 size_t i;
1135
1136 #if BUSLOGIC_DEBUG
1137 buslogic_printk("*** READ CAPACITY ***\n");
1138 #endif
1139 for (i = 0; i < sizeof buf; i++)
1140 buf[i] = 0x87;
1141 for (i = 0; i < 2; i++)
1142 if (!buslogic_command(i, cmd, buf, sizeof buf)) {
1143 buslogic_printk("buslogic_detect: LU %u "
1144 "sector_size %d device_size %d\n",
1145 i, *(int *)(buf + 4), *(int *)buf);
1146 }
1147
1148 #if BUSLOGIC_DEBUG
1149 buslogic_printk("*** NOW RUNNING MY OWN TEST ***\n");
1150 #endif
1151 for (i = 0; i < 4; i++) {
1152 static buffer[512];
1153
1154 cmd[0] = READ_10;
1155 cmd[1] = 0;
1156 xany2scsi(cmd + 2, i);
1157 cmd[6] = 0;
1158 cmd[7] = 0;
1159 cmd[8] = 1;
1160 cmd[9] = 0;
1161 buslogic_command(0, cmd, buffer, sizeof buffer);
1162 }
1163 }
1164 #endif
1165
1166 snarf_region(bases[indx], 3);
1167
1168 count++;
1169 continue;
1170 unregister:
1171 scsi_unregister(shpnt);
1172 }
1173 return count;
1174 }
1175
1176 static int restart(struct Scsi_Host *shpnt)
1177 {
1178 unsigned int i;
1179 unsigned int count = 0;
1180 #if 0
1181 static const unsigned char buscmd[] = { CMD_START_SCSI };
1182 #endif
1183
1184 for (i = 0; i < BUSLOGIC_MAILBOXES; i++)
1185 if (HOSTDATA(shpnt)->sc[i]
1186 && !HOSTDATA(shpnt)->sc[i]->device->soft_reset) {
1187 #if 0
1188 HOSTDATA(shpnt)->mb[i].status
1189 = MBX_ACTION_START;
1190 #endif
1191 count++;
1192 }
1193
1194 buslogic_printk("Potential to restart %d stalled commands...\n", count);
1195 #if 0
1196
1197 if (count)
1198 buslogic_out(shpnt->host->io_port, buscmd, sizeof buscmd);
1199 #endif
1200 return 0;
1201 }
1202
1203
1204
1205
1206
1207 int buslogic_abort(Scsi_Cmnd *scpnt)
1208 {
1209 #if 1
1210 static const unsigned char buscmd[] = { CMD_START_SCSI };
1211 struct mailbox *mb;
1212 size_t mbi, mbo;
1213 unsigned int i;
1214
1215 buslogic_printk("buslogic_abort: %X %X\n",
1216 inb(STATUS(scpnt->host->io_port)),
1217 inb(INTERRUPT(scpnt->host->io_port)));
1218
1219 cli();
1220 mb = HOSTDATA(scpnt->host)->mb;
1221 mbi = HOSTDATA(scpnt->host)->last_mbi_used + 1;
1222 if (mbi >= 2 * BUSLOGIC_MAILBOXES)
1223 mbi = BUSLOGIC_MAILBOXES;
1224
1225 do {
1226 if (mb[mbi].status != MBX_NOT_IN_USE)
1227 break;
1228 mbi++;
1229 if (mbi >= 2 * BUSLOGIC_MAILBOXES)
1230 mbi = BUSLOGIC_MAILBOXES;
1231 } while (mbi != HOSTDATA(scpnt->host)->last_mbi_used);
1232 sti();
1233
1234 if (mb[mbi].status != MBX_NOT_IN_USE) {
1235 buslogic_printk("Lost interrupt discovered on irq %d"
1236 " - attempting to recover\n",
1237 scpnt->host->irq);
1238 {
1239 int intval[3];
1240
1241 intval[0] = scpnt->host->irq;
1242 buslogic_interrupt((int)&intval[2]);
1243 return SCSI_ABORT_SUCCESS;
1244 }
1245 }
1246
1247
1248
1249 for (i = 0; i < BUSLOGIC_MAILBOXES; i++)
1250 if (HOSTDATA(scpnt->host)->sc[i]) {
1251 if (HOSTDATA(scpnt->host)->sc[i] == scpnt) {
1252 buslogic_printk("Timed out command pending for %4.4X\n",
1253 scpnt->request.dev);
1254 if (HOSTDATA(scpnt->host)->mb[i].status != MBX_NOT_IN_USE) {
1255 buslogic_printk("OGMB still full - restarting\n");
1256 buslogic_out(scpnt->host->io_port, buscmd, sizeof buscmd);
1257 }
1258 } else
1259 buslogic_printk("Other pending command %4.4X\n",
1260 scpnt->request.dev);
1261 }
1262 #endif
1263
1264 #if (BUSLOGIC_DEBUG & BD_ABORT)
1265 buslogic_printk("buslogic_abort\n");
1266 #endif
1267
1268 #if 1
1269
1270
1271 cli();
1272 for (mbo = 0; mbo < BUSLOGIC_MAILBOXES; mbo++)
1273 if (scpnt == HOSTDATA(scpnt->host)->sc[mbo]) {
1274 mb[mbo].status = MBX_ACTION_ABORT;
1275 buslogic_out(scpnt->host->io_port, buscmd, sizeof buscmd);
1276 break;
1277 }
1278 sti();
1279 #endif
1280
1281 return SCSI_ABORT_SNOOZE;
1282 }
1283
1284
1285
1286
1287
1288
1289 int buslogic_reset(Scsi_Cmnd *scpnt)
1290 {
1291 static const unsigned char buscmd[] = { CMD_START_SCSI };
1292 unsigned int i;
1293
1294 #if BUSLOGIC_DEBUG
1295 buslogic_printk("buslogic_reset\n");
1296 #endif
1297 #if 0
1298
1299 outb(RSBUS, CONTROL(scpnt->host->io_port));
1300 #else
1301
1302
1303 for (i = 0; i < BUSLOGIC_MAILBOXES; i++)
1304 if (HOSTDATA(scpnt->host)->sc[i] == scpnt) {
1305 HOSTDATA(scpnt->host)->ccbs[i].op = 0x81;
1306
1307
1308
1309
1310 buslogic_out(scpnt->host->io_port, buscmd, sizeof buscmd);
1311
1312
1313
1314
1315
1316 buslogic_printk("Sent BUS DEVICE RESET to target %d\n",
1317 scpnt->target);
1318
1319
1320
1321
1322 #if 1
1323 for (i = 0; i < BUSLOGIC_MAILBOXES; i++)
1324 if (HOSTDATA(scpnt->host)->sc[i]
1325 && HOSTDATA(scpnt->host)->sc[i]->target == scpnt->target) {
1326 Scsi_Cmnd *sctmp = HOSTDATA(scpnt->host)->sc[i];
1327
1328 sctmp->result = DID_RESET << 16;
1329 if (sctmp->host_scribble)
1330 scsi_free(sctmp->host_scribble, BUSLOGIC_SG_MALLOC);
1331 printk("Sending DID_RESET for target %d\n", scpnt->target);
1332 sctmp->scsi_done(scpnt);
1333
1334 HOSTDATA(scpnt->host)->sc[i] = NULL;
1335 HOSTDATA(scpnt->host)->mb[i].status = MBX_NOT_IN_USE;
1336 }
1337 return SCSI_RESET_SUCCESS;
1338 #else
1339 return SCSI_RESET_PENDING;
1340 #endif
1341 }
1342 #endif
1343
1344
1345
1346 return SCSI_RESET_PUNT;
1347 }
1348
1349 int buslogic_biosparam(Disk *disk, int dev, int *ip)
1350 {
1351
1352 unsigned int mb = disk->capacity >> 11;
1353
1354
1355 if (HOSTDATA(disk->device->host)->bios_translation == BIOS_TRANSLATION_BIG
1356 && mb > 1024) {
1357 if (mb > 4096) {
1358 ip[0] = 256;
1359 ip[1] = 64;
1360 ip[2] = mb >> 3;
1361
1362
1363 } else if (mb > 2048) {
1364 ip[0] = 256;
1365 ip[1] = 32;
1366 ip[2] = mb >> 2;
1367 } else {
1368 ip[0] = 128;
1369 ip[1] = 32;
1370 ip[2] = mb >> 1;
1371 }
1372 } else {
1373 ip[0] = 64;
1374 ip[1] = 32;
1375 ip[2] = mb;
1376
1377
1378 }
1379 return 0;
1380 }