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#define blogic_drvr_version "2.1.17"
30#define blogic_drvr_date "12 September 2013"
31
32#include <linux/module.h>
33#include <linux/init.h>
34#include <linux/interrupt.h>
35#include <linux/types.h>
36#include <linux/blkdev.h>
37#include <linux/delay.h>
38#include <linux/ioport.h>
39#include <linux/mm.h>
40#include <linux/stat.h>
41#include <linux/pci.h>
42#include <linux/spinlock.h>
43#include <linux/jiffies.h>
44#include <linux/dma-mapping.h>
45#include <linux/slab.h>
46#include <scsi/scsicam.h>
47
48#include <asm/dma.h>
49#include <asm/io.h>
50
51#include <scsi/scsi.h>
52#include <scsi/scsi_cmnd.h>
53#include <scsi/scsi_device.h>
54#include <scsi/scsi_host.h>
55#include <scsi/scsi_tcq.h>
56#include "BusLogic.h"
57#include "FlashPoint.c"
58
59#ifndef FAILURE
60#define FAILURE (-1)
61#endif
62
63static struct scsi_host_template blogic_template;
64
65
66
67
68
69
70
71static int blogic_drvr_options_count;
72
73
74
75
76
77
78
79
80static struct blogic_drvr_options blogic_drvr_options[BLOGIC_MAX_ADAPTERS];
81
82
83
84
85
86
87MODULE_LICENSE("GPL");
88#ifdef MODULE
89static char *BusLogic;
90module_param(BusLogic, charp, 0);
91#endif
92
93
94
95
96
97
98
99static struct blogic_probe_options blogic_probe_options;
100
101
102
103
104
105
106
107static struct blogic_global_options blogic_global_options;
108
109static LIST_HEAD(blogic_host_list);
110
111
112
113
114
115static int blogic_probeinfo_count;
116
117
118
119
120
121
122
123
124
125static struct blogic_probeinfo *blogic_probeinfo_list;
126
127
128
129
130
131
132
133
134static char *blogic_cmd_failure_reason;
135
136
137
138
139
140
141static void blogic_announce_drvr(struct blogic_adapter *adapter)
142{
143 blogic_announce("***** BusLogic SCSI Driver Version " blogic_drvr_version " of " blogic_drvr_date " *****\n", adapter);
144 blogic_announce("Copyright 1995-1998 by Leonard N. Zubkoff " "<lnz@dandelion.com>\n", adapter);
145}
146
147
148
149
150
151
152
153static const char *blogic_drvr_info(struct Scsi_Host *host)
154{
155 struct blogic_adapter *adapter =
156 (struct blogic_adapter *) host->hostdata;
157 return adapter->full_model;
158}
159
160
161
162
163
164
165
166static void blogic_init_ccbs(struct blogic_adapter *adapter, void *blk_pointer,
167 int blk_size, dma_addr_t blkp)
168{
169 struct blogic_ccb *ccb = (struct blogic_ccb *) blk_pointer;
170 unsigned int offset = 0;
171 memset(blk_pointer, 0, blk_size);
172 ccb->allocgrp_head = blkp;
173 ccb->allocgrp_size = blk_size;
174 while ((blk_size -= sizeof(struct blogic_ccb)) >= 0) {
175 ccb->status = BLOGIC_CCB_FREE;
176 ccb->adapter = adapter;
177 ccb->dma_handle = (u32) blkp + offset;
178 if (blogic_flashpoint_type(adapter)) {
179 ccb->callback = blogic_qcompleted_ccb;
180 ccb->base_addr = adapter->fpinfo.base_addr;
181 }
182 ccb->next = adapter->free_ccbs;
183 ccb->next_all = adapter->all_ccbs;
184 adapter->free_ccbs = ccb;
185 adapter->all_ccbs = ccb;
186 adapter->alloc_ccbs++;
187 ccb++;
188 offset += sizeof(struct blogic_ccb);
189 }
190}
191
192
193
194
195
196
197static bool __init blogic_create_initccbs(struct blogic_adapter *adapter)
198{
199 int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
200 void *blk_pointer;
201 dma_addr_t blkp;
202
203 while (adapter->alloc_ccbs < adapter->initccbs) {
204 blk_pointer = pci_alloc_consistent(adapter->pci_device,
205 blk_size, &blkp);
206 if (blk_pointer == NULL) {
207 blogic_err("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
208 adapter);
209 return false;
210 }
211 blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
212 }
213 return true;
214}
215
216
217
218
219
220
221static void blogic_destroy_ccbs(struct blogic_adapter *adapter)
222{
223 struct blogic_ccb *next_ccb = adapter->all_ccbs, *ccb, *lastccb = NULL;
224 adapter->all_ccbs = NULL;
225 adapter->free_ccbs = NULL;
226 while ((ccb = next_ccb) != NULL) {
227 next_ccb = ccb->next_all;
228 if (ccb->allocgrp_head) {
229 if (lastccb)
230 pci_free_consistent(adapter->pci_device,
231 lastccb->allocgrp_size, lastccb,
232 lastccb->allocgrp_head);
233 lastccb = ccb;
234 }
235 }
236 if (lastccb)
237 pci_free_consistent(adapter->pci_device, lastccb->allocgrp_size,
238 lastccb, lastccb->allocgrp_head);
239}
240
241
242
243
244
245
246
247
248
249static void blogic_create_addlccbs(struct blogic_adapter *adapter,
250 int addl_ccbs, bool print_success)
251{
252 int blk_size = BLOGIC_CCB_GRP_ALLOCSIZE * sizeof(struct blogic_ccb);
253 int prev_alloc = adapter->alloc_ccbs;
254 void *blk_pointer;
255 dma_addr_t blkp;
256 if (addl_ccbs <= 0)
257 return;
258 while (adapter->alloc_ccbs - prev_alloc < addl_ccbs) {
259 blk_pointer = pci_alloc_consistent(adapter->pci_device,
260 blk_size, &blkp);
261 if (blk_pointer == NULL)
262 break;
263 blogic_init_ccbs(adapter, blk_pointer, blk_size, blkp);
264 }
265 if (adapter->alloc_ccbs > prev_alloc) {
266 if (print_success)
267 blogic_notice("Allocated %d additional CCBs (total now %d)\n", adapter, adapter->alloc_ccbs - prev_alloc, adapter->alloc_ccbs);
268 return;
269 }
270 blogic_notice("Failed to allocate additional CCBs\n", adapter);
271 if (adapter->drvr_qdepth > adapter->alloc_ccbs - adapter->tgt_count) {
272 adapter->drvr_qdepth = adapter->alloc_ccbs - adapter->tgt_count;
273 adapter->scsi_host->can_queue = adapter->drvr_qdepth;
274 }
275}
276
277
278
279
280
281
282
283static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
284{
285 static unsigned long serial;
286 struct blogic_ccb *ccb;
287 ccb = adapter->free_ccbs;
288 if (ccb != NULL) {
289 ccb->serial = ++serial;
290 adapter->free_ccbs = ccb->next;
291 ccb->next = NULL;
292 if (adapter->free_ccbs == NULL)
293 blogic_create_addlccbs(adapter, adapter->inc_ccbs,
294 true);
295 return ccb;
296 }
297 blogic_create_addlccbs(adapter, adapter->inc_ccbs, true);
298 ccb = adapter->free_ccbs;
299 if (ccb == NULL)
300 return NULL;
301 ccb->serial = ++serial;
302 adapter->free_ccbs = ccb->next;
303 ccb->next = NULL;
304 return ccb;
305}
306
307
308
309
310
311
312
313
314static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
315{
316 struct blogic_adapter *adapter = ccb->adapter;
317
318 if (ccb->command != NULL)
319 scsi_dma_unmap(ccb->command);
320 if (dma_unmap)
321 pci_unmap_single(adapter->pci_device, ccb->sensedata,
322 ccb->sense_datalen, PCI_DMA_FROMDEVICE);
323
324 ccb->command = NULL;
325 ccb->status = BLOGIC_CCB_FREE;
326 ccb->next = adapter->free_ccbs;
327 adapter->free_ccbs = ccb;
328}
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349static int blogic_cmd(struct blogic_adapter *adapter, enum blogic_opcode opcode,
350 void *param, int paramlen, void *reply, int replylen)
351{
352 unsigned char *param_p = (unsigned char *) param;
353 unsigned char *reply_p = (unsigned char *) reply;
354 union blogic_stat_reg statusreg;
355 union blogic_int_reg intreg;
356 unsigned long processor_flag = 0;
357 int reply_b = 0, result;
358 long timeout;
359
360
361
362 if (replylen > 0)
363 memset(reply, 0, replylen);
364
365
366
367
368
369
370
371 if (!adapter->irq_acquired)
372 local_irq_save(processor_flag);
373
374
375
376
377
378 timeout = 10000;
379 while (--timeout >= 0) {
380 statusreg.all = blogic_rdstatus(adapter);
381 if (statusreg.sr.adapter_ready && !statusreg.sr.cmd_param_busy)
382 break;
383 udelay(100);
384 }
385 if (timeout < 0) {
386 blogic_cmd_failure_reason =
387 "Timeout waiting for Host Adapter Ready";
388 result = -2;
389 goto done;
390 }
391
392
393
394 adapter->adapter_cmd_complete = false;
395 blogic_setcmdparam(adapter, opcode);
396
397
398
399 timeout = 10000;
400 while (paramlen > 0 && --timeout >= 0) {
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416 udelay(100);
417 intreg.all = blogic_rdint(adapter);
418 statusreg.all = blogic_rdstatus(adapter);
419 if (intreg.ir.cmd_complete)
420 break;
421 if (adapter->adapter_cmd_complete)
422 break;
423 if (statusreg.sr.datain_ready)
424 break;
425 if (statusreg.sr.cmd_param_busy)
426 continue;
427 blogic_setcmdparam(adapter, *param_p++);
428 paramlen--;
429 }
430 if (timeout < 0) {
431 blogic_cmd_failure_reason =
432 "Timeout waiting for Parameter Acceptance";
433 result = -2;
434 goto done;
435 }
436
437
438
439
440 if (opcode == BLOGIC_MOD_IOADDR) {
441 statusreg.all = blogic_rdstatus(adapter);
442 if (statusreg.sr.cmd_invalid) {
443 blogic_cmd_failure_reason =
444 "Modify I/O Address Invalid";
445 result = -1;
446 goto done;
447 }
448 if (blogic_global_options.trace_config)
449 blogic_notice("blogic_cmd(%02X) Status = %02X: " "(Modify I/O Address)\n", adapter, opcode, statusreg.all);
450 result = 0;
451 goto done;
452 }
453
454
455
456 switch (opcode) {
457 case BLOGIC_INQ_DEV0TO7:
458 case BLOGIC_INQ_DEV8TO15:
459 case BLOGIC_INQ_DEV:
460
461 timeout = 60 * 10000;
462 break;
463 default:
464
465 timeout = 10000;
466 break;
467 }
468
469
470
471
472
473
474 while (--timeout >= 0) {
475 intreg.all = blogic_rdint(adapter);
476 statusreg.all = blogic_rdstatus(adapter);
477 if (intreg.ir.cmd_complete)
478 break;
479 if (adapter->adapter_cmd_complete)
480 break;
481 if (statusreg.sr.datain_ready) {
482 if (++reply_b <= replylen)
483 *reply_p++ = blogic_rddatain(adapter);
484 else
485 blogic_rddatain(adapter);
486 }
487 if (opcode == BLOGIC_FETCH_LOCALRAM &&
488 statusreg.sr.adapter_ready)
489 break;
490 udelay(100);
491 }
492 if (timeout < 0) {
493 blogic_cmd_failure_reason =
494 "Timeout waiting for Command Complete";
495 result = -2;
496 goto done;
497 }
498
499
500
501 blogic_intreset(adapter);
502
503
504
505 if (blogic_global_options.trace_config) {
506 int i;
507 blogic_notice("blogic_cmd(%02X) Status = %02X: %2d ==> %2d:",
508 adapter, opcode, statusreg.all, replylen,
509 reply_b);
510 if (replylen > reply_b)
511 replylen = reply_b;
512 for (i = 0; i < replylen; i++)
513 blogic_notice(" %02X", adapter,
514 ((unsigned char *) reply)[i]);
515 blogic_notice("\n", adapter);
516 }
517
518
519
520 if (statusreg.sr.cmd_invalid) {
521
522
523
524
525
526
527
528
529
530 udelay(1000);
531 statusreg.all = blogic_rdstatus(adapter);
532 if (statusreg.sr.cmd_invalid || statusreg.sr.rsvd ||
533 statusreg.sr.datain_ready ||
534 statusreg.sr.cmd_param_busy ||
535 !statusreg.sr.adapter_ready ||
536 !statusreg.sr.init_reqd ||
537 statusreg.sr.diag_active ||
538 statusreg.sr.diag_failed) {
539 blogic_softreset(adapter);
540 udelay(1000);
541 }
542 blogic_cmd_failure_reason = "Command Invalid";
543 result = -1;
544 goto done;
545 }
546
547
548
549 if (paramlen > 0) {
550 blogic_cmd_failure_reason = "Excess Parameters Supplied";
551 result = -1;
552 goto done;
553 }
554
555
556
557 blogic_cmd_failure_reason = NULL;
558 result = reply_b;
559
560
561
562done:
563 if (!adapter->irq_acquired)
564 local_irq_restore(processor_flag);
565 return result;
566}
567
568
569
570
571
572
573
574
575static void __init blogic_add_probeaddr_isa(unsigned long io_addr)
576{
577 struct blogic_probeinfo *probeinfo;
578 if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
579 return;
580 probeinfo = &blogic_probeinfo_list[blogic_probeinfo_count++];
581 probeinfo->adapter_type = BLOGIC_MULTIMASTER;
582 probeinfo->adapter_bus_type = BLOGIC_ISA_BUS;
583 probeinfo->io_addr = io_addr;
584 probeinfo->pci_device = NULL;
585}
586
587
588
589
590
591
592
593
594static void __init blogic_init_probeinfo_isa(struct blogic_adapter *adapter)
595{
596
597
598
599
600 if (blogic_probe_options.noprobe_isa)
601 return;
602
603
604
605 if (!blogic_probe_options.limited_isa || blogic_probe_options.probe330)
606 blogic_add_probeaddr_isa(0x330);
607 if (!blogic_probe_options.limited_isa || blogic_probe_options.probe334)
608 blogic_add_probeaddr_isa(0x334);
609 if (!blogic_probe_options.limited_isa || blogic_probe_options.probe230)
610 blogic_add_probeaddr_isa(0x230);
611 if (!blogic_probe_options.limited_isa || blogic_probe_options.probe234)
612 blogic_add_probeaddr_isa(0x234);
613 if (!blogic_probe_options.limited_isa || blogic_probe_options.probe130)
614 blogic_add_probeaddr_isa(0x130);
615 if (!blogic_probe_options.limited_isa || blogic_probe_options.probe134)
616 blogic_add_probeaddr_isa(0x134);
617}
618
619
620#ifdef CONFIG_PCI
621
622
623
624
625
626
627
628static void __init blogic_sort_probeinfo(struct blogic_probeinfo
629 *probeinfo_list, int probeinfo_cnt)
630{
631 int last_exchange = probeinfo_cnt - 1, bound, j;
632
633 while (last_exchange > 0) {
634 bound = last_exchange;
635 last_exchange = 0;
636 for (j = 0; j < bound; j++) {
637 struct blogic_probeinfo *probeinfo1 =
638 &probeinfo_list[j];
639 struct blogic_probeinfo *probeinfo2 =
640 &probeinfo_list[j + 1];
641 if (probeinfo1->bus > probeinfo2->bus ||
642 (probeinfo1->bus == probeinfo2->bus &&
643 (probeinfo1->dev > probeinfo2->dev))) {
644 struct blogic_probeinfo tmp_probeinfo;
645
646 memcpy(&tmp_probeinfo, probeinfo1,
647 sizeof(struct blogic_probeinfo));
648 memcpy(probeinfo1, probeinfo2,
649 sizeof(struct blogic_probeinfo));
650 memcpy(probeinfo2, &tmp_probeinfo,
651 sizeof(struct blogic_probeinfo));
652 last_exchange = j;
653 }
654 }
655 }
656}
657
658
659
660
661
662
663
664
665
666
667static int __init blogic_init_mm_probeinfo(struct blogic_adapter *adapter)
668{
669 struct blogic_probeinfo *pr_probeinfo =
670 &blogic_probeinfo_list[blogic_probeinfo_count];
671 int nonpr_mmindex = blogic_probeinfo_count + 1;
672 int nonpr_mmcount = 0, mmcount = 0;
673 bool force_scan_order = false;
674 bool force_scan_order_checked = false;
675 bool addr_seen[6];
676 struct pci_dev *pci_device = NULL;
677 int i;
678 if (blogic_probeinfo_count >= BLOGIC_MAX_ADAPTERS)
679 return 0;
680 blogic_probeinfo_count++;
681 for (i = 0; i < 6; i++)
682 addr_seen[i] = false;
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697 pr_probeinfo->io_addr = 0;
698 while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
699 PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
700 pci_device)) != NULL) {
701 struct blogic_adapter *host_adapter = adapter;
702 struct blogic_adapter_info adapter_info;
703 enum blogic_isa_ioport mod_ioaddr_req;
704 unsigned char bus;
705 unsigned char device;
706 unsigned int irq_ch;
707 unsigned long base_addr0;
708 unsigned long base_addr1;
709 unsigned long io_addr;
710 unsigned long pci_addr;
711
712 if (pci_enable_device(pci_device))
713 continue;
714
715 if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32)))
716 continue;
717
718 bus = pci_device->bus->number;
719 device = pci_device->devfn >> 3;
720 irq_ch = pci_device->irq;
721 io_addr = base_addr0 = pci_resource_start(pci_device, 0);
722 pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
723
724 if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
725 blogic_err("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, base_addr0);
726 blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
727 continue;
728 }
729 if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
730 blogic_err("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, base_addr1);
731 blogic_err("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, bus, device, pci_addr);
732 continue;
733 }
734 if (irq_ch == 0) {
735 blogic_err("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, irq_ch);
736 blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
737 continue;
738 }
739 if (blogic_global_options.trace_probe) {
740 blogic_notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL);
741 blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, bus, device, io_addr, pci_addr);
742 }
743
744
745
746
747
748
749 host_adapter->io_addr = io_addr;
750 blogic_intreset(host_adapter);
751 if (blogic_cmd(host_adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
752 &adapter_info, sizeof(adapter_info)) ==
753 sizeof(adapter_info)) {
754 if (adapter_info.isa_port < 6)
755 addr_seen[adapter_info.isa_port] = true;
756 } else
757 adapter_info.isa_port = BLOGIC_IO_DISABLE;
758
759
760
761
762
763
764
765
766 mod_ioaddr_req = BLOGIC_IO_DISABLE;
767 blogic_cmd(host_adapter, BLOGIC_MOD_IOADDR, &mod_ioaddr_req,
768 sizeof(mod_ioaddr_req), NULL, 0);
769
770
771
772
773
774
775
776
777 if (!force_scan_order_checked) {
778 struct blogic_fetch_localram fetch_localram;
779 struct blogic_autoscsi_byte45 autoscsi_byte45;
780 struct blogic_board_id id;
781
782 fetch_localram.offset = BLOGIC_AUTOSCSI_BASE + 45;
783 fetch_localram.count = sizeof(autoscsi_byte45);
784 blogic_cmd(host_adapter, BLOGIC_FETCH_LOCALRAM,
785 &fetch_localram, sizeof(fetch_localram),
786 &autoscsi_byte45,
787 sizeof(autoscsi_byte45));
788 blogic_cmd(host_adapter, BLOGIC_GET_BOARD_ID, NULL, 0,
789 &id, sizeof(id));
790 if (id.fw_ver_digit1 == '5')
791 force_scan_order =
792 autoscsi_byte45.force_scan_order;
793 force_scan_order_checked = true;
794 }
795
796
797
798
799
800
801
802
803 if (adapter_info.isa_port == BLOGIC_IO_330) {
804 pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
805 pr_probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
806 pr_probeinfo->io_addr = io_addr;
807 pr_probeinfo->pci_addr = pci_addr;
808 pr_probeinfo->bus = bus;
809 pr_probeinfo->dev = device;
810 pr_probeinfo->irq_ch = irq_ch;
811 pr_probeinfo->pci_device = pci_dev_get(pci_device);
812 mmcount++;
813 } else if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
814 struct blogic_probeinfo *probeinfo =
815 &blogic_probeinfo_list[blogic_probeinfo_count++];
816 probeinfo->adapter_type = BLOGIC_MULTIMASTER;
817 probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
818 probeinfo->io_addr = io_addr;
819 probeinfo->pci_addr = pci_addr;
820 probeinfo->bus = bus;
821 probeinfo->dev = device;
822 probeinfo->irq_ch = irq_ch;
823 probeinfo->pci_device = pci_dev_get(pci_device);
824 nonpr_mmcount++;
825 mmcount++;
826 } else
827 blogic_warn("BusLogic: Too many Host Adapters " "detected\n", NULL);
828 }
829
830
831
832
833
834
835
836
837
838
839
840 if (force_scan_order)
841 blogic_sort_probeinfo(&blogic_probeinfo_list[nonpr_mmindex],
842 nonpr_mmcount);
843
844
845
846
847
848 if (!blogic_probe_options.noprobe_isa)
849 if (pr_probeinfo->io_addr == 0 &&
850 (!blogic_probe_options.limited_isa ||
851 blogic_probe_options.probe330)) {
852 pr_probeinfo->adapter_type = BLOGIC_MULTIMASTER;
853 pr_probeinfo->adapter_bus_type = BLOGIC_ISA_BUS;
854 pr_probeinfo->io_addr = 0x330;
855 }
856
857
858
859
860 if (!blogic_probe_options.noprobe_isa) {
861 if (!addr_seen[1] &&
862 (!blogic_probe_options.limited_isa ||
863 blogic_probe_options.probe334))
864 blogic_add_probeaddr_isa(0x334);
865 if (!addr_seen[2] &&
866 (!blogic_probe_options.limited_isa ||
867 blogic_probe_options.probe230))
868 blogic_add_probeaddr_isa(0x230);
869 if (!addr_seen[3] &&
870 (!blogic_probe_options.limited_isa ||
871 blogic_probe_options.probe234))
872 blogic_add_probeaddr_isa(0x234);
873 if (!addr_seen[4] &&
874 (!blogic_probe_options.limited_isa ||
875 blogic_probe_options.probe130))
876 blogic_add_probeaddr_isa(0x130);
877 if (!addr_seen[5] &&
878 (!blogic_probe_options.limited_isa ||
879 blogic_probe_options.probe134))
880 blogic_add_probeaddr_isa(0x134);
881 }
882
883
884
885
886 pci_device = NULL;
887 while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
888 PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
889 pci_device)) != NULL) {
890 unsigned char bus;
891 unsigned char device;
892 unsigned int irq_ch;
893 unsigned long io_addr;
894
895 if (pci_enable_device(pci_device))
896 continue;
897
898 if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32)))
899 continue;
900
901 bus = pci_device->bus->number;
902 device = pci_device->devfn >> 3;
903 irq_ch = pci_device->irq;
904 io_addr = pci_resource_start(pci_device, 0);
905
906 if (io_addr == 0 || irq_ch == 0)
907 continue;
908 for (i = 0; i < blogic_probeinfo_count; i++) {
909 struct blogic_probeinfo *probeinfo =
910 &blogic_probeinfo_list[i];
911 if (probeinfo->io_addr == io_addr &&
912 probeinfo->adapter_type == BLOGIC_MULTIMASTER) {
913 probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
914 probeinfo->pci_addr = 0;
915 probeinfo->bus = bus;
916 probeinfo->dev = device;
917 probeinfo->irq_ch = irq_ch;
918 probeinfo->pci_device = pci_dev_get(pci_device);
919 break;
920 }
921 }
922 }
923 return mmcount;
924}
925
926
927
928
929
930
931
932
933
934static int __init blogic_init_fp_probeinfo(struct blogic_adapter *adapter)
935{
936 int fpindex = blogic_probeinfo_count, fpcount = 0;
937 struct pci_dev *pci_device = NULL;
938
939
940
941 while ((pci_device = pci_get_device(PCI_VENDOR_ID_BUSLOGIC,
942 PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
943 pci_device)) != NULL) {
944 unsigned char bus;
945 unsigned char device;
946 unsigned int irq_ch;
947 unsigned long base_addr0;
948 unsigned long base_addr1;
949 unsigned long io_addr;
950 unsigned long pci_addr;
951
952 if (pci_enable_device(pci_device))
953 continue;
954
955 if (pci_set_dma_mask(pci_device, DMA_BIT_MASK(32)))
956 continue;
957
958 bus = pci_device->bus->number;
959 device = pci_device->devfn >> 3;
960 irq_ch = pci_device->irq;
961 io_addr = base_addr0 = pci_resource_start(pci_device, 0);
962 pci_addr = base_addr1 = pci_resource_start(pci_device, 1);
963#ifdef CONFIG_SCSI_FLASHPOINT
964 if (pci_resource_flags(pci_device, 0) & IORESOURCE_MEM) {
965 blogic_err("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, base_addr0);
966 blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
967 continue;
968 }
969 if (pci_resource_flags(pci_device, 1) & IORESOURCE_IO) {
970 blogic_err("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, base_addr1);
971 blogic_err("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, bus, device, pci_addr);
972 continue;
973 }
974 if (irq_ch == 0) {
975 blogic_err("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, irq_ch);
976 blogic_err("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, bus, device, io_addr);
977 continue;
978 }
979 if (blogic_global_options.trace_probe) {
980 blogic_notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL);
981 blogic_notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, bus, device, io_addr, pci_addr);
982 }
983 if (blogic_probeinfo_count < BLOGIC_MAX_ADAPTERS) {
984 struct blogic_probeinfo *probeinfo =
985 &blogic_probeinfo_list[blogic_probeinfo_count++];
986 probeinfo->adapter_type = BLOGIC_FLASHPOINT;
987 probeinfo->adapter_bus_type = BLOGIC_PCI_BUS;
988 probeinfo->io_addr = io_addr;
989 probeinfo->pci_addr = pci_addr;
990 probeinfo->bus = bus;
991 probeinfo->dev = device;
992 probeinfo->irq_ch = irq_ch;
993 probeinfo->pci_device = pci_dev_get(pci_device);
994 fpcount++;
995 } else
996 blogic_warn("BusLogic: Too many Host Adapters " "detected\n", NULL);
997#else
998 blogic_err("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, bus, device);
999 blogic_err("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, io_addr, pci_addr, irq_ch);
1000 blogic_err("BusLogic: support was omitted in this kernel " "configuration.\n", NULL);
1001#endif
1002 }
1003
1004
1005
1006
1007
1008 blogic_sort_probeinfo(&blogic_probeinfo_list[fpindex], fpcount);
1009 return fpcount;
1010}
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026static void __init blogic_init_probeinfo_list(struct blogic_adapter *adapter)
1027{
1028
1029
1030
1031
1032
1033 if (!blogic_probe_options.noprobe_pci) {
1034 if (blogic_probe_options.multimaster_first) {
1035 blogic_init_mm_probeinfo(adapter);
1036 blogic_init_fp_probeinfo(adapter);
1037 } else if (blogic_probe_options.flashpoint_first) {
1038 blogic_init_fp_probeinfo(adapter);
1039 blogic_init_mm_probeinfo(adapter);
1040 } else {
1041 int fpcount = blogic_init_fp_probeinfo(adapter);
1042 int mmcount = blogic_init_mm_probeinfo(adapter);
1043 if (fpcount > 0 && mmcount > 0) {
1044 struct blogic_probeinfo *probeinfo =
1045 &blogic_probeinfo_list[fpcount];
1046 struct blogic_adapter *myadapter = adapter;
1047 struct blogic_fetch_localram fetch_localram;
1048 struct blogic_bios_drvmap d0_mapbyte;
1049
1050 while (probeinfo->adapter_bus_type !=
1051 BLOGIC_PCI_BUS)
1052 probeinfo++;
1053 myadapter->io_addr = probeinfo->io_addr;
1054 fetch_localram.offset =
1055 BLOGIC_BIOS_BASE + BLOGIC_BIOS_DRVMAP;
1056 fetch_localram.count = sizeof(d0_mapbyte);
1057 blogic_cmd(myadapter, BLOGIC_FETCH_LOCALRAM,
1058 &fetch_localram,
1059 sizeof(fetch_localram),
1060 &d0_mapbyte,
1061 sizeof(d0_mapbyte));
1062
1063
1064
1065
1066
1067
1068
1069
1070 if (d0_mapbyte.diskgeom != BLOGIC_BIOS_NODISK) {
1071 struct blogic_probeinfo saved_probeinfo[BLOGIC_MAX_ADAPTERS];
1072 int mmcount = blogic_probeinfo_count - fpcount;
1073
1074 memcpy(saved_probeinfo,
1075 blogic_probeinfo_list,
1076 blogic_probeinfo_count * sizeof(struct blogic_probeinfo));
1077 memcpy(&blogic_probeinfo_list[0],
1078 &saved_probeinfo[fpcount],
1079 mmcount * sizeof(struct blogic_probeinfo));
1080 memcpy(&blogic_probeinfo_list[mmcount],
1081 &saved_probeinfo[0],
1082 fpcount * sizeof(struct blogic_probeinfo));
1083 }
1084 }
1085 }
1086 } else {
1087 blogic_init_probeinfo_isa(adapter);
1088 }
1089}
1090
1091
1092#else
1093#define blogic_init_probeinfo_list(adapter) \
1094 blogic_init_probeinfo_isa(adapter)
1095#endif
1096
1097
1098
1099
1100
1101
1102static bool blogic_failure(struct blogic_adapter *adapter, char *msg)
1103{
1104 blogic_announce_drvr(adapter);
1105 if (adapter->adapter_bus_type == BLOGIC_PCI_BUS) {
1106 blogic_err("While configuring BusLogic PCI Host Adapter at\n",
1107 adapter);
1108 blogic_err("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n", adapter, adapter->bus, adapter->dev, adapter->io_addr, adapter->pci_addr);
1109 } else
1110 blogic_err("While configuring BusLogic Host Adapter at " "I/O Address 0x%X:\n", adapter, adapter->io_addr);
1111 blogic_err("%s FAILED - DETACHING\n", adapter, msg);
1112 if (blogic_cmd_failure_reason != NULL)
1113 blogic_err("ADDITIONAL FAILURE INFO - %s\n", adapter,
1114 blogic_cmd_failure_reason);
1115 return false;
1116}
1117
1118
1119
1120
1121
1122
1123static bool __init blogic_probe(struct blogic_adapter *adapter)
1124{
1125 union blogic_stat_reg statusreg;
1126 union blogic_int_reg intreg;
1127 union blogic_geo_reg georeg;
1128
1129
1130
1131 if (blogic_flashpoint_type(adapter)) {
1132 struct fpoint_info *fpinfo = &adapter->fpinfo;
1133 fpinfo->base_addr = (u32) adapter->io_addr;
1134 fpinfo->irq_ch = adapter->irq_ch;
1135 fpinfo->present = false;
1136 if (!(FlashPoint_ProbeHostAdapter(fpinfo) == 0 &&
1137 fpinfo->present)) {
1138 blogic_err("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", adapter, adapter->bus, adapter->dev);
1139 blogic_err("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", adapter, adapter->io_addr, adapter->pci_addr);
1140 blogic_err("BusLogic: Probe Function failed to validate it.\n", adapter);
1141 return false;
1142 }
1143 if (blogic_global_options.trace_probe)
1144 blogic_notice("BusLogic_Probe(0x%X): FlashPoint Found\n", adapter, adapter->io_addr);
1145
1146
1147
1148 return true;
1149 }
1150
1151
1152
1153
1154
1155
1156
1157 statusreg.all = blogic_rdstatus(adapter);
1158 intreg.all = blogic_rdint(adapter);
1159 georeg.all = blogic_rdgeom(adapter);
1160 if (blogic_global_options.trace_probe)
1161 blogic_notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", adapter, adapter->io_addr, statusreg.all, intreg.all, georeg.all);
1162 if (statusreg.all == 0 || statusreg.sr.diag_active ||
1163 statusreg.sr.cmd_param_busy || statusreg.sr.rsvd ||
1164 statusreg.sr.cmd_invalid || intreg.ir.rsvd != 0)
1165 return false;
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 if (georeg.all == 0xFF)
1183 return false;
1184
1185
1186
1187 return true;
1188}
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199static bool blogic_hwreset(struct blogic_adapter *adapter, bool hard_reset)
1200{
1201 union blogic_stat_reg statusreg;
1202 int timeout;
1203
1204
1205
1206
1207 if (blogic_flashpoint_type(adapter)) {
1208 struct fpoint_info *fpinfo = &adapter->fpinfo;
1209 fpinfo->softreset = !hard_reset;
1210 fpinfo->report_underrun = true;
1211 adapter->cardhandle =
1212 FlashPoint_HardwareResetHostAdapter(fpinfo);
1213 if (adapter->cardhandle == (void *)FPOINT_BADCARD_HANDLE)
1214 return false;
1215
1216
1217
1218 return true;
1219 }
1220
1221
1222
1223
1224
1225 if (hard_reset)
1226 blogic_hardreset(adapter);
1227 else
1228 blogic_softreset(adapter);
1229
1230
1231
1232 timeout = 5 * 10000;
1233 while (--timeout >= 0) {
1234 statusreg.all = blogic_rdstatus(adapter);
1235 if (statusreg.sr.diag_active)
1236 break;
1237 udelay(100);
1238 }
1239 if (blogic_global_options.trace_hw_reset)
1240 blogic_notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1241 if (timeout < 0)
1242 return false;
1243
1244
1245
1246
1247
1248 udelay(100);
1249
1250
1251
1252 timeout = 10 * 10000;
1253 while (--timeout >= 0) {
1254 statusreg.all = blogic_rdstatus(adapter);
1255 if (!statusreg.sr.diag_active)
1256 break;
1257 udelay(100);
1258 }
1259 if (blogic_global_options.trace_hw_reset)
1260 blogic_notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1261 if (timeout < 0)
1262 return false;
1263
1264
1265
1266
1267 timeout = 10000;
1268 while (--timeout >= 0) {
1269 statusreg.all = blogic_rdstatus(adapter);
1270 if (statusreg.sr.diag_failed || statusreg.sr.adapter_ready ||
1271 statusreg.sr.datain_ready)
1272 break;
1273 udelay(100);
1274 }
1275 if (blogic_global_options.trace_hw_reset)
1276 blogic_notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", adapter, adapter->io_addr, statusreg.all);
1277 if (timeout < 0)
1278 return false;
1279
1280
1281
1282
1283
1284
1285 if (statusreg.sr.diag_failed || !statusreg.sr.adapter_ready) {
1286 blogic_cmd_failure_reason = NULL;
1287 blogic_failure(adapter, "HARD RESET DIAGNOSTICS");
1288 blogic_err("HOST ADAPTER STATUS REGISTER = %02X\n", adapter,
1289 statusreg.all);
1290 if (statusreg.sr.datain_ready)
1291 blogic_err("HOST ADAPTER ERROR CODE = %d\n", adapter,
1292 blogic_rddatain(adapter));
1293 return false;
1294 }
1295
1296
1297
1298 return true;
1299}
1300
1301
1302
1303
1304
1305
1306
1307static bool __init blogic_checkadapter(struct blogic_adapter *adapter)
1308{
1309 struct blogic_ext_setup ext_setupinfo;
1310 unsigned char req_replylen;
1311 bool result = true;
1312
1313
1314
1315 if (blogic_flashpoint_type(adapter))
1316 return true;
1317
1318
1319
1320
1321
1322
1323 req_replylen = sizeof(ext_setupinfo);
1324 if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
1325 sizeof(req_replylen), &ext_setupinfo,
1326 sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
1327 result = false;
1328
1329
1330
1331 if (blogic_global_options.trace_probe)
1332 blogic_notice("BusLogic_Check(0x%X): MultiMaster %s\n", adapter,
1333 adapter->io_addr,
1334 (result ? "Found" : "Not Found"));
1335 return result;
1336}
1337
1338
1339
1340
1341
1342
1343
1344static bool __init blogic_rdconfig(struct blogic_adapter *adapter)
1345{
1346 struct blogic_board_id id;
1347 struct blogic_config config;
1348 struct blogic_setup_info setupinfo;
1349 struct blogic_ext_setup ext_setupinfo;
1350 unsigned char model[5];
1351 unsigned char fw_ver_digit3;
1352 unsigned char fw_ver_letter;
1353 struct blogic_adapter_info adapter_info;
1354 struct blogic_fetch_localram fetch_localram;
1355 struct blogic_autoscsi autoscsi;
1356 union blogic_geo_reg georeg;
1357 unsigned char req_replylen;
1358 unsigned char *tgt, ch;
1359 int tgt_id, i;
1360
1361
1362
1363
1364
1365
1366 if (blogic_flashpoint_type(adapter)) {
1367 struct fpoint_info *fpinfo = &adapter->fpinfo;
1368 tgt = adapter->model;
1369 *tgt++ = 'B';
1370 *tgt++ = 'T';
1371 *tgt++ = '-';
1372 for (i = 0; i < sizeof(fpinfo->model); i++)
1373 *tgt++ = fpinfo->model[i];
1374 *tgt++ = '\0';
1375 strcpy(adapter->fw_ver, FLASHPOINT_FW_VER);
1376 adapter->scsi_id = fpinfo->scsi_id;
1377 adapter->ext_trans_enable = fpinfo->ext_trans_enable;
1378 adapter->parity = fpinfo->parity;
1379 adapter->reset_enabled = !fpinfo->softreset;
1380 adapter->level_int = true;
1381 adapter->wide = fpinfo->wide;
1382 adapter->differential = false;
1383 adapter->scam = true;
1384 adapter->ultra = true;
1385 adapter->ext_lun = true;
1386 adapter->terminfo_valid = true;
1387 adapter->low_term = fpinfo->low_term;
1388 adapter->high_term = fpinfo->high_term;
1389 adapter->scam_enabled = fpinfo->scam_enabled;
1390 adapter->scam_lev2 = fpinfo->scam_lev2;
1391 adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
1392 adapter->maxdev = (adapter->wide ? 16 : 8);
1393 adapter->maxlun = 32;
1394 adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
1395 adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
1396 adapter->drvr_qdepth = 255;
1397 adapter->adapter_qdepth = adapter->drvr_qdepth;
1398 adapter->sync_ok = fpinfo->sync_ok;
1399 adapter->fast_ok = fpinfo->fast_ok;
1400 adapter->ultra_ok = fpinfo->ultra_ok;
1401 adapter->wide_ok = fpinfo->wide_ok;
1402 adapter->discon_ok = fpinfo->discon_ok;
1403 adapter->tagq_ok = 0xFFFF;
1404 goto common;
1405 }
1406
1407
1408
1409 if (blogic_cmd(adapter, BLOGIC_GET_BOARD_ID, NULL, 0, &id,
1410 sizeof(id)) != sizeof(id))
1411 return blogic_failure(adapter, "INQUIRE BOARD ID");
1412
1413
1414
1415 if (blogic_cmd(adapter, BLOGIC_INQ_CONFIG, NULL, 0, &config,
1416 sizeof(config))
1417 != sizeof(config))
1418 return blogic_failure(adapter, "INQUIRE CONFIGURATION");
1419
1420
1421
1422 req_replylen = sizeof(setupinfo);
1423 if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
1424 sizeof(req_replylen), &setupinfo,
1425 sizeof(setupinfo)) != sizeof(setupinfo))
1426 return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
1427
1428
1429
1430 req_replylen = sizeof(ext_setupinfo);
1431 if (blogic_cmd(adapter, BLOGIC_INQ_EXTSETUP, &req_replylen,
1432 sizeof(req_replylen), &ext_setupinfo,
1433 sizeof(ext_setupinfo)) != sizeof(ext_setupinfo))
1434 return blogic_failure(adapter,
1435 "INQUIRE EXTENDED SETUP INFORMATION");
1436
1437
1438
1439 fw_ver_digit3 = '\0';
1440 if (id.fw_ver_digit1 > '0')
1441 if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_D3, NULL, 0,
1442 &fw_ver_digit3,
1443 sizeof(fw_ver_digit3)) != sizeof(fw_ver_digit3))
1444 return blogic_failure(adapter,
1445 "INQUIRE FIRMWARE 3RD DIGIT");
1446
1447
1448
1449 if (ext_setupinfo.bus_type == 'A' && id.fw_ver_digit1 == '2')
1450
1451 strcpy(model, "542B");
1452 else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '2' &&
1453 (id.fw_ver_digit2 <= '1' || (id.fw_ver_digit2 == '2' &&
1454 fw_ver_digit3 == '0')))
1455
1456 strcpy(model, "742A");
1457 else if (ext_setupinfo.bus_type == 'E' && id.fw_ver_digit1 == '0')
1458
1459 strcpy(model, "747A");
1460 else {
1461 req_replylen = sizeof(model);
1462 if (blogic_cmd(adapter, BLOGIC_INQ_MODELNO, &req_replylen,
1463 sizeof(req_replylen), &model,
1464 sizeof(model)) != sizeof(model))
1465 return blogic_failure(adapter,
1466 "INQUIRE HOST ADAPTER MODEL NUMBER");
1467 }
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488 tgt = adapter->model;
1489 *tgt++ = 'B';
1490 *tgt++ = 'T';
1491 *tgt++ = '-';
1492 for (i = 0; i < sizeof(model); i++) {
1493 ch = model[i];
1494 if (ch == ' ' || ch == '\0')
1495 break;
1496 *tgt++ = ch;
1497 }
1498 *tgt++ = '\0';
1499
1500
1501
1502 tgt = adapter->fw_ver;
1503 *tgt++ = id.fw_ver_digit1;
1504 *tgt++ = '.';
1505 *tgt++ = id.fw_ver_digit2;
1506 if (fw_ver_digit3 != ' ' && fw_ver_digit3 != '\0')
1507 *tgt++ = fw_ver_digit3;
1508 *tgt = '\0';
1509
1510
1511
1512 if (strcmp(adapter->fw_ver, "3.3") >= 0) {
1513 if (blogic_cmd(adapter, BLOGIC_INQ_FWVER_LETTER, NULL, 0,
1514 &fw_ver_letter,
1515 sizeof(fw_ver_letter)) != sizeof(fw_ver_letter))
1516 return blogic_failure(adapter,
1517 "INQUIRE FIRMWARE VERSION LETTER");
1518 if (fw_ver_letter != ' ' && fw_ver_letter != '\0')
1519 *tgt++ = fw_ver_letter;
1520 *tgt = '\0';
1521 }
1522
1523
1524
1525 adapter->scsi_id = config.id;
1526
1527
1528
1529
1530
1531 adapter->adapter_bus_type =
1532 blogic_adater_bus_types[adapter->model[3] - '4'];
1533 if (adapter->irq_ch == 0) {
1534 if (config.irq_ch9)
1535 adapter->irq_ch = 9;
1536 else if (config.irq_ch10)
1537 adapter->irq_ch = 10;
1538 else if (config.irq_ch11)
1539 adapter->irq_ch = 11;
1540 else if (config.irq_ch12)
1541 adapter->irq_ch = 12;
1542 else if (config.irq_ch14)
1543 adapter->irq_ch = 14;
1544 else if (config.irq_ch15)
1545 adapter->irq_ch = 15;
1546 }
1547 if (adapter->adapter_bus_type == BLOGIC_ISA_BUS) {
1548 if (config.dma_ch5)
1549 adapter->dma_ch = 5;
1550 else if (config.dma_ch6)
1551 adapter->dma_ch = 6;
1552 else if (config.dma_ch7)
1553 adapter->dma_ch = 7;
1554 }
1555
1556
1557
1558
1559 georeg.all = blogic_rdgeom(adapter);
1560 adapter->ext_trans_enable = georeg.gr.ext_trans_enable;
1561
1562
1563
1564
1565
1566 adapter->adapter_sglimit = ext_setupinfo.sg_limit;
1567 adapter->drvr_sglimit = adapter->adapter_sglimit;
1568 if (adapter->adapter_sglimit > BLOGIC_SG_LIMIT)
1569 adapter->drvr_sglimit = BLOGIC_SG_LIMIT;
1570 if (ext_setupinfo.misc.level_int)
1571 adapter->level_int = true;
1572 adapter->wide = ext_setupinfo.wide;
1573 adapter->differential = ext_setupinfo.differential;
1574 adapter->scam = ext_setupinfo.scam;
1575 adapter->ultra = ext_setupinfo.ultra;
1576
1577
1578
1579
1580 if (adapter->fw_ver[0] == '5' || (adapter->fw_ver[0] == '4' &&
1581 adapter->wide))
1582 adapter->ext_lun = true;
1583
1584
1585
1586
1587 if (adapter->fw_ver[0] == '5') {
1588 if (blogic_cmd(adapter, BLOGIC_INQ_PCI_INFO, NULL, 0,
1589 &adapter_info,
1590 sizeof(adapter_info)) != sizeof(adapter_info))
1591 return blogic_failure(adapter,
1592 "INQUIRE PCI HOST ADAPTER INFORMATION");
1593
1594
1595
1596
1597 if (adapter_info.genericinfo_valid) {
1598 adapter->terminfo_valid = true;
1599 adapter->low_term = adapter_info.low_term;
1600 adapter->high_term = adapter_info.high_term;
1601 }
1602 }
1603
1604
1605
1606
1607 if (adapter->fw_ver[0] >= '4') {
1608 fetch_localram.offset = BLOGIC_AUTOSCSI_BASE;
1609 fetch_localram.count = sizeof(autoscsi);
1610 if (blogic_cmd(adapter, BLOGIC_FETCH_LOCALRAM, &fetch_localram,
1611 sizeof(fetch_localram), &autoscsi,
1612 sizeof(autoscsi)) != sizeof(autoscsi))
1613 return blogic_failure(adapter,
1614 "FETCH HOST ADAPTER LOCAL RAM");
1615
1616
1617
1618
1619 adapter->parity = autoscsi.parity;
1620 adapter->reset_enabled = autoscsi.reset_enabled;
1621 if (adapter->fw_ver[0] == '4') {
1622 adapter->terminfo_valid = true;
1623 adapter->low_term = autoscsi.low_term;
1624 adapter->high_term = autoscsi.high_term;
1625 }
1626
1627
1628
1629
1630
1631 adapter->wide_ok = autoscsi.wide_ok;
1632 adapter->fast_ok = autoscsi.fast_ok;
1633 adapter->sync_ok = autoscsi.sync_ok;
1634 adapter->discon_ok = autoscsi.discon_ok;
1635 if (adapter->ultra)
1636 adapter->ultra_ok = autoscsi.ultra_ok;
1637 if (adapter->scam) {
1638 adapter->scam_enabled = autoscsi.scam_enabled;
1639 adapter->scam_lev2 = autoscsi.scam_lev2;
1640 }
1641 }
1642
1643
1644
1645
1646 if (adapter->fw_ver[0] < '4') {
1647 if (setupinfo.sync) {
1648 adapter->sync_ok = 0xFF;
1649 if (adapter->adapter_bus_type == BLOGIC_EISA_BUS) {
1650 if (ext_setupinfo.misc.fast_on_eisa)
1651 adapter->fast_ok = 0xFF;
1652 if (strcmp(adapter->model, "BT-757") == 0)
1653 adapter->wide_ok = 0xFF;
1654 }
1655 }
1656 adapter->discon_ok = 0xFF;
1657 adapter->parity = setupinfo.parity;
1658 adapter->reset_enabled = true;
1659 }
1660
1661
1662
1663
1664 adapter->maxdev = (adapter->wide ? 16 : 8);
1665 adapter->maxlun = (adapter->ext_lun ? 32 : 8);
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691 if (adapter->fw_ver[0] == '5')
1692 adapter->adapter_qdepth = 192;
1693 else if (adapter->fw_ver[0] == '4')
1694 adapter->adapter_qdepth = (adapter->adapter_bus_type !=
1695 BLOGIC_ISA_BUS ? 100 : 50);
1696 else
1697 adapter->adapter_qdepth = 30;
1698 if (strcmp(adapter->fw_ver, "3.31") >= 0) {
1699 adapter->strict_rr = true;
1700 adapter->mbox_count = BLOGIC_MAX_MAILBOX;
1701 } else {
1702 adapter->strict_rr = false;
1703 adapter->mbox_count = 32;
1704 }
1705 adapter->drvr_qdepth = adapter->mbox_count;
1706 adapter->initccbs = 4 * BLOGIC_CCB_GRP_ALLOCSIZE;
1707 adapter->inc_ccbs = BLOGIC_CCB_GRP_ALLOCSIZE;
1708
1709
1710
1711
1712
1713
1714
1715 adapter->tagq_ok = 0;
1716 switch (adapter->fw_ver[0]) {
1717 case '5':
1718 adapter->tagq_ok = 0xFFFF;
1719 break;
1720 case '4':
1721 if (strcmp(adapter->fw_ver, "4.22") >= 0)
1722 adapter->tagq_ok = 0xFFFF;
1723 break;
1724 case '3':
1725 if (strcmp(adapter->fw_ver, "3.35") >= 0)
1726 adapter->tagq_ok = 0xFFFF;
1727 break;
1728 }
1729
1730
1731
1732
1733
1734 adapter->bios_addr = ext_setupinfo.bios_addr << 12;
1735
1736
1737
1738
1739 if (adapter->adapter_bus_type == BLOGIC_ISA_BUS &&
1740 (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1741 adapter->need_bouncebuf = true;
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751 if (adapter->bios_addr > 0 && strcmp(adapter->model, "BT-445S") == 0 &&
1752 strcmp(adapter->fw_ver, "3.37") < 0 &&
1753 (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1754 adapter->need_bouncebuf = true;
1755
1756
1757
1758
1759common:
1760
1761
1762
1763 strcpy(adapter->full_model, "BusLogic ");
1764 strcat(adapter->full_model, adapter->model);
1765
1766
1767
1768
1769
1770
1771
1772 for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
1773 unsigned char qdepth = 0;
1774 if (adapter->drvr_opts != NULL &&
1775 adapter->drvr_opts->qdepth[tgt_id] > 0)
1776 qdepth = adapter->drvr_opts->qdepth[tgt_id];
1777 else if (adapter->need_bouncebuf)
1778 qdepth = BLOGIC_TAG_DEPTH_BB;
1779 adapter->qdepth[tgt_id] = qdepth;
1780 }
1781 if (adapter->need_bouncebuf)
1782 adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH_BB;
1783 else
1784 adapter->untag_qdepth = BLOGIC_UNTAG_DEPTH;
1785 if (adapter->drvr_opts != NULL)
1786 adapter->common_qdepth = adapter->drvr_opts->common_qdepth;
1787 if (adapter->common_qdepth > 0 &&
1788 adapter->common_qdepth < adapter->untag_qdepth)
1789 adapter->untag_qdepth = adapter->common_qdepth;
1790
1791
1792
1793
1794
1795 adapter->tagq_ok &= adapter->discon_ok;
1796
1797
1798
1799
1800 if (adapter->drvr_opts != NULL)
1801 adapter->tagq_ok = (adapter->drvr_opts->tagq_ok &
1802 adapter->drvr_opts->tagq_ok_mask) |
1803 (adapter->tagq_ok & ~adapter->drvr_opts->tagq_ok_mask);
1804
1805
1806
1807
1808
1809
1810 if (adapter->drvr_opts != NULL &&
1811 adapter->drvr_opts->bus_settle_time > 0)
1812 adapter->bus_settle_time = adapter->drvr_opts->bus_settle_time;
1813 else
1814 adapter->bus_settle_time = BLOGIC_BUS_SETTLE_TIME;
1815
1816
1817
1818
1819 return true;
1820}
1821
1822
1823
1824
1825
1826
1827static bool __init blogic_reportconfig(struct blogic_adapter *adapter)
1828{
1829 unsigned short alltgt_mask = (1 << adapter->maxdev) - 1;
1830 unsigned short sync_ok, fast_ok;
1831 unsigned short ultra_ok, wide_ok;
1832 unsigned short discon_ok, tagq_ok;
1833 bool common_syncneg, common_tagq_depth;
1834 char syncstr[BLOGIC_MAXDEV + 1];
1835 char widestr[BLOGIC_MAXDEV + 1];
1836 char discon_str[BLOGIC_MAXDEV + 1];
1837 char tagq_str[BLOGIC_MAXDEV + 1];
1838 char *syncmsg = syncstr;
1839 char *widemsg = widestr;
1840 char *discon_msg = discon_str;
1841 char *tagq_msg = tagq_str;
1842 int tgt_id;
1843
1844 blogic_info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", adapter, adapter->model, blogic_adapter_busnames[adapter->adapter_bus_type], (adapter->wide ? " Wide" : ""), (adapter->differential ? " Differential" : ""), (adapter->ultra ? " Ultra" : ""));
1845 blogic_info(" Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", adapter, adapter->fw_ver, adapter->io_addr, adapter->irq_ch, (adapter->level_int ? "Level" : "Edge"));
1846 if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) {
1847 blogic_info(" DMA Channel: ", adapter);
1848 if (adapter->dma_ch > 0)
1849 blogic_info("%d, ", adapter, adapter->dma_ch);
1850 else
1851 blogic_info("None, ", adapter);
1852 if (adapter->bios_addr > 0)
1853 blogic_info("BIOS Address: 0x%X, ", adapter,
1854 adapter->bios_addr);
1855 else
1856 blogic_info("BIOS Address: None, ", adapter);
1857 } else {
1858 blogic_info(" PCI Bus: %d, Device: %d, Address: ", adapter,
1859 adapter->bus, adapter->dev);
1860 if (adapter->pci_addr > 0)
1861 blogic_info("0x%X, ", adapter, adapter->pci_addr);
1862 else
1863 blogic_info("Unassigned, ", adapter);
1864 }
1865 blogic_info("Host Adapter SCSI ID: %d\n", adapter, adapter->scsi_id);
1866 blogic_info(" Parity Checking: %s, Extended Translation: %s\n",
1867 adapter, (adapter->parity ? "Enabled" : "Disabled"),
1868 (adapter->ext_trans_enable ? "Enabled" : "Disabled"));
1869 alltgt_mask &= ~(1 << adapter->scsi_id);
1870 sync_ok = adapter->sync_ok & alltgt_mask;
1871 fast_ok = adapter->fast_ok & alltgt_mask;
1872 ultra_ok = adapter->ultra_ok & alltgt_mask;
1873 if ((blogic_multimaster_type(adapter) &&
1874 (adapter->fw_ver[0] >= '4' ||
1875 adapter->adapter_bus_type == BLOGIC_EISA_BUS)) ||
1876 blogic_flashpoint_type(adapter)) {
1877 common_syncneg = false;
1878 if (sync_ok == 0) {
1879 syncmsg = "Disabled";
1880 common_syncneg = true;
1881 } else if (sync_ok == alltgt_mask) {
1882 if (fast_ok == 0) {
1883 syncmsg = "Slow";
1884 common_syncneg = true;
1885 } else if (fast_ok == alltgt_mask) {
1886 if (ultra_ok == 0) {
1887 syncmsg = "Fast";
1888 common_syncneg = true;
1889 } else if (ultra_ok == alltgt_mask) {
1890 syncmsg = "Ultra";
1891 common_syncneg = true;
1892 }
1893 }
1894 }
1895 if (!common_syncneg) {
1896 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1897 syncstr[tgt_id] = ((!(sync_ok & (1 << tgt_id))) ? 'N' : (!(fast_ok & (1 << tgt_id)) ? 'S' : (!(ultra_ok & (1 << tgt_id)) ? 'F' : 'U')));
1898 syncstr[adapter->scsi_id] = '#';
1899 syncstr[adapter->maxdev] = '\0';
1900 }
1901 } else
1902 syncmsg = (sync_ok == 0 ? "Disabled" : "Enabled");
1903 wide_ok = adapter->wide_ok & alltgt_mask;
1904 if (wide_ok == 0)
1905 widemsg = "Disabled";
1906 else if (wide_ok == alltgt_mask)
1907 widemsg = "Enabled";
1908 else {
1909 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1910 widestr[tgt_id] = ((wide_ok & (1 << tgt_id)) ? 'Y' : 'N');
1911 widestr[adapter->scsi_id] = '#';
1912 widestr[adapter->maxdev] = '\0';
1913 }
1914 discon_ok = adapter->discon_ok & alltgt_mask;
1915 if (discon_ok == 0)
1916 discon_msg = "Disabled";
1917 else if (discon_ok == alltgt_mask)
1918 discon_msg = "Enabled";
1919 else {
1920 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1921 discon_str[tgt_id] = ((discon_ok & (1 << tgt_id)) ? 'Y' : 'N');
1922 discon_str[adapter->scsi_id] = '#';
1923 discon_str[adapter->maxdev] = '\0';
1924 }
1925 tagq_ok = adapter->tagq_ok & alltgt_mask;
1926 if (tagq_ok == 0)
1927 tagq_msg = "Disabled";
1928 else if (tagq_ok == alltgt_mask)
1929 tagq_msg = "Enabled";
1930 else {
1931 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
1932 tagq_str[tgt_id] = ((tagq_ok & (1 << tgt_id)) ? 'Y' : 'N');
1933 tagq_str[adapter->scsi_id] = '#';
1934 tagq_str[adapter->maxdev] = '\0';
1935 }
1936 blogic_info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n",
1937 adapter, syncmsg, widemsg);
1938 blogic_info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", adapter,
1939 discon_msg, tagq_msg);
1940 if (blogic_multimaster_type(adapter)) {
1941 blogic_info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", adapter, adapter->drvr_sglimit, adapter->adapter_sglimit, adapter->mbox_count);
1942 blogic_info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", adapter, adapter->drvr_qdepth, adapter->adapter_qdepth);
1943 } else
1944 blogic_info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", adapter, adapter->drvr_qdepth, adapter->drvr_sglimit);
1945 blogic_info(" Tagged Queue Depth: ", adapter);
1946 common_tagq_depth = true;
1947 for (tgt_id = 1; tgt_id < adapter->maxdev; tgt_id++)
1948 if (adapter->qdepth[tgt_id] != adapter->qdepth[0]) {
1949 common_tagq_depth = false;
1950 break;
1951 }
1952 if (common_tagq_depth) {
1953 if (adapter->qdepth[0] > 0)
1954 blogic_info("%d", adapter, adapter->qdepth[0]);
1955 else
1956 blogic_info("Automatic", adapter);
1957 } else
1958 blogic_info("Individual", adapter);
1959 blogic_info(", Untagged Queue Depth: %d\n", adapter,
1960 adapter->untag_qdepth);
1961 if (adapter->terminfo_valid) {
1962 if (adapter->wide)
1963 blogic_info(" SCSI Bus Termination: %s", adapter,
1964 (adapter->low_term ? (adapter->high_term ? "Both Enabled" : "Low Enabled") : (adapter->high_term ? "High Enabled" : "Both Disabled")));
1965 else
1966 blogic_info(" SCSI Bus Termination: %s", adapter,
1967 (adapter->low_term ? "Enabled" : "Disabled"));
1968 if (adapter->scam)
1969 blogic_info(", SCAM: %s", adapter,
1970 (adapter->scam_enabled ? (adapter->scam_lev2 ? "Enabled, Level 2" : "Enabled, Level 1") : "Disabled"));
1971 blogic_info("\n", adapter);
1972 }
1973
1974
1975
1976
1977 return true;
1978}
1979
1980
1981
1982
1983
1984
1985
1986static bool __init blogic_getres(struct blogic_adapter *adapter)
1987{
1988 if (adapter->irq_ch == 0) {
1989 blogic_err("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
1990 adapter);
1991 return false;
1992 }
1993
1994
1995
1996 if (request_irq(adapter->irq_ch, blogic_inthandler, IRQF_SHARED,
1997 adapter->full_model, adapter) < 0) {
1998 blogic_err("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
1999 adapter, adapter->irq_ch);
2000 return false;
2001 }
2002 adapter->irq_acquired = true;
2003
2004
2005
2006 if (adapter->dma_ch > 0) {
2007 if (request_dma(adapter->dma_ch, adapter->full_model) < 0) {
2008 blogic_err("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", adapter, adapter->dma_ch);
2009 return false;
2010 }
2011 set_dma_mode(adapter->dma_ch, DMA_MODE_CASCADE);
2012 enable_dma(adapter->dma_ch);
2013 adapter->dma_chan_acquired = true;
2014 }
2015
2016
2017
2018 return true;
2019}
2020
2021
2022
2023
2024
2025
2026
2027static void blogic_relres(struct blogic_adapter *adapter)
2028{
2029
2030
2031
2032 if (adapter->irq_acquired)
2033 free_irq(adapter->irq_ch, adapter);
2034
2035
2036
2037 if (adapter->dma_chan_acquired)
2038 free_dma(adapter->dma_ch);
2039
2040
2041
2042 if (adapter->mbox_space)
2043 pci_free_consistent(adapter->pci_device, adapter->mbox_sz,
2044 adapter->mbox_space, adapter->mbox_space_handle);
2045 pci_dev_put(adapter->pci_device);
2046 adapter->mbox_space = NULL;
2047 adapter->mbox_space_handle = 0;
2048 adapter->mbox_sz = 0;
2049}
2050
2051
2052
2053
2054
2055
2056
2057
2058static bool blogic_initadapter(struct blogic_adapter *adapter)
2059{
2060 struct blogic_extmbox_req extmbox_req;
2061 enum blogic_rr_req rr_req;
2062 enum blogic_setccb_fmt setccb_fmt;
2063 int tgt_id;
2064
2065
2066
2067
2068
2069 adapter->firstccb = NULL;
2070 adapter->lastccb = NULL;
2071
2072
2073
2074
2075
2076
2077 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
2078 adapter->bdr_pend[tgt_id] = NULL;
2079 adapter->tgt_flags[tgt_id].tagq_active = false;
2080 adapter->tgt_flags[tgt_id].cmd_good = false;
2081 adapter->active_cmds[tgt_id] = 0;
2082 adapter->cmds_since_rst[tgt_id] = 0;
2083 }
2084
2085
2086
2087
2088 if (blogic_flashpoint_type(adapter))
2089 goto done;
2090
2091
2092
2093
2094 adapter->mbox_sz = adapter->mbox_count * (sizeof(struct blogic_outbox) + sizeof(struct blogic_inbox));
2095 adapter->mbox_space = pci_alloc_consistent(adapter->pci_device,
2096 adapter->mbox_sz, &adapter->mbox_space_handle);
2097 if (adapter->mbox_space == NULL)
2098 return blogic_failure(adapter, "MAILBOX ALLOCATION");
2099 adapter->first_outbox = (struct blogic_outbox *) adapter->mbox_space;
2100 adapter->last_outbox = adapter->first_outbox + adapter->mbox_count - 1;
2101 adapter->next_outbox = adapter->first_outbox;
2102 adapter->first_inbox = (struct blogic_inbox *) (adapter->last_outbox + 1);
2103 adapter->last_inbox = adapter->first_inbox + adapter->mbox_count - 1;
2104 adapter->next_inbox = adapter->first_inbox;
2105
2106
2107
2108
2109 memset(adapter->first_outbox, 0,
2110 adapter->mbox_count * sizeof(struct blogic_outbox));
2111 memset(adapter->first_inbox, 0,
2112 adapter->mbox_count * sizeof(struct blogic_inbox));
2113
2114
2115
2116
2117
2118 extmbox_req.mbox_count = adapter->mbox_count;
2119 extmbox_req.base_mbox_addr = (u32) adapter->mbox_space_handle;
2120 if (blogic_cmd(adapter, BLOGIC_INIT_EXT_MBOX, &extmbox_req,
2121 sizeof(extmbox_req), NULL, 0) < 0)
2122 return blogic_failure(adapter, "MAILBOX INITIALIZATION");
2123
2124
2125
2126
2127
2128
2129
2130
2131 if (adapter->strict_rr) {
2132 rr_req = BLOGIC_STRICT_RR_MODE;
2133 if (blogic_cmd(adapter, BLOGIC_STRICT_RR, &rr_req,
2134 sizeof(rr_req), NULL, 0) < 0)
2135 return blogic_failure(adapter,
2136 "ENABLE STRICT ROUND ROBIN MODE");
2137 }
2138
2139
2140
2141
2142
2143 if (adapter->ext_lun) {
2144 setccb_fmt = BLOGIC_EXT_LUN_CCB;
2145 if (blogic_cmd(adapter, BLOGIC_SETCCB_FMT, &setccb_fmt,
2146 sizeof(setccb_fmt), NULL, 0) < 0)
2147 return blogic_failure(adapter, "SET CCB FORMAT");
2148 }
2149
2150
2151
2152
2153done:
2154 if (!adapter->adapter_initd) {
2155 blogic_info("*** %s Initialized Successfully ***\n", adapter,
2156 adapter->full_model);
2157 blogic_info("\n", adapter);
2158 } else
2159 blogic_warn("*** %s Initialized Successfully ***\n", adapter,
2160 adapter->full_model);
2161 adapter->adapter_initd = true;
2162
2163
2164
2165
2166 return true;
2167}
2168
2169
2170
2171
2172
2173
2174
2175static bool __init blogic_inquiry(struct blogic_adapter *adapter)
2176{
2177 u16 installed_devs;
2178 u8 installed_devs0to7[8];
2179 struct blogic_setup_info setupinfo;
2180 u8 sync_period[BLOGIC_MAXDEV];
2181 unsigned char req_replylen;
2182 int tgt_id;
2183
2184
2185
2186
2187
2188
2189
2190 blogic_delay(adapter->bus_settle_time);
2191
2192
2193
2194 if (blogic_flashpoint_type(adapter))
2195 return true;
2196
2197
2198
2199 if (adapter->drvr_opts != NULL && adapter->drvr_opts->stop_tgt_inquiry)
2200 return true;
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211 if (strcmp(adapter->fw_ver, "4.25") >= 0) {
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221 if (blogic_cmd(adapter, BLOGIC_INQ_DEV, NULL, 0,
2222 &installed_devs, sizeof(installed_devs))
2223 != sizeof(installed_devs))
2224 return blogic_failure(adapter, "INQUIRE TARGET DEVICES");
2225 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2226 adapter->tgt_flags[tgt_id].tgt_exists =
2227 (installed_devs & (1 << tgt_id) ? true : false);
2228 } else {
2229
2230
2231
2232
2233
2234
2235
2236
2237 if (blogic_cmd(adapter, BLOGIC_INQ_DEV0TO7, NULL, 0,
2238 &installed_devs0to7, sizeof(installed_devs0to7))
2239 != sizeof(installed_devs0to7))
2240 return blogic_failure(adapter,
2241 "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2242 for (tgt_id = 0; tgt_id < 8; tgt_id++)
2243 adapter->tgt_flags[tgt_id].tgt_exists =
2244 (installed_devs0to7[tgt_id] != 0 ? true : false);
2245 }
2246
2247
2248
2249 req_replylen = sizeof(setupinfo);
2250 if (blogic_cmd(adapter, BLOGIC_INQ_SETUPINFO, &req_replylen,
2251 sizeof(req_replylen), &setupinfo, sizeof(setupinfo))
2252 != sizeof(setupinfo))
2253 return blogic_failure(adapter, "INQUIRE SETUP INFORMATION");
2254 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2255 adapter->sync_offset[tgt_id] = (tgt_id < 8 ? setupinfo.sync0to7[tgt_id].offset : setupinfo.sync8to15[tgt_id - 8].offset);
2256 if (strcmp(adapter->fw_ver, "5.06L") >= 0)
2257 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2258 adapter->tgt_flags[tgt_id].wide_active = (tgt_id < 8 ? (setupinfo.wide_tx_active0to7 & (1 << tgt_id) ? true : false) : (setupinfo.wide_tx_active8to15 & (1 << (tgt_id - 8)) ? true : false));
2259
2260
2261
2262 if (adapter->fw_ver[0] >= '3') {
2263
2264
2265
2266
2267
2268
2269 req_replylen = sizeof(sync_period);
2270 if (blogic_cmd(adapter, BLOGIC_INQ_SYNC_PERIOD, &req_replylen,
2271 sizeof(req_replylen), &sync_period,
2272 sizeof(sync_period)) != sizeof(sync_period))
2273 return blogic_failure(adapter,
2274 "INQUIRE SYNCHRONOUS PERIOD");
2275 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2276 adapter->sync_period[tgt_id] = sync_period[tgt_id];
2277 } else
2278 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2279 if (setupinfo.sync0to7[tgt_id].offset > 0)
2280 adapter->sync_period[tgt_id] = 20 + 5 * setupinfo.sync0to7[tgt_id].tx_period;
2281
2282
2283
2284 return true;
2285}
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296static void __init blogic_inithoststruct(struct blogic_adapter *adapter,
2297 struct Scsi_Host *host)
2298{
2299 host->max_id = adapter->maxdev;
2300 host->max_lun = adapter->maxlun;
2301 host->max_channel = 0;
2302 host->unique_id = adapter->io_addr;
2303 host->this_id = adapter->scsi_id;
2304 host->can_queue = adapter->drvr_qdepth;
2305 host->sg_tablesize = adapter->drvr_sglimit;
2306 host->unchecked_isa_dma = adapter->need_bouncebuf;
2307 host->cmd_per_lun = adapter->untag_qdepth;
2308}
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318static int blogic_slaveconfig(struct scsi_device *dev)
2319{
2320 struct blogic_adapter *adapter =
2321 (struct blogic_adapter *) dev->host->hostdata;
2322 int tgt_id = dev->id;
2323 int qdepth = adapter->qdepth[tgt_id];
2324
2325 if (adapter->tgt_flags[tgt_id].tagq_ok &&
2326 (adapter->tagq_ok & (1 << tgt_id))) {
2327 if (qdepth == 0)
2328 qdepth = BLOGIC_MAX_AUTO_TAG_DEPTH;
2329 adapter->qdepth[tgt_id] = qdepth;
2330 scsi_change_queue_depth(dev, qdepth);
2331 } else {
2332 adapter->tagq_ok &= ~(1 << tgt_id);
2333 qdepth = adapter->untag_qdepth;
2334 adapter->qdepth[tgt_id] = qdepth;
2335 scsi_change_queue_depth(dev, qdepth);
2336 }
2337 qdepth = 0;
2338 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++)
2339 if (adapter->tgt_flags[tgt_id].tgt_exists)
2340 qdepth += adapter->qdepth[tgt_id];
2341 if (qdepth > adapter->alloc_ccbs)
2342 blogic_create_addlccbs(adapter, qdepth - adapter->alloc_ccbs,
2343 false);
2344 return 0;
2345}
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355static int __init blogic_init(void)
2356{
2357 int adapter_count = 0, drvr_optindex = 0, probeindex;
2358 struct blogic_adapter *adapter;
2359 int ret = 0;
2360
2361#ifdef MODULE
2362 if (BusLogic)
2363 blogic_setup(BusLogic);
2364#endif
2365
2366 if (blogic_probe_options.noprobe)
2367 return -ENODEV;
2368 blogic_probeinfo_list =
2369 kzalloc(BLOGIC_MAX_ADAPTERS * sizeof(struct blogic_probeinfo),
2370 GFP_KERNEL);
2371 if (blogic_probeinfo_list == NULL) {
2372 blogic_err("BusLogic: Unable to allocate Probe Info List\n",
2373 NULL);
2374 return -ENOMEM;
2375 }
2376
2377 adapter = kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL);
2378 if (adapter == NULL) {
2379 kfree(blogic_probeinfo_list);
2380 blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL);
2381 return -ENOMEM;
2382 }
2383
2384#ifdef MODULE
2385 if (BusLogic != NULL)
2386 blogic_setup(BusLogic);
2387#endif
2388 blogic_init_probeinfo_list(adapter);
2389 for (probeindex = 0; probeindex < blogic_probeinfo_count; probeindex++) {
2390 struct blogic_probeinfo *probeinfo =
2391 &blogic_probeinfo_list[probeindex];
2392 struct blogic_adapter *myadapter = adapter;
2393 struct Scsi_Host *host;
2394
2395 if (probeinfo->io_addr == 0)
2396 continue;
2397 memset(myadapter, 0, sizeof(struct blogic_adapter));
2398 myadapter->adapter_type = probeinfo->adapter_type;
2399 myadapter->adapter_bus_type = probeinfo->adapter_bus_type;
2400 myadapter->io_addr = probeinfo->io_addr;
2401 myadapter->pci_addr = probeinfo->pci_addr;
2402 myadapter->bus = probeinfo->bus;
2403 myadapter->dev = probeinfo->dev;
2404 myadapter->pci_device = probeinfo->pci_device;
2405 myadapter->irq_ch = probeinfo->irq_ch;
2406 myadapter->addr_count =
2407 blogic_adapter_addr_count[myadapter->adapter_type];
2408
2409
2410
2411
2412 if (!request_region(myadapter->io_addr, myadapter->addr_count,
2413 "BusLogic"))
2414 continue;
2415
2416
2417
2418
2419 if (!blogic_probe(myadapter)) {
2420 release_region(myadapter->io_addr,
2421 myadapter->addr_count);
2422 continue;
2423 }
2424
2425
2426
2427
2428 if (!blogic_hwreset(myadapter, true)) {
2429 release_region(myadapter->io_addr,
2430 myadapter->addr_count);
2431 continue;
2432 }
2433
2434
2435
2436
2437 if (!blogic_checkadapter(myadapter)) {
2438 release_region(myadapter->io_addr,
2439 myadapter->addr_count);
2440 continue;
2441 }
2442
2443
2444
2445 if (drvr_optindex < blogic_drvr_options_count)
2446 myadapter->drvr_opts =
2447 &blogic_drvr_options[drvr_optindex++];
2448
2449
2450
2451
2452 blogic_announce_drvr(myadapter);
2453
2454
2455
2456
2457 host = scsi_host_alloc(&blogic_template,
2458 sizeof(struct blogic_adapter));
2459 if (host == NULL) {
2460 release_region(myadapter->io_addr,
2461 myadapter->addr_count);
2462 continue;
2463 }
2464 myadapter = (struct blogic_adapter *) host->hostdata;
2465 memcpy(myadapter, adapter, sizeof(struct blogic_adapter));
2466 myadapter->scsi_host = host;
2467 myadapter->host_no = host->host_no;
2468
2469
2470
2471
2472 list_add_tail(&myadapter->host_list, &blogic_host_list);
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487 if (blogic_rdconfig(myadapter) &&
2488 blogic_reportconfig(myadapter) &&
2489 blogic_getres(myadapter) &&
2490 blogic_create_initccbs(myadapter) &&
2491 blogic_initadapter(myadapter) &&
2492 blogic_inquiry(myadapter)) {
2493
2494
2495
2496
2497
2498
2499 release_region(myadapter->io_addr,
2500 myadapter->addr_count);
2501 if (!request_region(myadapter->io_addr,
2502 myadapter->addr_count,
2503 myadapter->full_model)) {
2504 printk(KERN_WARNING
2505 "BusLogic: Release and re-register of "
2506 "port 0x%04lx failed \n",
2507 (unsigned long)myadapter->io_addr);
2508 blogic_destroy_ccbs(myadapter);
2509 blogic_relres(myadapter);
2510 list_del(&myadapter->host_list);
2511 scsi_host_put(host);
2512 ret = -ENOMEM;
2513 } else {
2514 blogic_inithoststruct(myadapter,
2515 host);
2516 if (scsi_add_host(host, myadapter->pci_device
2517 ? &myadapter->pci_device->dev
2518 : NULL)) {
2519 printk(KERN_WARNING
2520 "BusLogic: scsi_add_host()"
2521 "failed!\n");
2522 blogic_destroy_ccbs(myadapter);
2523 blogic_relres(myadapter);
2524 list_del(&myadapter->host_list);
2525 scsi_host_put(host);
2526 ret = -ENODEV;
2527 } else {
2528 scsi_scan_host(host);
2529 adapter_count++;
2530 }
2531 }
2532 } else {
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543 blogic_destroy_ccbs(myadapter);
2544 blogic_relres(myadapter);
2545 list_del(&myadapter->host_list);
2546 scsi_host_put(host);
2547 ret = -ENODEV;
2548 }
2549 }
2550 kfree(adapter);
2551 kfree(blogic_probeinfo_list);
2552 blogic_probeinfo_list = NULL;
2553 return ret;
2554}
2555
2556
2557
2558
2559
2560
2561
2562
2563static int __exit blogic_deladapter(struct blogic_adapter *adapter)
2564{
2565 struct Scsi_Host *host = adapter->scsi_host;
2566
2567 scsi_remove_host(host);
2568
2569
2570
2571
2572
2573 if (blogic_flashpoint_type(adapter))
2574 FlashPoint_ReleaseHostAdapter(adapter->cardhandle);
2575
2576
2577
2578
2579 blogic_destroy_ccbs(adapter);
2580 blogic_relres(adapter);
2581
2582
2583
2584 release_region(adapter->io_addr, adapter->addr_count);
2585
2586
2587
2588
2589 list_del(&adapter->host_list);
2590
2591 scsi_host_put(host);
2592 return 0;
2593}
2594
2595
2596
2597
2598
2599
2600static void blogic_qcompleted_ccb(struct blogic_ccb *ccb)
2601{
2602 struct blogic_adapter *adapter = ccb->adapter;
2603
2604 ccb->status = BLOGIC_CCB_COMPLETE;
2605 ccb->next = NULL;
2606 if (adapter->firstccb == NULL) {
2607 adapter->firstccb = ccb;
2608 adapter->lastccb = ccb;
2609 } else {
2610 adapter->lastccb->next = ccb;
2611 adapter->lastccb = ccb;
2612 }
2613 adapter->active_cmds[ccb->tgt_id]--;
2614}
2615
2616
2617
2618
2619
2620
2621
2622static int blogic_resultcode(struct blogic_adapter *adapter,
2623 enum blogic_adapter_status adapter_status,
2624 enum blogic_tgt_status tgt_status)
2625{
2626 int hoststatus;
2627
2628 switch (adapter_status) {
2629 case BLOGIC_CMD_CMPLT_NORMAL:
2630 case BLOGIC_LINK_CMD_CMPLT:
2631 case BLOGIC_LINK_CMD_CMPLT_FLAG:
2632 hoststatus = DID_OK;
2633 break;
2634 case BLOGIC_SELECT_TIMEOUT:
2635 hoststatus = DID_TIME_OUT;
2636 break;
2637 case BLOGIC_INVALID_OUTBOX_CODE:
2638 case BLOGIC_INVALID_CMD_CODE:
2639 case BLOGIC_BAD_CMD_PARAM:
2640 blogic_warn("BusLogic Driver Protocol Error 0x%02X\n",
2641 adapter, adapter_status);
2642 case BLOGIC_DATA_UNDERRUN:
2643 case BLOGIC_DATA_OVERRUN:
2644 case BLOGIC_NOEXPECT_BUSFREE:
2645 case BLOGIC_LINKCCB_BADLUN:
2646 case BLOGIC_AUTOREQSENSE_FAIL:
2647 case BLOGIC_TAGQUEUE_REJECT:
2648 case BLOGIC_BAD_MSG_RCVD:
2649 case BLOGIC_HW_FAIL:
2650 case BLOGIC_BAD_RECONNECT:
2651 case BLOGIC_ABRT_QUEUE:
2652 case BLOGIC_ADAPTER_SW_ERROR:
2653 case BLOGIC_HW_TIMEOUT:
2654 case BLOGIC_PARITY_ERR:
2655 hoststatus = DID_ERROR;
2656 break;
2657 case BLOGIC_INVALID_BUSPHASE:
2658 case BLOGIC_NORESPONSE_TO_ATN:
2659 case BLOGIC_HW_RESET:
2660 case BLOGIC_RST_FROM_OTHERDEV:
2661 case BLOGIC_HW_BDR:
2662 hoststatus = DID_RESET;
2663 break;
2664 default:
2665 blogic_warn("Unknown Host Adapter Status 0x%02X\n", adapter,
2666 adapter_status);
2667 hoststatus = DID_ERROR;
2668 break;
2669 }
2670 return (hoststatus << 16) | tgt_status;
2671}
2672
2673
2674
2675
2676
2677
2678
2679static void blogic_scan_inbox(struct blogic_adapter *adapter)
2680{
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694 struct blogic_inbox *next_inbox = adapter->next_inbox;
2695 enum blogic_cmplt_code comp_code;
2696
2697 while ((comp_code = next_inbox->comp_code) != BLOGIC_INBOX_FREE) {
2698
2699
2700
2701
2702
2703
2704
2705
2706 struct blogic_ccb *ccb =
2707 (struct blogic_ccb *) bus_to_virt(next_inbox->ccb);
2708 if (comp_code != BLOGIC_CMD_NOTFOUND) {
2709 if (ccb->status == BLOGIC_CCB_ACTIVE ||
2710 ccb->status == BLOGIC_CCB_RESET) {
2711
2712
2713
2714
2715 ccb->comp_code = comp_code;
2716 blogic_qcompleted_ccb(ccb);
2717 } else {
2718
2719
2720
2721
2722
2723
2724 blogic_warn("Illegal CCB #%ld status %d in " "Incoming Mailbox\n", adapter, ccb->serial, ccb->status);
2725 }
2726 }
2727 next_inbox->comp_code = BLOGIC_INBOX_FREE;
2728 if (++next_inbox > adapter->last_inbox)
2729 next_inbox = adapter->first_inbox;
2730 }
2731 adapter->next_inbox = next_inbox;
2732}
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742static void blogic_process_ccbs(struct blogic_adapter *adapter)
2743{
2744 if (adapter->processing_ccbs)
2745 return;
2746 adapter->processing_ccbs = true;
2747 while (adapter->firstccb != NULL) {
2748 struct blogic_ccb *ccb = adapter->firstccb;
2749 struct scsi_cmnd *command = ccb->command;
2750 adapter->firstccb = ccb->next;
2751 if (adapter->firstccb == NULL)
2752 adapter->lastccb = NULL;
2753
2754
2755
2756 if (ccb->opcode == BLOGIC_BDR) {
2757 int tgt_id = ccb->tgt_id;
2758
2759 blogic_warn("Bus Device Reset CCB #%ld to Target " "%d Completed\n", adapter, ccb->serial, tgt_id);
2760 blogic_inc_count(&adapter->tgt_stats[tgt_id].bdr_done);
2761 adapter->tgt_flags[tgt_id].tagq_active = false;
2762 adapter->cmds_since_rst[tgt_id] = 0;
2763 adapter->last_resetdone[tgt_id] = jiffies;
2764
2765
2766
2767 blogic_dealloc_ccb(ccb, 1);
2768#if 0
2769
2770
2771
2772
2773
2774
2775
2776
2777 while (command != NULL) {
2778 struct scsi_cmnd *nxt_cmd =
2779 command->reset_chain;
2780 command->reset_chain = NULL;
2781 command->result = DID_RESET << 16;
2782 command->scsi_done(command);
2783 command = nxt_cmd;
2784 }
2785#endif
2786
2787
2788
2789
2790
2791 for (ccb = adapter->all_ccbs; ccb != NULL;
2792 ccb = ccb->next_all)
2793 if (ccb->status == BLOGIC_CCB_RESET &&
2794 ccb->tgt_id == tgt_id) {
2795 command = ccb->command;
2796 blogic_dealloc_ccb(ccb, 1);
2797 adapter->active_cmds[tgt_id]--;
2798 command->result = DID_RESET << 16;
2799 command->scsi_done(command);
2800 }
2801 adapter->bdr_pend[tgt_id] = NULL;
2802 } else {
2803
2804
2805
2806
2807
2808 switch (ccb->comp_code) {
2809 case BLOGIC_INBOX_FREE:
2810 case BLOGIC_CMD_NOTFOUND:
2811 case BLOGIC_INVALID_CCB:
2812 blogic_warn("CCB #%ld to Target %d Impossible State\n", adapter, ccb->serial, ccb->tgt_id);
2813 break;
2814 case BLOGIC_CMD_COMPLETE_GOOD:
2815 adapter->tgt_stats[ccb->tgt_id]
2816 .cmds_complete++;
2817 adapter->tgt_flags[ccb->tgt_id]
2818 .cmd_good = true;
2819 command->result = DID_OK << 16;
2820 break;
2821 case BLOGIC_CMD_ABORT_BY_HOST:
2822 blogic_warn("CCB #%ld to Target %d Aborted\n",
2823 adapter, ccb->serial, ccb->tgt_id);
2824 blogic_inc_count(&adapter->tgt_stats[ccb->tgt_id].aborts_done);
2825 command->result = DID_ABORT << 16;
2826 break;
2827 case BLOGIC_CMD_COMPLETE_ERROR:
2828 command->result = blogic_resultcode(adapter,
2829 ccb->adapter_status, ccb->tgt_status);
2830 if (ccb->adapter_status != BLOGIC_SELECT_TIMEOUT) {
2831 adapter->tgt_stats[ccb->tgt_id]
2832 .cmds_complete++;
2833 if (blogic_global_options.trace_err) {
2834 int i;
2835 blogic_notice("CCB #%ld Target %d: Result %X Host "
2836 "Adapter Status %02X " "Target Status %02X\n", adapter, ccb->serial, ccb->tgt_id, command->result, ccb->adapter_status, ccb->tgt_status);
2837 blogic_notice("CDB ", adapter);
2838 for (i = 0; i < ccb->cdblen; i++)
2839 blogic_notice(" %02X", adapter, ccb->cdb[i]);
2840 blogic_notice("\n", adapter);
2841 blogic_notice("Sense ", adapter);
2842 for (i = 0; i < ccb->sense_datalen; i++)
2843 blogic_notice(" %02X", adapter, command->sense_buffer[i]);
2844 blogic_notice("\n", adapter);
2845 }
2846 }
2847 break;
2848 }
2849
2850
2851
2852
2853
2854 if (ccb->cdb[0] == INQUIRY && ccb->cdb[1] == 0 &&
2855 ccb->adapter_status == BLOGIC_CMD_CMPLT_NORMAL) {
2856 struct blogic_tgt_flags *tgt_flags =
2857 &adapter->tgt_flags[ccb->tgt_id];
2858 struct scsi_inquiry *inquiry =
2859 (struct scsi_inquiry *) scsi_sglist(command);
2860 tgt_flags->tgt_exists = true;
2861 tgt_flags->tagq_ok = inquiry->CmdQue;
2862 tgt_flags->wide_ok = inquiry->WBus16;
2863 }
2864
2865
2866
2867 blogic_dealloc_ccb(ccb, 1);
2868
2869
2870
2871 command->scsi_done(command);
2872 }
2873 }
2874 adapter->processing_ccbs = false;
2875}
2876
2877
2878
2879
2880
2881
2882
2883static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
2884{
2885 struct blogic_adapter *adapter = (struct blogic_adapter *) devid;
2886 unsigned long processor_flag;
2887
2888
2889
2890 spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag);
2891
2892
2893
2894 if (blogic_multimaster_type(adapter)) {
2895 union blogic_int_reg intreg;
2896
2897
2898
2899 intreg.all = blogic_rdint(adapter);
2900 if (intreg.ir.int_valid) {
2901
2902
2903
2904
2905 blogic_intreset(adapter);
2906
2907
2908
2909
2910
2911
2912 if (intreg.ir.ext_busreset)
2913 adapter->adapter_extreset = true;
2914 else if (intreg.ir.mailin_loaded)
2915 blogic_scan_inbox(adapter);
2916 else if (intreg.ir.cmd_complete)
2917 adapter->adapter_cmd_complete = true;
2918 }
2919 } else {
2920
2921
2922
2923 if (FlashPoint_InterruptPending(adapter->cardhandle))
2924 switch (FlashPoint_HandleInterrupt(adapter->cardhandle)) {
2925 case FPOINT_NORMAL_INT:
2926 break;
2927 case FPOINT_EXT_RESET:
2928 adapter->adapter_extreset = true;
2929 break;
2930 case FPOINT_INTERN_ERR:
2931 blogic_warn("Internal FlashPoint Error detected - Resetting Host Adapter\n", adapter);
2932 adapter->adapter_intern_err = true;
2933 break;
2934 }
2935 }
2936
2937
2938
2939 if (adapter->firstccb != NULL)
2940 blogic_process_ccbs(adapter);
2941
2942
2943
2944 if (adapter->adapter_extreset) {
2945 blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model);
2946 blogic_inc_count(&adapter->ext_resets);
2947 blogic_resetadapter(adapter, false);
2948 adapter->adapter_extreset = false;
2949 } else if (adapter->adapter_intern_err) {
2950 blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model);
2951 blogic_inc_count(&adapter->adapter_intern_errors);
2952 blogic_resetadapter(adapter, true);
2953 adapter->adapter_intern_err = false;
2954 }
2955
2956
2957
2958 spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag);
2959 return IRQ_HANDLED;
2960}
2961
2962
2963
2964
2965
2966
2967
2968
2969static bool blogic_write_outbox(struct blogic_adapter *adapter,
2970 enum blogic_action action, struct blogic_ccb *ccb)
2971{
2972 struct blogic_outbox *next_outbox;
2973
2974 next_outbox = adapter->next_outbox;
2975 if (next_outbox->action == BLOGIC_OUTBOX_FREE) {
2976 ccb->status = BLOGIC_CCB_ACTIVE;
2977
2978
2979
2980
2981
2982
2983 next_outbox->ccb = ccb->dma_handle;
2984 next_outbox->action = action;
2985 blogic_execmbox(adapter);
2986 if (++next_outbox > adapter->last_outbox)
2987 next_outbox = adapter->first_outbox;
2988 adapter->next_outbox = next_outbox;
2989 if (action == BLOGIC_MBOX_START) {
2990 adapter->active_cmds[ccb->tgt_id]++;
2991 if (ccb->opcode != BLOGIC_BDR)
2992 adapter->tgt_stats[ccb->tgt_id].cmds_tried++;
2993 }
2994 return true;
2995 }
2996 return false;
2997}
2998
2999
3000
3001static int blogic_hostreset(struct scsi_cmnd *SCpnt)
3002{
3003 struct blogic_adapter *adapter =
3004 (struct blogic_adapter *) SCpnt->device->host->hostdata;
3005
3006 unsigned int id = SCpnt->device->id;
3007 struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
3008 int rc;
3009
3010 spin_lock_irq(SCpnt->device->host->host_lock);
3011
3012 blogic_inc_count(&stats->adatper_reset_req);
3013
3014 rc = blogic_resetadapter(adapter, false);
3015 spin_unlock_irq(SCpnt->device->host->host_lock);
3016 return rc;
3017}
3018
3019
3020
3021
3022
3023
3024static int blogic_qcmd_lck(struct scsi_cmnd *command,
3025 void (*comp_cb) (struct scsi_cmnd *))
3026{
3027 struct blogic_adapter *adapter =
3028 (struct blogic_adapter *) command->device->host->hostdata;
3029 struct blogic_tgt_flags *tgt_flags =
3030 &adapter->tgt_flags[command->device->id];
3031 struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
3032 unsigned char *cdb = command->cmnd;
3033 int cdblen = command->cmd_len;
3034 int tgt_id = command->device->id;
3035 int lun = command->device->lun;
3036 int buflen = scsi_bufflen(command);
3037 int count;
3038 struct blogic_ccb *ccb;
3039 dma_addr_t sense_buf;
3040
3041
3042
3043
3044
3045
3046
3047 if (cdb[0] == REQUEST_SENSE && command->sense_buffer[0] != 0) {
3048 command->result = DID_OK << 16;
3049 comp_cb(command);
3050 return 0;
3051 }
3052
3053
3054
3055
3056
3057
3058
3059 ccb = blogic_alloc_ccb(adapter);
3060 if (ccb == NULL) {
3061 spin_unlock_irq(adapter->scsi_host->host_lock);
3062 blogic_delay(1);
3063 spin_lock_irq(adapter->scsi_host->host_lock);
3064 ccb = blogic_alloc_ccb(adapter);
3065 if (ccb == NULL) {
3066 command->result = DID_ERROR << 16;
3067 comp_cb(command);
3068 return 0;
3069 }
3070 }
3071
3072
3073
3074
3075 count = scsi_dma_map(command);
3076 BUG_ON(count < 0);
3077 if (count) {
3078 struct scatterlist *sg;
3079 int i;
3080
3081 ccb->opcode = BLOGIC_INITIATOR_CCB_SG;
3082 ccb->datalen = count * sizeof(struct blogic_sg_seg);
3083 if (blogic_multimaster_type(adapter))
3084 ccb->data = (void *)((unsigned int) ccb->dma_handle +
3085 ((unsigned long) &ccb->sglist -
3086 (unsigned long) ccb));
3087 else
3088 ccb->data = ccb->sglist;
3089
3090 scsi_for_each_sg(command, sg, count, i) {
3091 ccb->sglist[i].segbytes = sg_dma_len(sg);
3092 ccb->sglist[i].segdata = sg_dma_address(sg);
3093 }
3094 } else if (!count) {
3095 ccb->opcode = BLOGIC_INITIATOR_CCB;
3096 ccb->datalen = buflen;
3097 ccb->data = 0;
3098 }
3099
3100 switch (cdb[0]) {
3101 case READ_6:
3102 case READ_10:
3103 ccb->datadir = BLOGIC_DATAIN_CHECKED;
3104 tgt_stats[tgt_id].read_cmds++;
3105 blogic_addcount(&tgt_stats[tgt_id].bytesread, buflen);
3106 blogic_incszbucket(tgt_stats[tgt_id].read_sz_buckets, buflen);
3107 break;
3108 case WRITE_6:
3109 case WRITE_10:
3110 ccb->datadir = BLOGIC_DATAOUT_CHECKED;
3111 tgt_stats[tgt_id].write_cmds++;
3112 blogic_addcount(&tgt_stats[tgt_id].byteswritten, buflen);
3113 blogic_incszbucket(tgt_stats[tgt_id].write_sz_buckets, buflen);
3114 break;
3115 default:
3116 ccb->datadir = BLOGIC_UNCHECKED_TX;
3117 break;
3118 }
3119 ccb->cdblen = cdblen;
3120 ccb->adapter_status = 0;
3121 ccb->tgt_status = 0;
3122 ccb->tgt_id = tgt_id;
3123 ccb->lun = lun;
3124 ccb->tag_enable = false;
3125 ccb->legacytag_enable = false;
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142 if (adapter->cmds_since_rst[tgt_id]++ >= BLOGIC_MAX_TAG_DEPTH &&
3143 !tgt_flags->tagq_active &&
3144 adapter->active_cmds[tgt_id] == 0
3145 && tgt_flags->tagq_ok &&
3146 (adapter->tagq_ok & (1 << tgt_id))) {
3147 tgt_flags->tagq_active = true;
3148 blogic_notice("Tagged Queuing now active for Target %d\n",
3149 adapter, tgt_id);
3150 }
3151 if (tgt_flags->tagq_active) {
3152 enum blogic_queuetag queuetag = BLOGIC_SIMPLETAG;
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168 if (adapter->active_cmds[tgt_id] == 0)
3169 adapter->last_seqpoint[tgt_id] = jiffies;
3170 else if (time_after(jiffies,
3171 adapter->last_seqpoint[tgt_id] + 4 * HZ)) {
3172 adapter->last_seqpoint[tgt_id] = jiffies;
3173 queuetag = BLOGIC_ORDEREDTAG;
3174 }
3175 if (adapter->ext_lun) {
3176 ccb->tag_enable = true;
3177 ccb->queuetag = queuetag;
3178 } else {
3179 ccb->legacytag_enable = true;
3180 ccb->legacy_tag = queuetag;
3181 }
3182 }
3183 memcpy(ccb->cdb, cdb, cdblen);
3184 ccb->sense_datalen = SCSI_SENSE_BUFFERSIZE;
3185 ccb->command = command;
3186 sense_buf = pci_map_single(adapter->pci_device,
3187 command->sense_buffer, ccb->sense_datalen,
3188 PCI_DMA_FROMDEVICE);
3189 if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
3190 blogic_err("DMA mapping for sense data buffer failed\n",
3191 adapter);
3192 blogic_dealloc_ccb(ccb, 0);
3193 return SCSI_MLQUEUE_HOST_BUSY;
3194 }
3195 ccb->sensedata = sense_buf;
3196 command->scsi_done = comp_cb;
3197 if (blogic_multimaster_type(adapter)) {
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208 if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
3209 spin_unlock_irq(adapter->scsi_host->host_lock);
3210 blogic_warn("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", adapter);
3211 blogic_delay(1);
3212 spin_lock_irq(adapter->scsi_host->host_lock);
3213 if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
3214 ccb)) {
3215 blogic_warn("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", adapter);
3216 blogic_dealloc_ccb(ccb, 1);
3217 command->result = DID_ERROR << 16;
3218 command->scsi_done(command);
3219 }
3220 }
3221 } else {
3222
3223
3224
3225
3226 ccb->status = BLOGIC_CCB_ACTIVE;
3227 adapter->active_cmds[tgt_id]++;
3228 tgt_stats[tgt_id].cmds_tried++;
3229 FlashPoint_StartCCB(adapter->cardhandle, ccb);
3230
3231
3232
3233
3234
3235 if (ccb->status == BLOGIC_CCB_COMPLETE)
3236 blogic_process_ccbs(adapter);
3237 }
3238 return 0;
3239}
3240
3241static DEF_SCSI_QCMD(blogic_qcmd)
3242
3243#if 0
3244
3245
3246
3247
3248static int blogic_abort(struct scsi_cmnd *command)
3249{
3250 struct blogic_adapter *adapter =
3251 (struct blogic_adapter *) command->device->host->hostdata;
3252
3253 int tgt_id = command->device->id;
3254 struct blogic_ccb *ccb;
3255 blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);
3256
3257
3258
3259
3260
3261 for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
3262 if (ccb->command == command)
3263 break;
3264 if (ccb == NULL) {
3265 blogic_warn("Unable to Abort Command to Target %d - No CCB Found\n", adapter, tgt_id);
3266 return SUCCESS;
3267 } else if (ccb->status == BLOGIC_CCB_COMPLETE) {
3268 blogic_warn("Unable to Abort Command to Target %d - CCB Completed\n", adapter, tgt_id);
3269 return SUCCESS;
3270 } else if (ccb->status == BLOGIC_CCB_RESET) {
3271 blogic_warn("Unable to Abort Command to Target %d - CCB Reset\n", adapter, tgt_id);
3272 return SUCCESS;
3273 }
3274 if (blogic_multimaster_type(adapter)) {
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287 if (adapter->tgt_flags[tgt_id].tagq_active &&
3288 adapter->fw_ver[0] < '5') {
3289 blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
3290 return FAILURE;
3291 } else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
3292 ccb)) {
3293 blogic_warn("Aborting CCB #%ld to Target %d\n",
3294 adapter, ccb->serial, tgt_id);
3295 blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
3296 return SUCCESS;
3297 } else {
3298 blogic_warn("Unable to Abort CCB #%ld to Target %d - No Outgoing Mailboxes\n", adapter, ccb->serial, tgt_id);
3299 return FAILURE;
3300 }
3301 } else {
3302
3303
3304
3305
3306 blogic_warn("Aborting CCB #%ld to Target %d\n", adapter,
3307 ccb->serial, tgt_id);
3308 blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_tried);
3309 FlashPoint_AbortCCB(adapter->cardhandle, ccb);
3310
3311
3312
3313
3314
3315 if (ccb->status == BLOGIC_CCB_COMPLETE)
3316 blogic_process_ccbs(adapter);
3317 return SUCCESS;
3318 }
3319 return SUCCESS;
3320}
3321
3322#endif
3323
3324
3325
3326
3327
3328static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
3329{
3330 struct blogic_ccb *ccb;
3331 int tgt_id;
3332
3333
3334
3335
3336
3337 if (!(blogic_hwreset(adapter, hard_reset) &&
3338 blogic_initadapter(adapter))) {
3339 blogic_err("Resetting %s Failed\n", adapter,
3340 adapter->full_model);
3341 return FAILURE;
3342 }
3343
3344
3345
3346
3347
3348 for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
3349 if (ccb->status == BLOGIC_CCB_ACTIVE)
3350 blogic_dealloc_ccb(ccb, 1);
3351
3352
3353
3354
3355
3356
3357
3358 if (hard_reset) {
3359 spin_unlock_irq(adapter->scsi_host->host_lock);
3360 blogic_delay(adapter->bus_settle_time);
3361 spin_lock_irq(adapter->scsi_host->host_lock);
3362 }
3363
3364 for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
3365 adapter->last_resettried[tgt_id] = jiffies;
3366 adapter->last_resetdone[tgt_id] = jiffies;
3367 }
3368 return SUCCESS;
3369}
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388static int blogic_diskparam(struct scsi_device *sdev, struct block_device *dev,
3389 sector_t capacity, int *params)
3390{
3391 struct blogic_adapter *adapter =
3392 (struct blogic_adapter *) sdev->host->hostdata;
3393 struct bios_diskparam *diskparam = (struct bios_diskparam *) params;
3394 unsigned char *buf;
3395
3396 if (adapter->ext_trans_enable && capacity >= 2 * 1024 * 1024 ) {
3397 if (capacity >= 4 * 1024 * 1024 ) {
3398 diskparam->heads = 255;
3399 diskparam->sectors = 63;
3400 } else {
3401 diskparam->heads = 128;
3402 diskparam->sectors = 32;
3403 }
3404 } else {
3405 diskparam->heads = 64;
3406 diskparam->sectors = 32;
3407 }
3408 diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
3409 buf = scsi_bios_ptable(dev);
3410 if (buf == NULL)
3411 return 0;
3412
3413
3414
3415
3416
3417 if (*(unsigned short *) (buf + 64) == 0xAA55) {
3418 struct partition *part1_entry = (struct partition *) buf;
3419 struct partition *part_entry = part1_entry;
3420 int saved_cyl = diskparam->cylinders, part_no;
3421 unsigned char part_end_head = 0, part_end_sector = 0;
3422
3423 for (part_no = 0; part_no < 4; part_no++) {
3424 part_end_head = part_entry->end_head;
3425 part_end_sector = part_entry->end_sector & 0x3F;
3426 if (part_end_head == 64 - 1) {
3427 diskparam->heads = 64;
3428 diskparam->sectors = 32;
3429 break;
3430 } else if (part_end_head == 128 - 1) {
3431 diskparam->heads = 128;
3432 diskparam->sectors = 32;
3433 break;
3434 } else if (part_end_head == 255 - 1) {
3435 diskparam->heads = 255;
3436 diskparam->sectors = 63;
3437 break;
3438 }
3439 part_entry++;
3440 }
3441 if (part_no == 4) {
3442 part_end_head = part1_entry->end_head;
3443 part_end_sector = part1_entry->end_sector & 0x3F;
3444 }
3445 diskparam->cylinders = (unsigned long) capacity / (diskparam->heads * diskparam->sectors);
3446 if (part_no < 4 && part_end_sector == diskparam->sectors) {
3447 if (diskparam->cylinders != saved_cyl)
3448 blogic_warn("Adopting Geometry %d/%d from Partition Table\n", adapter, diskparam->heads, diskparam->sectors);
3449 } else if (part_end_head > 0 || part_end_sector > 0) {
3450 blogic_warn("Warning: Partition Table appears to " "have Geometry %d/%d which is\n", adapter, part_end_head + 1, part_end_sector);
3451 blogic_warn("not compatible with current BusLogic " "Host Adapter Geometry %d/%d\n", adapter, diskparam->heads, diskparam->sectors);
3452 }
3453 }
3454 kfree(buf);
3455 return 0;
3456}
3457
3458
3459
3460
3461
3462
3463static int blogic_write_info(struct Scsi_Host *shost, char *procbuf,
3464 int bytes_avail)
3465{
3466 struct blogic_adapter *adapter =
3467 (struct blogic_adapter *) shost->hostdata;
3468 struct blogic_tgt_stats *tgt_stats;
3469
3470 tgt_stats = adapter->tgt_stats;
3471 adapter->ext_resets = 0;
3472 adapter->adapter_intern_errors = 0;
3473 memset(tgt_stats, 0, BLOGIC_MAXDEV * sizeof(struct blogic_tgt_stats));
3474 return 0;
3475}
3476
3477static int blogic_show_info(struct seq_file *m, struct Scsi_Host *shost)
3478{
3479 struct blogic_adapter *adapter = (struct blogic_adapter *) shost->hostdata;
3480 struct blogic_tgt_stats *tgt_stats;
3481 int tgt;
3482
3483 tgt_stats = adapter->tgt_stats;
3484 seq_write(m, adapter->msgbuf, adapter->msgbuflen);
3485 seq_printf(m, "\n\
3486Current Driver Queue Depth: %d\n\
3487Currently Allocated CCBs: %d\n", adapter->drvr_qdepth, adapter->alloc_ccbs);
3488 seq_puts(m, "\n\n\
3489 DATA TRANSFER STATISTICS\n\
3490\n\
3491Target Tagged Queuing Queue Depth Active Attempted Completed\n\
3492====== ============== =========== ====== ========= =========\n");
3493 for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3494 struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3495 if (!tgt_flags->tgt_exists)
3496 continue;
3497 seq_printf(m, " %2d %s", tgt, (tgt_flags->tagq_ok ? (tgt_flags->tagq_active ? " Active" : (adapter->tagq_ok & (1 << tgt)
3498 ? " Permitted" : " Disabled"))
3499 : "Not Supported"));
3500 seq_printf(m,
3501 " %3d %3u %9u %9u\n", adapter->qdepth[tgt], adapter->active_cmds[tgt], tgt_stats[tgt].cmds_tried, tgt_stats[tgt].cmds_complete);
3502 }
3503 seq_puts(m, "\n\
3504Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
3505====== ============= ============== =================== ===================\n");
3506 for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3507 struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3508 if (!tgt_flags->tgt_exists)
3509 continue;
3510 seq_printf(m, " %2d %9u %9u", tgt, tgt_stats[tgt].read_cmds, tgt_stats[tgt].write_cmds);
3511 if (tgt_stats[tgt].bytesread.billions > 0)
3512 seq_printf(m, " %9u%09u", tgt_stats[tgt].bytesread.billions, tgt_stats[tgt].bytesread.units);
3513 else
3514 seq_printf(m, " %9u", tgt_stats[tgt].bytesread.units);
3515 if (tgt_stats[tgt].byteswritten.billions > 0)
3516 seq_printf(m, " %9u%09u\n", tgt_stats[tgt].byteswritten.billions, tgt_stats[tgt].byteswritten.units);
3517 else
3518 seq_printf(m, " %9u\n", tgt_stats[tgt].byteswritten.units);
3519 }
3520 seq_puts(m, "\n\
3521Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
3522====== ======= ========= ========= ========= ========= =========\n");
3523 for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3524 struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3525 if (!tgt_flags->tgt_exists)
3526 continue;
3527 seq_printf(m,
3528 " %2d Read %9u %9u %9u %9u %9u\n", tgt,
3529 tgt_stats[tgt].read_sz_buckets[0],
3530 tgt_stats[tgt].read_sz_buckets[1], tgt_stats[tgt].read_sz_buckets[2], tgt_stats[tgt].read_sz_buckets[3], tgt_stats[tgt].read_sz_buckets[4]);
3531 seq_printf(m,
3532 " %2d Write %9u %9u %9u %9u %9u\n", tgt,
3533 tgt_stats[tgt].write_sz_buckets[0],
3534 tgt_stats[tgt].write_sz_buckets[1], tgt_stats[tgt].write_sz_buckets[2], tgt_stats[tgt].write_sz_buckets[3], tgt_stats[tgt].write_sz_buckets[4]);
3535 }
3536 seq_puts(m, "\n\
3537Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
3538====== ======= ========= ========= ========= ========= =========\n");
3539 for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3540 struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3541 if (!tgt_flags->tgt_exists)
3542 continue;
3543 seq_printf(m,
3544 " %2d Read %9u %9u %9u %9u %9u\n", tgt,
3545 tgt_stats[tgt].read_sz_buckets[5],
3546 tgt_stats[tgt].read_sz_buckets[6], tgt_stats[tgt].read_sz_buckets[7], tgt_stats[tgt].read_sz_buckets[8], tgt_stats[tgt].read_sz_buckets[9]);
3547 seq_printf(m,
3548 " %2d Write %9u %9u %9u %9u %9u\n", tgt,
3549 tgt_stats[tgt].write_sz_buckets[5],
3550 tgt_stats[tgt].write_sz_buckets[6], tgt_stats[tgt].write_sz_buckets[7], tgt_stats[tgt].write_sz_buckets[8], tgt_stats[tgt].write_sz_buckets[9]);
3551 }
3552 seq_puts(m, "\n\n\
3553 ERROR RECOVERY STATISTICS\n\
3554\n\
3555 Command Aborts Bus Device Resets Host Adapter Resets\n\
3556Target Requested Completed Requested Completed Requested Completed\n\
3557 ID \\\\\\\\ Attempted
3558====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
3559 for (tgt = 0; tgt < adapter->maxdev; tgt++) {
3560 struct blogic_tgt_flags *tgt_flags = &adapter->tgt_flags[tgt];
3561 if (!tgt_flags->tgt_exists)
3562 continue;
3563 seq_printf(m, "\
3564 %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", tgt, tgt_stats[tgt].aborts_request, tgt_stats[tgt].aborts_tried, tgt_stats[tgt].aborts_done, tgt_stats[tgt].bdr_request, tgt_stats[tgt].bdr_tried, tgt_stats[tgt].bdr_done, tgt_stats[tgt].adatper_reset_req, tgt_stats[tgt].adapter_reset_attempt, tgt_stats[tgt].adapter_reset_done);
3565 }
3566 seq_printf(m, "\nExternal Host Adapter Resets: %d\n", adapter->ext_resets);
3567 seq_printf(m, "Host Adapter Internal Errors: %d\n", adapter->adapter_intern_errors);
3568 return 0;
3569}
3570
3571
3572
3573
3574
3575
3576static void blogic_msg(enum blogic_msglevel msglevel, char *fmt,
3577 struct blogic_adapter *adapter, ...)
3578{
3579 static char buf[BLOGIC_LINEBUF_SIZE];
3580 static bool begin = true;
3581 va_list args;
3582 int len = 0;
3583
3584 va_start(args, adapter);
3585 len = vsprintf(buf, fmt, args);
3586 va_end(args);
3587 if (msglevel == BLOGIC_ANNOUNCE_LEVEL) {
3588 static int msglines = 0;
3589 strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
3590 adapter->msgbuflen += len;
3591 if (++msglines <= 2)
3592 printk("%sscsi: %s", blogic_msglevelmap[msglevel], buf);
3593 } else if (msglevel == BLOGIC_INFO_LEVEL) {
3594 strcpy(&adapter->msgbuf[adapter->msgbuflen], buf);
3595 adapter->msgbuflen += len;
3596 if (begin) {
3597 if (buf[0] != '\n' || len > 1)
3598 printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
3599 } else
3600 printk("%s", buf);
3601 } else {
3602 if (begin) {
3603 if (adapter != NULL && adapter->adapter_initd)
3604 printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf);
3605 else
3606 printk("%s%s", blogic_msglevelmap[msglevel], buf);
3607 } else
3608 printk("%s", buf);
3609 }
3610 begin = (buf[len - 1] == '\n');
3611}
3612
3613
3614
3615
3616
3617
3618
3619static bool __init blogic_parse(char **str, char *keyword)
3620{
3621 char *pointer = *str;
3622 while (*keyword != '\0') {
3623 char strch = *pointer++;
3624 char keywordch = *keyword++;
3625 if (strch >= 'A' && strch <= 'Z')
3626 strch += 'a' - 'Z';
3627 if (keywordch >= 'A' && keywordch <= 'Z')
3628 keywordch += 'a' - 'Z';
3629 if (strch != keywordch)
3630 return false;
3631 }
3632 *str = pointer;
3633 return true;
3634}
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654static int __init blogic_parseopts(char *options)
3655{
3656 while (true) {
3657 struct blogic_drvr_options *drvr_opts =
3658 &blogic_drvr_options[blogic_drvr_options_count++];
3659 int tgt_id;
3660
3661 memset(drvr_opts, 0, sizeof(struct blogic_drvr_options));
3662 while (*options != '\0' && *options != ';') {
3663
3664 if (blogic_parse(&options, "IO:")) {
3665 unsigned long io_addr = simple_strtoul(options,
3666 &options, 0);
3667 blogic_probe_options.limited_isa = true;
3668 switch (io_addr) {
3669 case 0x330:
3670 blogic_probe_options.probe330 = true;
3671 break;
3672 case 0x334:
3673 blogic_probe_options.probe334 = true;
3674 break;
3675 case 0x230:
3676 blogic_probe_options.probe230 = true;
3677 break;
3678 case 0x234:
3679 blogic_probe_options.probe234 = true;
3680 break;
3681 case 0x130:
3682 blogic_probe_options.probe130 = true;
3683 break;
3684 case 0x134:
3685 blogic_probe_options.probe134 = true;
3686 break;
3687 default:
3688 blogic_err("BusLogic: Invalid Driver Options " "(invalid I/O Address 0x%X)\n", NULL, io_addr);
3689 return 0;
3690 }
3691 } else if (blogic_parse(&options, "NoProbeISA"))
3692 blogic_probe_options.noprobe_isa = true;
3693 else if (blogic_parse(&options, "NoProbePCI"))
3694 blogic_probe_options.noprobe_pci = true;
3695 else if (blogic_parse(&options, "NoProbe"))
3696 blogic_probe_options.noprobe = true;
3697 else if (blogic_parse(&options, "NoSortPCI"))
3698 blogic_probe_options.nosort_pci = true;
3699 else if (blogic_parse(&options, "MultiMasterFirst"))
3700 blogic_probe_options.multimaster_first = true;
3701 else if (blogic_parse(&options, "FlashPointFirst"))
3702 blogic_probe_options.flashpoint_first = true;
3703
3704 else if (blogic_parse(&options, "QueueDepth:[") ||
3705 blogic_parse(&options, "QD:[")) {
3706 for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++) {
3707 unsigned short qdepth = simple_strtoul(options, &options, 0);
3708 if (qdepth > BLOGIC_MAX_TAG_DEPTH) {
3709 blogic_err("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, qdepth);
3710 return 0;
3711 }
3712 drvr_opts->qdepth[tgt_id] = qdepth;
3713 if (*options == ',')
3714 options++;
3715 else if (*options == ']')
3716 break;
3717 else {
3718 blogic_err("BusLogic: Invalid Driver Options " "(',' or ']' expected at '%s')\n", NULL, options);
3719 return 0;
3720 }
3721 }
3722 if (*options != ']') {
3723 blogic_err("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, options);
3724 return 0;
3725 } else
3726 options++;
3727 } else if (blogic_parse(&options, "QueueDepth:") || blogic_parse(&options, "QD:")) {
3728 unsigned short qdepth = simple_strtoul(options, &options, 0);
3729 if (qdepth == 0 ||
3730 qdepth > BLOGIC_MAX_TAG_DEPTH) {
3731 blogic_err("BusLogic: Invalid Driver Options " "(invalid Queue Depth %d)\n", NULL, qdepth);
3732 return 0;
3733 }
3734 drvr_opts->common_qdepth = qdepth;
3735 for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
3736 drvr_opts->qdepth[tgt_id] = qdepth;
3737 } else if (blogic_parse(&options, "TaggedQueuing:") ||
3738 blogic_parse(&options, "TQ:")) {
3739 if (blogic_parse(&options, "Default")) {
3740 drvr_opts->tagq_ok = 0x0000;
3741 drvr_opts->tagq_ok_mask = 0x0000;
3742 } else if (blogic_parse(&options, "Enable")) {
3743 drvr_opts->tagq_ok = 0xFFFF;
3744 drvr_opts->tagq_ok_mask = 0xFFFF;
3745 } else if (blogic_parse(&options, "Disable")) {
3746 drvr_opts->tagq_ok = 0x0000;
3747 drvr_opts->tagq_ok_mask = 0xFFFF;
3748 } else {
3749 unsigned short tgt_bit;
3750 for (tgt_id = 0, tgt_bit = 1;
3751 tgt_id < BLOGIC_MAXDEV;
3752 tgt_id++, tgt_bit <<= 1)
3753 switch (*options++) {
3754 case 'Y':
3755 drvr_opts->tagq_ok |= tgt_bit;
3756 drvr_opts->tagq_ok_mask |= tgt_bit;
3757 break;
3758 case 'N':
3759 drvr_opts->tagq_ok &= ~tgt_bit;
3760 drvr_opts->tagq_ok_mask |= tgt_bit;
3761 break;
3762 case 'X':
3763 break;
3764 default:
3765 options--;
3766 tgt_id = BLOGIC_MAXDEV;
3767 break;
3768 }
3769 }
3770 }
3771
3772 else if (blogic_parse(&options, "BusSettleTime:") ||
3773 blogic_parse(&options, "BST:")) {
3774 unsigned short bus_settle_time =
3775 simple_strtoul(options, &options, 0);
3776 if (bus_settle_time > 5 * 60) {
3777 blogic_err("BusLogic: Invalid Driver Options " "(invalid Bus Settle Time %d)\n", NULL, bus_settle_time);
3778 return 0;
3779 }
3780 drvr_opts->bus_settle_time = bus_settle_time;
3781 } else if (blogic_parse(&options,
3782 "InhibitTargetInquiry"))
3783 drvr_opts->stop_tgt_inquiry = true;
3784
3785 else if (blogic_parse(&options, "TraceProbe"))
3786 blogic_global_options.trace_probe = true;
3787 else if (blogic_parse(&options, "TraceHardwareReset"))
3788 blogic_global_options.trace_hw_reset = true;
3789 else if (blogic_parse(&options, "TraceConfiguration"))
3790 blogic_global_options.trace_config = true;
3791 else if (blogic_parse(&options, "TraceErrors"))
3792 blogic_global_options.trace_err = true;
3793 else if (blogic_parse(&options, "Debug")) {
3794 blogic_global_options.trace_probe = true;
3795 blogic_global_options.trace_hw_reset = true;
3796 blogic_global_options.trace_config = true;
3797 blogic_global_options.trace_err = true;
3798 }
3799 if (*options == ',')
3800 options++;
3801 else if (*options != ';' && *options != '\0') {
3802 blogic_err("BusLogic: Unexpected Driver Option '%s' " "ignored\n", NULL, options);
3803 *options = '\0';
3804 }
3805 }
3806 if (!(blogic_drvr_options_count == 0 ||
3807 blogic_probeinfo_count == 0 ||
3808 blogic_drvr_options_count == blogic_probeinfo_count)) {
3809 blogic_err("BusLogic: Invalid Driver Options " "(all or no I/O Addresses must be specified)\n", NULL);
3810 return 0;
3811 }
3812
3813
3814
3815
3816 for (tgt_id = 0; tgt_id < BLOGIC_MAXDEV; tgt_id++)
3817 if (drvr_opts->qdepth[tgt_id] == 1) {
3818 unsigned short tgt_bit = 1 << tgt_id;
3819 drvr_opts->tagq_ok &= ~tgt_bit;
3820 drvr_opts->tagq_ok_mask |= tgt_bit;
3821 }
3822 if (*options == ';')
3823 options++;
3824 if (*options == '\0')
3825 return 0;
3826 }
3827 return 1;
3828}
3829
3830
3831
3832
3833
3834static struct scsi_host_template blogic_template = {
3835 .module = THIS_MODULE,
3836 .proc_name = "BusLogic",
3837 .write_info = blogic_write_info,
3838 .show_info = blogic_show_info,
3839 .name = "BusLogic",
3840 .info = blogic_drvr_info,
3841 .queuecommand = blogic_qcmd,
3842 .slave_configure = blogic_slaveconfig,
3843 .bios_param = blogic_diskparam,
3844 .eh_host_reset_handler = blogic_hostreset,
3845#if 0
3846 .eh_abort_handler = blogic_abort,
3847#endif
3848 .unchecked_isa_dma = 1,
3849 .max_sectors = 128,
3850 .use_clustering = ENABLE_CLUSTERING,
3851};
3852
3853
3854
3855
3856
3857static int __init blogic_setup(char *str)
3858{
3859 int ints[3];
3860
3861 (void) get_options(str, ARRAY_SIZE(ints), ints);
3862
3863 if (ints[0] != 0) {
3864 blogic_err("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL);
3865 return 0;
3866 }
3867 if (str == NULL || *str == '\0')
3868 return 0;
3869 return blogic_parseopts(str);
3870}
3871
3872
3873
3874
3875
3876static void __exit blogic_exit(void)
3877{
3878 struct blogic_adapter *ha, *next;
3879
3880 list_for_each_entry_safe(ha, next, &blogic_host_list, host_list)
3881 blogic_deladapter(ha);
3882}
3883
3884__setup("BusLogic=", blogic_setup);
3885
3886#ifdef MODULE
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896static const struct pci_device_id blogic_pci_tbl[] = {
3897 {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER)},
3898 {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC)},
3899 {PCI_DEVICE(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT)},
3900 {0, },
3901};
3902#endif
3903MODULE_DEVICE_TABLE(pci, blogic_pci_tbl);
3904
3905module_init(blogic_init);
3906module_exit(blogic_exit);
3907