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