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