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