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