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