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