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