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