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