1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88#define SCSI_NCR_DRIVER_NAME "sym53c8xx-1.7.3c-20010512"
89
90#define SCSI_NCR_DEBUG_FLAGS (0)
91
92#define NAME53C "sym53c"
93#define NAME53C8XX "sym53c8xx"
94
95
96
97
98
99
100
101
102#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
103
104#include <linux/module.h>
105
106#include <asm/dma.h>
107#include <asm/io.h>
108#include <asm/system.h>
109#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
110#include <linux/spinlock.h>
111#elif LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
112#include <asm/spinlock.h>
113#endif
114#include <linux/delay.h>
115#include <linux/signal.h>
116#include <linux/sched.h>
117#include <linux/errno.h>
118#include <linux/pci.h>
119#include <linux/string.h>
120#include <linux/mm.h>
121#include <linux/ioport.h>
122#include <linux/time.h>
123#include <linux/timer.h>
124#include <linux/stat.h>
125
126#include <linux/version.h>
127#include <linux/blk.h>
128
129#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,35)
130#include <linux/init.h>
131#endif
132
133#ifndef __init
134#define __init
135#endif
136#ifndef __initdata
137#define __initdata
138#endif
139
140#if LINUX_VERSION_CODE <= LinuxVersionCode(2,1,92)
141#include <linux/bios32.h>
142#endif
143
144#include "scsi.h"
145#include "hosts.h"
146
147#include <linux/types.h>
148
149
150
151
152#ifndef BITS_PER_LONG
153#if (~0UL) == 0xffffffffUL
154#define BITS_PER_LONG 32
155#else
156#define BITS_PER_LONG 64
157#endif
158#endif
159
160
161
162
163
164typedef u32 u_int32;
165typedef u64 u_int64;
166
167#include "sym53c8xx.h"
168
169
170
171
172
173
174#if 0
175#define SCSI_NCR_INTEGRITY_CHECKING
176#endif
177
178#define MIN(a,b) (((a) < (b)) ? (a) : (b))
179#define MAX(a,b) (((a) > (b)) ? (a) : (b))
180
181
182
183
184
185
186#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,47)
187#define SCSI_NCR_DYNAMIC_DMA_MAPPING
188#endif
189
190
191
192
193
194
195
196
197
198typedef struct xpt_quehead {
199 struct xpt_quehead *flink;
200 struct xpt_quehead *blink;
201} XPT_QUEHEAD;
202
203#define xpt_que_init(ptr) do { \
204 (ptr)->flink = (ptr); (ptr)->blink = (ptr); \
205} while (0)
206
207static inline void __xpt_que_add(struct xpt_quehead * new,
208 struct xpt_quehead * blink,
209 struct xpt_quehead * flink)
210{
211 flink->blink = new;
212 new->flink = flink;
213 new->blink = blink;
214 blink->flink = new;
215}
216
217static inline void __xpt_que_del(struct xpt_quehead * blink,
218 struct xpt_quehead * flink)
219{
220 flink->blink = blink;
221 blink->flink = flink;
222}
223
224static inline int xpt_que_empty(struct xpt_quehead *head)
225{
226 return head->flink == head;
227}
228
229static inline void xpt_que_splice(struct xpt_quehead *list,
230 struct xpt_quehead *head)
231{
232 struct xpt_quehead *first = list->flink;
233
234 if (first != list) {
235 struct xpt_quehead *last = list->blink;
236 struct xpt_quehead *at = head->flink;
237
238 first->blink = head;
239 head->flink = first;
240
241 last->flink = at;
242 at->blink = last;
243 }
244}
245
246#define xpt_que_entry(ptr, type, member) \
247 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
248
249
250#define xpt_insque(new, pos) __xpt_que_add(new, pos, (pos)->flink)
251
252#define xpt_remque(el) __xpt_que_del((el)->blink, (el)->flink)
253
254#define xpt_insque_head(new, head) __xpt_que_add(new, head, (head)->flink)
255
256static inline struct xpt_quehead *xpt_remque_head(struct xpt_quehead *head)
257{
258 struct xpt_quehead *elem = head->flink;
259
260 if (elem != head)
261 __xpt_que_del(head, elem->flink);
262 else
263 elem = 0;
264 return elem;
265}
266
267#define xpt_insque_tail(new, head) __xpt_que_add(new, (head)->blink, head)
268
269static inline struct xpt_quehead *xpt_remque_tail(struct xpt_quehead *head)
270{
271 struct xpt_quehead *elem = head->blink;
272
273 if (elem != head)
274 __xpt_que_del(elem->blink, head);
275 else
276 elem = 0;
277 return elem;
278}
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293#ifndef SCSI_NCR_MYADDR
294#define SCSI_NCR_MYADDR (7)
295#endif
296
297
298
299
300
301
302#ifndef SCSI_NCR_MAX_TAGS
303#define SCSI_NCR_MAX_TAGS (8)
304#endif
305
306
307
308
309
310#if SCSI_NCR_MAX_TAGS > 255
311#define MAX_TAGS 255
312#else
313#define MAX_TAGS SCSI_NCR_MAX_TAGS
314#endif
315
316
317
318
319
320
321#if MAX_TAGS > (512/4)
322#define MAX_TASKS (1024/4)
323#elif MAX_TAGS > (256/4)
324#define MAX_TASKS (512/4)
325#else
326#define MAX_TASKS (256/4)
327#endif
328
329
330
331
332#define NO_TAG (256)
333
334
335
336
337
338
339
340
341#ifdef SCSI_NCR_MAX_TARGET
342#define MAX_TARGET (SCSI_NCR_MAX_TARGET)
343#else
344#define MAX_TARGET (16)
345#endif
346
347
348
349
350
351
352
353
354#ifdef SCSI_NCR_MAX_LUN
355#define MAX_LUN 64
356#else
357#define MAX_LUN (1)
358#endif
359
360
361
362
363
364
365#ifndef SCSI_NCR_MIN_ASYNC
366#define SCSI_NCR_MIN_ASYNC (40)
367#endif
368
369
370
371
372
373
374
375#ifdef SCSI_NCR_CAN_QUEUE
376#define MAX_START (SCSI_NCR_CAN_QUEUE + 4)
377#else
378#define MAX_START (MAX_TARGET + 7 * MAX_TAGS)
379#endif
380
381
382
383
384
385
386
387
388#if MAX_START > PAGE_SIZE/8
389#undef MAX_START
390#define MAX_START (PAGE_SIZE/8)
391#endif
392
393
394
395
396
397
398#define MAX_SCATTER (SCSI_NCR_MAX_SCATTER)
399#define SCR_SG_SIZE (2)
400
401
402
403
404
405#define NCR_SNOOP_TIMEOUT (1000000)
406
407
408
409
410
411
412
413
414#define u_char unsigned char
415#define u_short unsigned short
416#define u_int unsigned int
417#define u_long unsigned long
418
419#ifndef bcopy
420#define bcopy(s, d, n) memcpy((d), (s), (n))
421#endif
422
423#ifndef bzero
424#define bzero(d, n) memset((d), 0, (n))
425#endif
426
427#ifndef offsetof
428#define offsetof(t, m) ((size_t) (&((t *)0)->m))
429#endif
430
431
432
433
434
435
436
437
438
439
440
441
442#if LINUX_VERSION_CODE >= LinuxVersionCode(2,2,0)
443
444typedef struct pci_dev *pcidev_t;
445#define PCIDEV_NULL (0)
446#define PciBusNumber(d) (d)->bus->number
447#define PciDeviceFn(d) (d)->devfn
448#define PciVendorId(d) (d)->vendor
449#define PciDeviceId(d) (d)->device
450#define PciIrqLine(d) (d)->irq
451
452static u_long __init
453pci_get_base_cookie(struct pci_dev *pdev, int index)
454{
455 u_long base;
456
457#if LINUX_VERSION_CODE > LinuxVersionCode(2,3,12)
458 base = pdev->resource[index].start;
459#else
460 base = pdev->base_address[index];
461#if BITS_PER_LONG > 32
462 if ((base & 0x7) == 0x4)
463 *base |= (((u_long)pdev->base_address[++index]) << 32);
464#endif
465#endif
466 return (base & ~0x7ul);
467}
468
469static int __init
470pci_get_base_address(struct pci_dev *pdev, int index, u_long *base)
471{
472 u32 tmp;
473#define PCI_BAR_OFFSET(index) (PCI_BASE_ADDRESS_0 + (index<<2))
474
475 pci_read_config_dword(pdev, PCI_BAR_OFFSET(index), &tmp);
476 *base = tmp;
477 ++index;
478 if ((tmp & 0x7) == 0x4) {
479#if BITS_PER_LONG > 32
480 pci_read_config_dword(pdev, PCI_BAR_OFFSET(index), &tmp);
481 *base |= (((u_long)tmp) << 32);
482#endif
483 ++index;
484 }
485 return index;
486#undef PCI_BAR_OFFSET
487}
488
489#else
490
491typedef unsigned int pcidev_t;
492#define PCIDEV_NULL (~0u)
493#define PciBusNumber(d) ((d)>>8)
494#define PciDeviceFn(d) ((d)&0xff)
495#define __PciDev(busn, devfn) (((busn)<<8)+(devfn))
496
497#define pci_present pcibios_present
498
499#define pci_read_config_byte(d, w, v) \
500 pcibios_read_config_byte(PciBusNumber(d), PciDeviceFn(d), w, v)
501#define pci_read_config_word(d, w, v) \
502 pcibios_read_config_word(PciBusNumber(d), PciDeviceFn(d), w, v)
503#define pci_read_config_dword(d, w, v) \
504 pcibios_read_config_dword(PciBusNumber(d), PciDeviceFn(d), w, v)
505
506#define pci_write_config_byte(d, w, v) \
507 pcibios_write_config_byte(PciBusNumber(d), PciDeviceFn(d), w, v)
508#define pci_write_config_word(d, w, v) \
509 pcibios_write_config_word(PciBusNumber(d), PciDeviceFn(d), w, v)
510#define pci_write_config_dword(d, w, v) \
511 pcibios_write_config_dword(PciBusNumber(d), PciDeviceFn(d), w, v)
512
513static pcidev_t __init
514pci_find_device(unsigned int vendor, unsigned int device, pcidev_t prev)
515{
516 static unsigned short pci_index;
517 int retv;
518 unsigned char bus_number, device_fn;
519
520 if (prev == PCIDEV_NULL)
521 pci_index = 0;
522 else
523 ++pci_index;
524 retv = pcibios_find_device (vendor, device, pci_index,
525 &bus_number, &device_fn);
526 return retv ? PCIDEV_NULL : __PciDev(bus_number, device_fn);
527}
528
529static u_short __init PciVendorId(pcidev_t dev)
530{
531 u_short vendor_id;
532 pci_read_config_word(dev, PCI_VENDOR_ID, &vendor_id);
533 return vendor_id;
534}
535
536static u_short __init PciDeviceId(pcidev_t dev)
537{
538 u_short device_id;
539 pci_read_config_word(dev, PCI_DEVICE_ID, &device_id);
540 return device_id;
541}
542
543static u_int __init PciIrqLine(pcidev_t dev)
544{
545 u_char irq;
546 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
547 return irq;
548}
549
550static int __init
551pci_get_base_address(pcidev_t dev, int offset, u_long *base)
552{
553 u_int32 tmp;
554
555 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + offset, &tmp);
556 *base = tmp;
557 offset += sizeof(u_int32);
558 if ((tmp & 0x7) == 0x4) {
559#if BITS_PER_LONG > 32
560 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + offset, &tmp);
561 *base |= (((u_long)tmp) << 32);
562#endif
563 offset += sizeof(u_int32);
564 }
565 return offset;
566}
567static u_long __init
568pci_get_base_cookie(struct pci_dev *pdev, int offset)
569{
570 u_long base;
571
572 (void) pci_get_base_address(dev, offset, &base);
573
574 return base;
575}
576
577#endif
578
579
580#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
581#define pci_enable_device(pdev) (0)
582#endif
583#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,4)
584#define scsi_set_pci_device(inst, pdev) (0)
585#endif
586
587
588
589
590
591
592
593
594#define DEBUG_ALLOC (0x0001)
595#define DEBUG_PHASE (0x0002)
596#define DEBUG_QUEUE (0x0008)
597#define DEBUG_RESULT (0x0010)
598#define DEBUG_POINTER (0x0020)
599#define DEBUG_SCRIPT (0x0040)
600#define DEBUG_TINY (0x0080)
601#define DEBUG_TIMING (0x0100)
602#define DEBUG_NEGO (0x0200)
603#define DEBUG_TAGS (0x0400)
604#define DEBUG_IC (0x0800)
605
606
607
608
609
610
611#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
612static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
613 #define DEBUG_FLAGS ncr_debug
614#else
615 #define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS
616#endif
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
634
635spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
636#define NCR_LOCK_DRIVER(flags) spin_lock_irqsave(&sym53c8xx_lock, flags)
637#define NCR_UNLOCK_DRIVER(flags) spin_unlock_irqrestore(&sym53c8xx_lock,flags)
638
639#define NCR_INIT_LOCK_NCB(np) spin_lock_init(&np->smp_lock);
640#define NCR_LOCK_NCB(np, flags) spin_lock_irqsave(&np->smp_lock, flags)
641#define NCR_UNLOCK_NCB(np, flags) spin_unlock_irqrestore(&np->smp_lock, flags)
642
643#define NCR_LOCK_SCSI_DONE(host, flags) \
644 spin_lock_irqsave(((host)->host_lock), flags)
645#define NCR_UNLOCK_SCSI_DONE(host, flags) \
646 spin_unlock_irqrestore(((host)->host_lock), flags)
647
648#else
649
650#define NCR_LOCK_DRIVER(flags) do { save_flags(flags); cli(); } while (0)
651#define NCR_UNLOCK_DRIVER(flags) do { restore_flags(flags); } while (0)
652
653#define NCR_INIT_LOCK_NCB(np) do { } while (0)
654#define NCR_LOCK_NCB(np, flags) do { save_flags(flags); cli(); } while (0)
655#define NCR_UNLOCK_NCB(np, flags) do { restore_flags(flags); } while (0)
656
657#define NCR_LOCK_SCSI_DONE(host, flags) do {;} while (0)
658#define NCR_UNLOCK_SCSI_DONE(host, flags) do {;} while (0)
659
660#endif
661
662
663
664
665
666
667
668
669
670
671
672
673#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,0)
674#define ioremap vremap
675#define iounmap vfree
676#endif
677
678#ifdef __sparc__
679# include <asm/irq.h>
680# define memcpy_to_pci(a, b, c) memcpy_toio((a), (b), (c))
681#elif defined(__alpha__)
682# define memcpy_to_pci(a, b, c) memcpy_toio((a), (b), (c))
683#else
684# define memcpy_to_pci(a, b, c) memcpy_toio((a), (b), (c))
685#endif
686
687#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
688static u_long __init remap_pci_mem(u_long base, u_long size)
689{
690 u_long page_base = ((u_long) base) & PAGE_MASK;
691 u_long page_offs = ((u_long) base) - page_base;
692 u_long page_remapped = (u_long) ioremap(page_base, page_offs+size);
693
694 return page_remapped? (page_remapped + page_offs) : 0UL;
695}
696
697static void __init unmap_pci_mem(u_long vaddr, u_long size)
698{
699 if (vaddr)
700 iounmap((void *) (vaddr & PAGE_MASK));
701}
702
703#endif
704
705
706
707
708
709
710
711
712
713
714
715
716#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,105)
717#define UDELAY udelay
718#define MDELAY mdelay
719#else
720static void UDELAY(long us) { udelay(us); }
721static void MDELAY(long ms) { while (ms--) UDELAY(1000); }
722#endif
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0)
739#define __GetFreePages(flags, order) __get_free_pages(flags, order)
740#else
741#define __GetFreePages(flags, order) __get_free_pages(flags, order, 0)
742#endif
743
744#define MEMO_SHIFT 4
745#if PAGE_SIZE >= 8192
746#define MEMO_PAGE_ORDER 0
747#else
748#define MEMO_PAGE_ORDER 1
749#endif
750#define MEMO_FREE_UNUSED
751#define MEMO_WARN 1
752#define MEMO_GFP_FLAGS GFP_ATOMIC
753#define MEMO_CLUSTER_SHIFT (PAGE_SHIFT+MEMO_PAGE_ORDER)
754#define MEMO_CLUSTER_SIZE (1UL << MEMO_CLUSTER_SHIFT)
755#define MEMO_CLUSTER_MASK (MEMO_CLUSTER_SIZE-1)
756
757typedef u_long m_addr_t;
758typedef pcidev_t m_bush_t;
759
760typedef struct m_link {
761 struct m_link *next;
762} m_link_s;
763
764#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
765typedef struct m_vtob {
766 struct m_vtob *next;
767 m_addr_t vaddr;
768 m_addr_t baddr;
769} m_vtob_s;
770#define VTOB_HASH_SHIFT 5
771#define VTOB_HASH_SIZE (1UL << VTOB_HASH_SHIFT)
772#define VTOB_HASH_MASK (VTOB_HASH_SIZE-1)
773#define VTOB_HASH_CODE(m) \
774 ((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
775#endif
776
777typedef struct m_pool {
778#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
779 m_bush_t bush;
780 m_addr_t (*getp)(struct m_pool *);
781 void (*freep)(struct m_pool *, m_addr_t);
782#define M_GETP() mp->getp(mp)
783#define M_FREEP(p) mp->freep(mp, p)
784#define GetPages() __GetFreePages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER)
785#define FreePages(p) free_pages(p, MEMO_PAGE_ORDER)
786 int nump;
787 m_vtob_s *(vtob[VTOB_HASH_SIZE]);
788 struct m_pool *next;
789#else
790#define M_GETP() __GetFreePages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER)
791#define M_FREEP(p) free_pages(p, MEMO_PAGE_ORDER)
792#endif
793 struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
794} m_pool_s;
795
796static void *___m_alloc(m_pool_s *mp, int size)
797{
798 int i = 0;
799 int s = (1 << MEMO_SHIFT);
800 int j;
801 m_addr_t a;
802 m_link_s *h = mp->h;
803
804 if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
805 return 0;
806
807 while (size > s) {
808 s <<= 1;
809 ++i;
810 }
811
812 j = i;
813 while (!h[j].next) {
814 if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
815 h[j].next = (m_link_s *) M_GETP();
816 if (h[j].next)
817 h[j].next->next = 0;
818 break;
819 }
820 ++j;
821 s <<= 1;
822 }
823 a = (m_addr_t) h[j].next;
824 if (a) {
825 h[j].next = h[j].next->next;
826 while (j > i) {
827 j -= 1;
828 s >>= 1;
829 h[j].next = (m_link_s *) (a+s);
830 h[j].next->next = 0;
831 }
832 }
833#ifdef DEBUG
834 printk("___m_alloc(%d) = %p\n", size, (void *) a);
835#endif
836 return (void *) a;
837}
838
839static void ___m_free(m_pool_s *mp, void *ptr, int size)
840{
841 int i = 0;
842 int s = (1 << MEMO_SHIFT);
843 m_link_s *q;
844 m_addr_t a, b;
845 m_link_s *h = mp->h;
846
847#ifdef DEBUG
848 printk("___m_free(%p, %d)\n", ptr, size);
849#endif
850
851 if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
852 return;
853
854 while (size > s) {
855 s <<= 1;
856 ++i;
857 }
858
859 a = (m_addr_t) ptr;
860
861 while (1) {
862#ifdef MEMO_FREE_UNUSED
863 if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
864 M_FREEP(a);
865 break;
866 }
867#endif
868 b = a ^ s;
869 q = &h[i];
870 while (q->next && q->next != (m_link_s *) b) {
871 q = q->next;
872 }
873 if (!q->next) {
874 ((m_link_s *) a)->next = h[i].next;
875 h[i].next = (m_link_s *) a;
876 break;
877 }
878 q->next = q->next->next;
879 a = a & b;
880 s <<= 1;
881 ++i;
882 }
883}
884
885static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
886{
887 void *p;
888
889 p = ___m_alloc(mp, size);
890
891 if (DEBUG_FLAGS & DEBUG_ALLOC)
892 printk ("new %-10s[%4d] @%p.\n", name, size, p);
893
894 if (p)
895 bzero(p, size);
896 else if (uflags & MEMO_WARN)
897 printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
898
899 return p;
900}
901
902#define __m_calloc(mp, s, n) __m_calloc2(mp, s, n, MEMO_WARN)
903
904static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
905{
906 if (DEBUG_FLAGS & DEBUG_ALLOC)
907 printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
908
909 ___m_free(mp, ptr, size);
910
911}
912
913
914
915
916
917
918
919#ifndef SCSI_NCR_DYNAMIC_DMA_MAPPING
920
921static m_pool_s mp0;
922
923#else
924
925static m_addr_t ___mp0_getp(m_pool_s *mp)
926{
927 m_addr_t m = GetPages();
928 if (m)
929 ++mp->nump;
930 return m;
931}
932
933static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
934{
935 FreePages(m);
936 --mp->nump;
937}
938
939static m_pool_s mp0 = {0, ___mp0_getp, ___mp0_freep};
940
941#endif
942
943static void *m_calloc(int size, char *name)
944{
945 u_long flags;
946 void *m;
947 NCR_LOCK_DRIVER(flags);
948 m = __m_calloc(&mp0, size, name);
949 NCR_UNLOCK_DRIVER(flags);
950 return m;
951}
952
953static void m_free(void *ptr, int size, char *name)
954{
955 u_long flags;
956 NCR_LOCK_DRIVER(flags);
957 __m_free(&mp0, ptr, size, name);
958 NCR_UNLOCK_DRIVER(flags);
959}
960
961
962
963
964
965#ifndef SCSI_NCR_DYNAMIC_DMA_MAPPING
966
967
968
969#define __m_calloc_dma(b, s, n) m_calloc(s, n)
970#define __m_free_dma(b, p, s, n) m_free(p, s, n)
971#define __vtobus(b, p) virt_to_bus(p)
972
973#else
974
975
976
977
978
979static m_addr_t ___dma_getp(m_pool_s *mp)
980{
981 m_addr_t vp;
982 m_vtob_s *vbp;
983
984 vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
985 if (vbp) {
986 dma_addr_t daddr;
987 vp = (m_addr_t) pci_alloc_consistent(mp->bush,
988 PAGE_SIZE<<MEMO_PAGE_ORDER,
989 &daddr);
990 if (vp) {
991 int hc = VTOB_HASH_CODE(vp);
992 vbp->vaddr = vp;
993 vbp->baddr = daddr;
994 vbp->next = mp->vtob[hc];
995 mp->vtob[hc] = vbp;
996 ++mp->nump;
997 return vp;
998 }
999 else
1000 __m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
1001 }
1002 return 0;
1003}
1004
1005static void ___dma_freep(m_pool_s *mp, m_addr_t m)
1006{
1007 m_vtob_s **vbpp, *vbp;
1008 int hc = VTOB_HASH_CODE(m);
1009
1010 vbpp = &mp->vtob[hc];
1011 while (*vbpp && (*vbpp)->vaddr != m)
1012 vbpp = &(*vbpp)->next;
1013 if (*vbpp) {
1014 vbp = *vbpp;
1015 *vbpp = (*vbpp)->next;
1016 pci_free_consistent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
1017 (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
1018 __m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
1019 --mp->nump;
1020 }
1021}
1022
1023static inline m_pool_s *___get_dma_pool(m_bush_t bush)
1024{
1025 m_pool_s *mp;
1026 for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
1027 return mp;
1028}
1029
1030static m_pool_s *___cre_dma_pool(m_bush_t bush)
1031{
1032 m_pool_s *mp;
1033 mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
1034 if (mp) {
1035 bzero(mp, sizeof(*mp));
1036 mp->bush = bush;
1037 mp->getp = ___dma_getp;
1038 mp->freep = ___dma_freep;
1039 mp->next = mp0.next;
1040 mp0.next = mp;
1041 }
1042 return mp;
1043}
1044
1045static void ___del_dma_pool(m_pool_s *p)
1046{
1047 struct m_pool **pp = &mp0.next;
1048
1049 while (*pp && *pp != p)
1050 pp = &(*pp)->next;
1051 if (*pp) {
1052 *pp = (*pp)->next;
1053 __m_free(&mp0, p, sizeof(*p), "MPOOL");
1054 }
1055}
1056
1057static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
1058{
1059 u_long flags;
1060 struct m_pool *mp;
1061 void *m = 0;
1062
1063 NCR_LOCK_DRIVER(flags);
1064 mp = ___get_dma_pool(bush);
1065 if (!mp)
1066 mp = ___cre_dma_pool(bush);
1067 if (mp)
1068 m = __m_calloc(mp, size, name);
1069 if (mp && !mp->nump)
1070 ___del_dma_pool(mp);
1071 NCR_UNLOCK_DRIVER(flags);
1072
1073 return m;
1074}
1075
1076static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
1077{
1078 u_long flags;
1079 struct m_pool *mp;
1080
1081 NCR_LOCK_DRIVER(flags);
1082 mp = ___get_dma_pool(bush);
1083 if (mp)
1084 __m_free(mp, m, size, name);
1085 if (mp && !mp->nump)
1086 ___del_dma_pool(mp);
1087 NCR_UNLOCK_DRIVER(flags);
1088}
1089
1090static m_addr_t __vtobus(m_bush_t bush, void *m)
1091{
1092 u_long flags;
1093 m_pool_s *mp;
1094 int hc = VTOB_HASH_CODE(m);
1095 m_vtob_s *vp = 0;
1096 m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
1097
1098 NCR_LOCK_DRIVER(flags);
1099 mp = ___get_dma_pool(bush);
1100 if (mp) {
1101 vp = mp->vtob[hc];
1102 while (vp && (m_addr_t) vp->vaddr != a)
1103 vp = vp->next;
1104 }
1105 NCR_UNLOCK_DRIVER(flags);
1106 return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
1107}
1108
1109#endif
1110
1111#define _m_calloc_dma(np, s, n) __m_calloc_dma(np->pdev, s, n)
1112#define _m_free_dma(np, p, s, n) __m_free_dma(np->pdev, p, s, n)
1113#define m_calloc_dma(s, n) _m_calloc_dma(np, s, n)
1114#define m_free_dma(p, s, n) _m_free_dma(np, p, s, n)
1115#define _vtobus(np, p) __vtobus(np->pdev, p)
1116#define vtobus(p) _vtobus(np, p)
1117
1118
1119
1120
1121
1122#ifndef SCSI_NCR_DYNAMIC_DMA_MAPPING
1123
1124
1125
1126#define __unmap_scsi_data(pdev, cmd) do {; } while (0)
1127#define __map_scsi_single_data(pdev, cmd) (__vtobus(pdev,(cmd)->request_buffer))
1128#define __map_scsi_sg_data(pdev, cmd) ((cmd)->use_sg)
1129#define __sync_scsi_data(pdev, cmd) do {; } while (0)
1130
1131#define scsi_sg_dma_address(sc) vtobus((sc)->address)
1132#define scsi_sg_dma_len(sc) ((sc)->length)
1133
1134#else
1135
1136
1137
1138
1139#define __data_mapped(cmd) (cmd)->SCp.phase
1140#define __data_mapping(cmd) (cmd)->SCp.dma_handle
1141
1142static void __unmap_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
1143{
1144 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
1145
1146 switch(__data_mapped(cmd)) {
1147 case 2:
1148 pci_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
1149 break;
1150 case 1:
1151 pci_unmap_page(pdev, __data_mapping(cmd),
1152 cmd->request_bufflen, dma_dir);
1153 break;
1154 }
1155 __data_mapped(cmd) = 0;
1156}
1157
1158static dma_addr_t __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd)
1159{
1160 dma_addr_t mapping;
1161 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
1162
1163 if (cmd->request_bufflen == 0)
1164 return 0;
1165
1166 mapping = pci_map_page(pdev,
1167 virt_to_page(cmd->request_buffer),
1168 ((unsigned long)cmd->request_buffer &
1169 ~PAGE_MASK),
1170 cmd->request_bufflen, dma_dir);
1171 __data_mapped(cmd) = 1;
1172 __data_mapping(cmd) = mapping;
1173
1174 return mapping;
1175}
1176
1177static int __map_scsi_sg_data(pcidev_t pdev, Scsi_Cmnd *cmd)
1178{
1179 int use_sg;
1180 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
1181
1182 if (cmd->use_sg == 0)
1183 return 0;
1184
1185 use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
1186 __data_mapped(cmd) = 2;
1187 __data_mapping(cmd) = use_sg;
1188
1189 return use_sg;
1190}
1191
1192static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd)
1193{
1194 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
1195
1196 switch(__data_mapped(cmd)) {
1197 case 2:
1198 pci_dma_sync_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
1199 break;
1200 case 1:
1201 pci_dma_sync_single(pdev, __data_mapping(cmd),
1202 cmd->request_bufflen, dma_dir);
1203 break;
1204 }
1205}
1206
1207#define scsi_sg_dma_address(sc) sg_dma_address(sc)
1208#define scsi_sg_dma_len(sc) sg_dma_len(sc)
1209
1210#endif
1211
1212#define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->pdev, cmd)
1213#define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->pdev, cmd)
1214#define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->pdev, cmd)
1215#define sync_scsi_data(np, cmd) __sync_scsi_data(np->pdev, cmd)
1216
1217
1218
1219
1220
1221static void ncr_print_hex(u_char *p, int n)
1222{
1223 while (n-- > 0)
1224 printk (" %x", *p++);
1225}
1226
1227static void ncr_printl_hex(char *label, u_char *p, int n)
1228{
1229 printk("%s", label);
1230 ncr_print_hex(p, n);
1231 printk (".\n");
1232}
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245#ifdef SCSI_DATA_UNKNOWN
1246
1247#define scsi_data_direction(cmd) (cmd->sc_data_direction)
1248
1249#else
1250
1251#define SCSI_DATA_UNKNOWN 0
1252#define SCSI_DATA_WRITE 1
1253#define SCSI_DATA_READ 2
1254#define SCSI_DATA_NONE 3
1255
1256static __inline__ int scsi_data_direction(Scsi_Cmnd *cmd)
1257{
1258 int direction;
1259
1260 switch((int) cmd->cmnd[0]) {
1261 case 0x08:
1262 case 0x28:
1263 case 0xA8:
1264 direction = SCSI_DATA_READ;
1265 break;
1266 case 0x0A:
1267 case 0x2A:
1268 case 0xAA:
1269 direction = SCSI_DATA_WRITE;
1270 break;
1271 default:
1272 direction = SCSI_DATA_UNKNOWN;
1273 break;
1274 }
1275
1276 return direction;
1277}
1278
1279#endif
1280
1281
1282
1283
1284
1285#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
1286static struct proc_dir_entry proc_scsi_sym53c8xx = {
1287 PROC_SCSI_SYM53C8XX, 9, NAME53C8XX,
1288 S_IFDIR | S_IRUGO | S_IXUGO, 2
1289};
1290#endif
1291#ifdef SCSI_NCR_PROC_INFO_SUPPORT
1292static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset,
1293 int length, int hostno, int func);
1294#endif
1295
1296
1297
1298
1299
1300
1301
1302static struct ncr_driver_setup
1303 driver_setup = SCSI_NCR_DRIVER_SETUP;
1304
1305#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
1306static struct ncr_driver_setup
1307 driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP;
1308# ifdef MODULE
1309char *sym53c8xx = 0;
1310# if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30)
1311MODULE_PARM(sym53c8xx, "s");
1312# endif
1313# endif
1314#endif
1315
1316
1317
1318
1319#define SetScsiResult(cmd, h_sts, s_sts) \
1320 cmd->result = (((h_sts) << 16) + ((s_sts) & 0x7f))
1321
1322
1323#if 0
1324#define SetScsiAbortResult(cmd) \
1325 SetScsiResult( \
1326 cmd, \
1327 (cmd)->abort_reason == DID_TIME_OUT ? DID_TIME_OUT : DID_ABORT, \
1328 0xff)
1329#else
1330#define SetScsiAbortResult(cmd) SetScsiResult(cmd, DID_ABORT, 0xff)
1331#endif
1332
1333static void sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
1334static void sym53c8xx_timeout(unsigned long np);
1335
1336#define initverbose (driver_setup.verbose)
1337#define bootverbose (np->verbose)
1338
1339#ifdef SCSI_NCR_NVRAM_SUPPORT
1340static u_char Tekram_sync[16] __initdata =
1341 {25,31,37,43, 50,62,75,125, 12,15,18,21, 6,7,9,10};
1342#endif
1343
1344
1345
1346
1347
1348typedef struct {
1349 int bus;
1350 u_char device_fn;
1351 u_long base;
1352 u_long base_2;
1353 u_long io_port;
1354 u_long base_c;
1355 u_long base_2_c;
1356 int irq;
1357
1358 u_long base_io;
1359 volatile struct ncr_reg *reg;
1360} ncr_slot;
1361
1362typedef struct {
1363 int type;
1364#define SCSI_NCR_SYMBIOS_NVRAM (1)
1365#define SCSI_NCR_TEKRAM_NVRAM (2)
1366#ifdef SCSI_NCR_NVRAM_SUPPORT
1367 union {
1368 Symbios_nvram Symbios;
1369 Tekram_nvram Tekram;
1370 } data;
1371#endif
1372} ncr_nvram;
1373
1374
1375
1376
1377
1378typedef struct {
1379 pcidev_t pdev;
1380 ncr_slot slot;
1381 ncr_chip chip;
1382 ncr_nvram *nvram;
1383 u_char host_id;
1384#ifdef SCSI_NCR_PQS_PDS_SUPPORT
1385 u_char pqs_pds;
1386#endif
1387 int attach_done;
1388} ncr_device;
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401#define assert(expression) { \
1402 if (!(expression)) { \
1403 (void)panic( \
1404 "assertion \"%s\" failed: file \"%s\", line %d\n", \
1405 #expression, \
1406 __FILE__, __LINE__); \
1407 } \
1408}
1409
1410
1411
1412
1413
1414
1415
1416
1417#define HS_IDLE (0)
1418#define HS_BUSY (1)
1419#define HS_NEGOTIATE (2)
1420#define HS_DISCONNECT (3)
1421
1422#define HS_DONEMASK (0x80)
1423#define HS_COMPLETE (4|HS_DONEMASK)
1424#define HS_SEL_TIMEOUT (5|HS_DONEMASK)
1425#define HS_RESET (6|HS_DONEMASK)
1426#define HS_ABORTED (7|HS_DONEMASK)
1427#define HS_TIMEOUT (8|HS_DONEMASK)
1428#define HS_FAIL (9|HS_DONEMASK)
1429#define HS_UNEXPECTED (10|HS_DONEMASK)
1430
1431#define DSA_INVALID 0xffffffff
1432
1433
1434
1435
1436
1437
1438
1439
1440#define SIR_BAD_STATUS (1)
1441#define SIR_SEL_ATN_NO_MSG_OUT (2)
1442#define SIR_MSG_RECEIVED (3)
1443#define SIR_MSG_WEIRD (4)
1444#define SIR_NEGO_FAILED (5)
1445#define SIR_NEGO_PROTO (6)
1446#define SIR_SCRIPT_STOPPED (7)
1447#define SIR_REJECT_TO_SEND (8)
1448#define SIR_SWIDE_OVERRUN (9)
1449#define SIR_SODL_UNDERRUN (10)
1450#define SIR_RESEL_NO_MSG_IN (11)
1451#define SIR_RESEL_NO_IDENTIFY (12)
1452#define SIR_RESEL_BAD_LUN (13)
1453#define SIR_TARGET_SELECTED (14)
1454#define SIR_RESEL_BAD_I_T_L (15)
1455#define SIR_RESEL_BAD_I_T_L_Q (16)
1456#define SIR_ABORT_SENT (17)
1457#define SIR_RESEL_ABORTED (18)
1458#define SIR_MSG_OUT_DONE (19)
1459#define SIR_AUTO_SENSE_DONE (20)
1460#define SIR_DUMMY_INTERRUPT (21)
1461#define SIR_DATA_OVERRUN (22)
1462#define SIR_BAD_PHASE (23)
1463#define SIR_MAX (23)
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473#define XE_EXTRA_DATA (1)
1474#define XE_BAD_PHASE (2)
1475#define XE_PARITY_ERR (4)
1476#define XE_SODL_UNRUN (1<<3)
1477#define XE_SWIDE_OVRUN (1<<4)
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487#define NS_NOCHANGE (0)
1488#define NS_SYNC (1)
1489#define NS_WIDE (2)
1490#define NS_PPR (4)
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501#define QUIRK_AUTOSAVE (0x01)
1502
1503
1504
1505
1506
1507
1508
1509
1510#define INQ7_QUEUE (0x02)
1511#define INQ7_SYNC (0x10)
1512#define INQ7_WIDE16 (0x20)
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522#define CCB_HASH_SHIFT 8
1523#define CCB_HASH_SIZE (1UL << CCB_HASH_SHIFT)
1524#define CCB_HASH_MASK (CCB_HASH_SIZE-1)
1525#define CCB_HASH_CODE(dsa) (((dsa) >> 11) & CCB_HASH_MASK)
1526
1527
1528
1529
1530
1531
1532
1533
1534struct tcb;
1535struct lcb;
1536struct ccb;
1537struct ncb;
1538struct script;
1539
1540typedef struct ncb * ncb_p;
1541typedef struct tcb * tcb_p;
1542typedef struct lcb * lcb_p;
1543typedef struct ccb * ccb_p;
1544
1545struct link {
1546 ncrcmd l_cmd;
1547 ncrcmd l_paddr;
1548};
1549
1550struct usrcmd {
1551 u_long target;
1552 u_long lun;
1553 u_long data;
1554 u_long cmd;
1555};
1556
1557#define UC_SETSYNC 10
1558#define UC_SETTAGS 11
1559#define UC_SETDEBUG 12
1560#define UC_SETORDER 13
1561#define UC_SETWIDE 14
1562#define UC_SETFLAG 15
1563#define UC_SETVERBOSE 17
1564#define UC_RESETDEV 18
1565#define UC_CLEARDEV 19
1566
1567#define UF_TRACE (0x01)
1568#define UF_NODISC (0x02)
1569#define UF_NOSCAN (0x04)
1570
1571
1572
1573
1574
1575
1576
1577struct tcb {
1578
1579
1580
1581
1582
1583
1584 u_int32 *luntbl;
1585 u_int32 b_luntbl;
1586 u_int32 b_lun0;
1587 lcb_p l0p;
1588#if MAX_LUN > 1
1589 lcb_p *lmp;
1590#endif
1591
1592
1593
1594
1595 u_char inq_done;
1596 u_char inq_byte7;
1597
1598
1599
1600
1601
1602 u_char to_reset;
1603
1604
1605
1606
1607
1608
1609
1610 ccb_p nego_cp;
1611
1612
1613
1614
1615
1616
1617
1618 u_char uval;
1619 u_char sval;
1620 u_char filler2;
1621 u_char wval;
1622 u_short period;
1623 u_char minsync;
1624 u_char maxoffs;
1625 u_char quirks;
1626 u_char widedone;
1627
1628#ifdef SCSI_NCR_INTEGRITY_CHECKING
1629 u_char ic_min_sync;
1630 u_char ic_max_width;
1631 u_char ic_done;
1632#endif
1633 u_char ic_maximums_set;
1634 u_char ppr_negotiation;
1635
1636
1637
1638
1639
1640
1641 u_char usrsync;
1642 u_char usrwide;
1643 u_short usrtags;
1644 u_char usrflag;
1645};
1646
1647
1648
1649
1650
1651
1652
1653struct lcb {
1654
1655
1656
1657
1658
1659
1660
1661
1662 u_int32 resel_task;
1663
1664
1665
1666
1667
1668
1669
1670
1671 u_int32 tasktbl_0;
1672 u_int32 *tasktbl;
1673 u_int32 b_tasktbl;
1674
1675
1676
1677
1678
1679 XPT_QUEHEAD busy_ccbq;
1680 XPT_QUEHEAD wait_ccbq;
1681 u_short busyccbs;
1682 u_short queuedccbs;
1683 u_short queuedepth;
1684 u_short scdev_depth;
1685 u_short maxnxs;
1686
1687
1688
1689
1690
1691
1692
1693 u_short ia_tag;
1694 u_short if_tag;
1695 u_char *cb_tags;
1696 u_char inq_byte7;
1697 u_char usetags;
1698 u_char to_clear;
1699 u_short maxtags;
1700 u_short numtags;
1701
1702
1703
1704
1705
1706 u_short num_good;
1707 u_short tags_sum[2];
1708 u_char tags_si;
1709 u_long tags_stime;
1710};
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723struct action {
1724 u_int32 start;
1725 u_int32 restart;
1726};
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740struct pm_ctx {
1741 struct scr_tblmove sg;
1742 u_int32 ret;
1743};
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760struct head {
1761
1762
1763
1764
1765 struct action go;
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775 u_int32 savep;
1776 u_int32 lastp;
1777 u_int32 goalp;
1778
1779
1780
1781
1782
1783
1784
1785 u_int32 wlastp;
1786 u_int32 wgoalp;
1787
1788
1789
1790
1791
1792 u_char status[4];
1793};
1794
1795
1796
1797
1798
1799
1800#if MAX_LUN <= 1
1801#define ncr_lp(np, tp, lun) (!lun) ? (tp)->l0p : 0
1802#else
1803#define ncr_lp(np, tp, lun) \
1804 (!lun) ? (tp)->l0p : (tp)->lmp ? (tp)->lmp[(lun)] : 0
1805#endif
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819#define QU_REG scr0
1820#define HS_REG scr1
1821#define HS_PRT nc_scr1
1822#define SS_REG scr2
1823#define SS_PRT nc_scr2
1824#define HF_REG scr3
1825#define HF_PRT nc_scr3
1826
1827
1828
1829
1830#define actualquirks phys.header.status[0]
1831#define host_status phys.header.status[1]
1832#define scsi_status phys.header.status[2]
1833#define host_flags phys.header.status[3]
1834
1835
1836
1837
1838#define HF_IN_PM0 1u
1839#define HF_IN_PM1 (1u<<1)
1840#define HF_ACT_PM (1u<<2)
1841#define HF_DP_SAVED (1u<<3)
1842#define HF_AUTO_SENSE (1u<<4)
1843#define HF_DATA_IN (1u<<5)
1844#define HF_PM_TO_C (1u<<6)
1845#define HF_EXT_ERR (1u<<7)
1846
1847#ifdef SCSI_NCR_IARB_SUPPORT
1848#define HF_HINT_IARB (1u<<7)
1849#endif
1850
1851
1852
1853
1854#define HF_DATA_ST (1u<<7)
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872struct dsb {
1873
1874
1875
1876
1877
1878 struct head header;
1879
1880
1881
1882
1883
1884 struct scr_tblsel select;
1885 struct scr_tblmove smsg ;
1886 struct scr_tblmove smsg_ext ;
1887 struct scr_tblmove cmd ;
1888 struct scr_tblmove sense ;
1889 struct scr_tblmove wresid;
1890 struct scr_tblmove data [MAX_SCATTER];
1891
1892
1893
1894
1895
1896
1897
1898 struct pm_ctx pm0;
1899 struct pm_ctx pm1;
1900};
1901
1902
1903
1904
1905
1906
1907
1908
1909struct ccb {
1910
1911
1912
1913
1914
1915
1916 struct dsb phys;
1917
1918
1919
1920
1921
1922
1923 Scsi_Cmnd *cmd;
1924 u_char cdb_buf[16];
1925 u_char sense_buf[64];
1926 int data_len;
1927 int segments;
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939 u_char scsi_smsg [12];
1940 u_char scsi_smsg2[12];
1941
1942
1943
1944
1945
1946 u_char nego_status;
1947 u_char xerr_status;
1948 u_int32 extra_bytes;
1949
1950
1951
1952
1953
1954 u_char sv_scsi_status;
1955 u_char sv_xerr_status;
1956
1957
1958
1959
1960
1961 u_long p_ccb;
1962 u_char sensecmd[6];
1963 u_char to_abort;
1964 u_short tag;
1965
1966 u_char tags_si;
1967
1968 u_char target;
1969 u_char lun;
1970 u_short queued;
1971 ccb_p link_ccb;
1972 ccb_p link_ccbh;
1973 XPT_QUEHEAD link_ccbq;
1974 u_int32 startp;
1975 u_int32 lastp0;
1976 int ext_sg;
1977 int ext_ofs;
1978 int resid;
1979};
1980
1981#define CCB_PHYS(cp,lbl) (cp->p_ccb + offsetof(struct ccb, lbl))
1982
1983
1984
1985
1986
1987
1988
1989
1990struct ncb {
1991
1992
1993
1994
1995
1996 struct action idletask;
1997 struct action notask;
1998 struct action bad_i_t_l;
1999 struct action bad_i_t_l_q;
2000 u_long p_idletask;
2001 u_long p_notask;
2002 u_long p_bad_i_t_l;
2003 u_long p_bad_i_t_l_q;
2004
2005
2006
2007
2008
2009
2010 u_int32 *badluntbl;
2011 u_int32 resel_badlun;
2012
2013
2014
2015
2016
2017
2018
2019 u_int32 scr_ram_seg;
2020
2021
2022
2023
2024
2025 Scsi_Cmnd *waiting_list;
2026
2027 Scsi_Cmnd *done_list;
2028
2029#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
2030 spinlock_t smp_lock;
2031#endif
2032
2033
2034
2035
2036
2037 int unit;
2038 char chip_name[8];
2039 char inst_name[16];
2040
2041
2042
2043
2044
2045
2046
2047 u_char sv_scntl0, sv_scntl3, sv_dmode, sv_dcntl, sv_ctest3, sv_ctest4,
2048 sv_ctest5, sv_gpcntl, sv_stest2, sv_stest4, sv_stest1, sv_scntl4;
2049
2050
2051
2052
2053
2054
2055
2056 u_char rv_scntl0, rv_scntl3, rv_dmode, rv_dcntl, rv_ctest3, rv_ctest4,
2057 rv_ctest5, rv_stest2, rv_ccntl0, rv_ccntl1, rv_scntl4;
2058
2059
2060
2061
2062
2063
2064
2065 struct tcb target[MAX_TARGET];
2066 u_int32 *targtbl;
2067
2068
2069
2070
2071
2072#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
2073 u_long base_va;
2074 u_long base2_va;
2075#endif
2076 u_long base_ba;
2077 u_long base_io;
2078 u_long base_ws;
2079 u_long base2_ba;
2080 u_long base2_ws;
2081 u_int irq;
2082 volatile
2083 struct ncr_reg *reg;
2084
2085
2086
2087
2088
2089
2090
2091
2092 struct script *script0;
2093 struct scripth *scripth0;
2094 u_long p_script;
2095 u_long p_scripth;
2096 u_long p_scripth0;
2097
2098
2099
2100
2101
2102 pcidev_t pdev;
2103 u_short device_id;
2104 u_char revision_id;
2105 u_char bus;
2106 u_char device_fn;
2107 u_char myaddr;
2108 u_char maxburst;
2109 u_char maxwide;
2110 u_char minsync;
2111 u_char maxsync;
2112 u_char maxoffs;
2113 u_char maxoffs_st;
2114 u_char multiplier;
2115 u_char clock_divn;
2116 u_long clock_khz;
2117 u_int features;
2118
2119
2120
2121
2122
2123
2124
2125
2126 u_int pciclock_min;
2127 u_int pciclock_max;
2128
2129
2130
2131
2132
2133
2134
2135 u_long p_squeue;
2136 u_int32 *squeue;
2137 u_short squeueput;
2138 u_short actccbs;
2139 u_short queuedepth;
2140
2141
2142
2143
2144
2145
2146 u_short dqueueget;
2147 u_int32 *dqueue;
2148
2149
2150
2151
2152
2153 struct timer_list timer;
2154 u_long lasttime;
2155 u_long settle_time;
2156
2157
2158
2159
2160
2161 struct ncr_reg regdump;
2162 u_long regtime;
2163
2164
2165
2166
2167
2168
2169
2170 u_char msgout[12];
2171 u_char msgin [12];
2172 u_int32 lastmsg;
2173 u_char scratch;
2174
2175
2176
2177
2178
2179 u_char scsi_mode;
2180 u_char order;
2181 u_char verbose;
2182 u_int32 ncr_cache;
2183 u_long p_ncb;
2184
2185
2186
2187
2188
2189 ccb_p ccbh[CCB_HASH_SIZE];
2190 struct ccb *ccbc;
2191 XPT_QUEHEAD free_ccbq;
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205#ifdef SCSI_NCR_IARB_SUPPORT
2206 struct ccb *last_cp;
2207 u_short iarb_max;
2208 u_short iarb_count;
2209#endif
2210
2211
2212
2213
2214
2215
2216
2217
2218 XPT_QUEHEAD b0_ccbq;
2219
2220
2221
2222
2223
2224 int (*scatter) (ncb_p, ccb_p, Scsi_Cmnd *);
2225
2226
2227
2228
2229
2230
2231
2232 u_char abrt_msg[4];
2233 struct scr_tblmove abrt_tbl;
2234 struct scr_tblsel abrt_sel;
2235 u_char istat_sem;
2236
2237
2238
2239
2240
2241 struct usrcmd user;
2242 volatile u_char release_stage;
2243
2244
2245
2246
2247
2248 unsigned char check_integrity;
2249
2250#ifdef SCSI_NCR_INTEGRITY_CHECKING
2251 unsigned char check_integ_par;
2252
2253#endif
2254};
2255
2256#define NCB_PHYS(np, lbl) (np->p_ncb + offsetof(struct ncb, lbl))
2257#define NCB_SCRIPT_PHYS(np,lbl) (np->p_script + offsetof (struct script, lbl))
2258#define NCB_SCRIPTH_PHYS(np,lbl) (np->p_scripth + offsetof (struct scripth,lbl))
2259#define NCB_SCRIPTH0_PHYS(np,lbl) (np->p_scripth0+offsetof (struct scripth,lbl))
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286struct script {
2287 ncrcmd start [ 14];
2288 ncrcmd getjob_begin [ 4];
2289 ncrcmd getjob_end [ 4];
2290 ncrcmd select [ 8];
2291 ncrcmd wf_sel_done [ 2];
2292 ncrcmd send_ident [ 2];
2293#ifdef SCSI_NCR_IARB_SUPPORT
2294 ncrcmd select2 [ 8];
2295#else
2296 ncrcmd select2 [ 2];
2297#endif
2298 ncrcmd command [ 2];
2299 ncrcmd dispatch [ 28];
2300 ncrcmd sel_no_cmd [ 10];
2301 ncrcmd init [ 6];
2302 ncrcmd clrack [ 4];
2303 ncrcmd disp_status [ 4];
2304 ncrcmd datai_done [ 26];
2305 ncrcmd datao_done [ 12];
2306 ncrcmd ign_i_w_r_msg [ 4];
2307 ncrcmd datai_phase [ 2];
2308 ncrcmd datao_phase [ 4];
2309 ncrcmd msg_in [ 2];
2310 ncrcmd msg_in2 [ 10];
2311#ifdef SCSI_NCR_IARB_SUPPORT
2312 ncrcmd status [ 14];
2313#else
2314 ncrcmd status [ 10];
2315#endif
2316 ncrcmd complete [ 8];
2317#ifdef SCSI_NCR_PCIQ_MAY_REORDER_WRITES
2318 ncrcmd complete2 [ 12];
2319#else
2320 ncrcmd complete2 [ 10];
2321#endif
2322#ifdef SCSI_NCR_PCIQ_SYNC_ON_INTR
2323 ncrcmd done [ 18];
2324#else
2325 ncrcmd done [ 14];
2326#endif
2327 ncrcmd done_end [ 2];
2328 ncrcmd save_dp [ 8];
2329 ncrcmd restore_dp [ 4];
2330 ncrcmd disconnect [ 20];
2331#ifdef SCSI_NCR_IARB_SUPPORT
2332 ncrcmd idle [ 4];
2333#else
2334 ncrcmd idle [ 2];
2335#endif
2336#ifdef SCSI_NCR_IARB_SUPPORT
2337 ncrcmd ungetjob [ 6];
2338#else
2339 ncrcmd ungetjob [ 4];
2340#endif
2341 ncrcmd reselect [ 4];
2342 ncrcmd reselected [ 20];
2343 ncrcmd resel_scntl4 [ 30];
2344#if MAX_TASKS*4 > 512
2345 ncrcmd resel_tag [ 18];
2346#elif MAX_TASKS*4 > 256
2347 ncrcmd resel_tag [ 12];
2348#else
2349 ncrcmd resel_tag [ 8];
2350#endif
2351 ncrcmd resel_go [ 6];
2352 ncrcmd resel_notag [ 2];
2353 ncrcmd resel_dsa [ 8];
2354 ncrcmd data_in [MAX_SCATTER * SCR_SG_SIZE];
2355 ncrcmd data_in2 [ 4];
2356 ncrcmd data_out [MAX_SCATTER * SCR_SG_SIZE];
2357 ncrcmd data_out2 [ 4];
2358 ncrcmd pm0_data [ 12];
2359 ncrcmd pm0_data_out [ 6];
2360 ncrcmd pm0_data_end [ 6];
2361 ncrcmd pm1_data [ 12];
2362 ncrcmd pm1_data_out [ 6];
2363 ncrcmd pm1_data_end [ 6];
2364};
2365
2366
2367
2368
2369
2370struct scripth {
2371 ncrcmd start64 [ 2];
2372 ncrcmd no_data [ 2];
2373 ncrcmd sel_for_abort [ 18];
2374 ncrcmd sel_for_abort_1 [ 2];
2375 ncrcmd select_no_atn [ 8];
2376 ncrcmd wf_sel_done_no_atn [ 4];
2377
2378 ncrcmd msg_in_etc [ 14];
2379 ncrcmd msg_received [ 4];
2380 ncrcmd msg_weird_seen [ 4];
2381 ncrcmd msg_extended [ 20];
2382 ncrcmd msg_bad [ 6];
2383 ncrcmd msg_weird [ 4];
2384 ncrcmd msg_weird1 [ 8];
2385
2386 ncrcmd wdtr_resp [ 6];
2387 ncrcmd send_wdtr [ 4];
2388 ncrcmd sdtr_resp [ 6];
2389 ncrcmd send_sdtr [ 4];
2390 ncrcmd ppr_resp [ 6];
2391 ncrcmd send_ppr [ 4];
2392 ncrcmd nego_bad_phase [ 4];
2393 ncrcmd msg_out [ 4];
2394 ncrcmd msg_out_done [ 4];
2395 ncrcmd data_ovrun [ 2];
2396 ncrcmd data_ovrun1 [ 22];
2397 ncrcmd data_ovrun2 [ 8];
2398 ncrcmd abort_resel [ 16];
2399 ncrcmd resend_ident [ 4];
2400 ncrcmd ident_break [ 4];
2401 ncrcmd ident_break_atn [ 4];
2402 ncrcmd sdata_in [ 6];
2403 ncrcmd data_io [ 2];
2404 ncrcmd data_io_com [ 8];
2405 ncrcmd data_io_out [ 12];
2406 ncrcmd resel_bad_lun [ 4];
2407 ncrcmd bad_i_t_l [ 4];
2408 ncrcmd bad_i_t_l_q [ 4];
2409 ncrcmd bad_status [ 6];
2410 ncrcmd tweak_pmj [ 12];
2411 ncrcmd pm_handle [ 20];
2412 ncrcmd pm_handle1 [ 4];
2413 ncrcmd pm_save [ 4];
2414 ncrcmd pm0_save [ 14];
2415 ncrcmd pm1_save [ 14];
2416
2417
2418#ifdef SYM_DEBUG_PM_WITH_WSR
2419 ncrcmd pm_wsr_handle [ 44];
2420#else
2421 ncrcmd pm_wsr_handle [ 42];
2422#endif
2423 ncrcmd wsr_ma_helper [ 4];
2424
2425
2426 ncrcmd zero [ 1];
2427 ncrcmd scratch [ 1];
2428 ncrcmd scratch1 [ 1];
2429 ncrcmd pm0_data_addr [ 1];
2430 ncrcmd pm1_data_addr [ 1];
2431 ncrcmd saved_dsa [ 1];
2432 ncrcmd saved_drs [ 1];
2433 ncrcmd done_pos [ 1];
2434 ncrcmd startpos [ 1];
2435 ncrcmd targtbl [ 1];
2436
2437
2438#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
2439 ncrcmd start_ram [ 1];
2440 ncrcmd script0_ba [ 4];
2441 ncrcmd start_ram64 [ 3];
2442 ncrcmd script0_ba64 [ 3];
2443 ncrcmd scripth0_ba64 [ 6];
2444 ncrcmd ram_seg64 [ 1];
2445#endif
2446 ncrcmd snooptest [ 6];
2447 ncrcmd snoopend [ 2];
2448};
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459static ccb_p ncr_alloc_ccb (ncb_p np);
2460static void ncr_complete (ncb_p np, ccb_p cp);
2461static void ncr_exception (ncb_p np);
2462static void ncr_free_ccb (ncb_p np, ccb_p cp);
2463static ccb_p ncr_ccb_from_dsa(ncb_p np, u_long dsa);
2464static void ncr_init_tcb (ncb_p np, u_char tn);
2465static lcb_p ncr_alloc_lcb (ncb_p np, u_char tn, u_char ln);
2466static lcb_p ncr_setup_lcb (ncb_p np, u_char tn, u_char ln,
2467 u_char *inq_data);
2468static void ncr_getclock (ncb_p np, int mult);
2469static u_int ncr_getpciclock (ncb_p np);
2470static void ncr_selectclock (ncb_p np, u_char scntl3);
2471static ccb_p ncr_get_ccb (ncb_p np, u_char tn, u_char ln);
2472static void ncr_init (ncb_p np, int reset, char * msg, u_long code);
2473static void ncr_int_sbmc (ncb_p np);
2474static void ncr_int_par (ncb_p np, u_short sist);
2475static void ncr_int_ma (ncb_p np);
2476static void ncr_int_sir (ncb_p np);
2477static void ncr_int_sto (ncb_p np);
2478static void ncr_int_udc (ncb_p np);
2479static void ncr_negotiate (ncb_p np, tcb_p tp);
2480static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr);
2481#ifdef SCSI_NCR_INTEGRITY_CHECKING
2482static int ncr_ic_nego(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd, u_char *msgptr);
2483#endif
2484static void ncr_script_copy_and_bind
2485 (ncb_p np, ncrcmd *src, ncrcmd *dst, int len);
2486static void ncr_script_fill (struct script * scr, struct scripth * scripth);
2487static int ncr_scatter_896R1 (ncb_p np, ccb_p cp, Scsi_Cmnd *cmd);
2488static int ncr_scatter (ncb_p np, ccb_p cp, Scsi_Cmnd *cmd);
2489static void ncr_getsync (ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p);
2490static void ncr_get_xfer_info(ncb_p np, tcb_p tp, u_char *factor, u_char *offset, u_char *width);
2491static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer, u_char scntl4);
2492static void ncr_set_sync_wide_status (ncb_p np, u_char target);
2493static void ncr_setup_tags (ncb_p np, u_char tn, u_char ln);
2494static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack);
2495static void ncr_setsyncwide (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer, u_char scntl4, u_char wide);
2496static int ncr_show_msg (u_char * msg);
2497static void ncr_print_msg (ccb_p cp, char *label, u_char * msg);
2498static int ncr_snooptest (ncb_p np);
2499static void ncr_timeout (ncb_p np);
2500static void ncr_wakeup (ncb_p np, u_long code);
2501static int ncr_wakeup_done (ncb_p np);
2502static void ncr_start_next_ccb (ncb_p np, lcb_p lp, int maxn);
2503static void ncr_put_start_queue(ncb_p np, ccb_p cp);
2504static void ncr_chip_reset (ncb_p np);
2505static void ncr_soft_reset (ncb_p np);
2506static void ncr_start_reset (ncb_p np);
2507static int ncr_reset_scsi_bus (ncb_p np, int enab_int, int settle_delay);
2508static int ncr_compute_residual (ncb_p np, ccb_p cp);
2509
2510#ifdef SCSI_NCR_USER_COMMAND_SUPPORT
2511static void ncr_usercmd (ncb_p np);
2512#endif
2513
2514static int ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device);
2515static void ncr_free_resources(ncb_p np);
2516
2517static void insert_into_waiting_list(ncb_p np, Scsi_Cmnd *cmd);
2518static Scsi_Cmnd *retrieve_from_waiting_list(int to_remove, ncb_p np, Scsi_Cmnd *cmd);
2519static void process_waiting_list(ncb_p np, int sts);
2520
2521#define remove_from_waiting_list(np, cmd) \
2522 retrieve_from_waiting_list(1, (np), (cmd))
2523#define requeue_waiting_list(np) process_waiting_list((np), DID_OK)
2524#define reset_waiting_list(np) process_waiting_list((np), DID_RESET)
2525
2526#ifdef SCSI_NCR_NVRAM_SUPPORT
2527static void ncr_get_nvram (ncr_device *devp, ncr_nvram *nvp);
2528static int sym_read_Tekram_nvram (ncr_slot *np, u_short device_id,
2529 Tekram_nvram *nvram);
2530static int sym_read_Symbios_nvram (ncr_slot *np, Symbios_nvram *nvram);
2531#endif
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542static inline char *ncr_name (ncb_p np)
2543{
2544 return np->inst_name;
2545}
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567#define RELOC_SOFTC 0x40000000
2568#define RELOC_LABEL 0x50000000
2569#define RELOC_REGISTER 0x60000000
2570#if 0
2571#define RELOC_KVAR 0x70000000
2572#endif
2573#define RELOC_LABELH 0x80000000
2574#define RELOC_MASK 0xf0000000
2575
2576#define NADDR(label) (RELOC_SOFTC | offsetof(struct ncb, label))
2577#define PADDR(label) (RELOC_LABEL | offsetof(struct script, label))
2578#define PADDRH(label) (RELOC_LABELH | offsetof(struct scripth, label))
2579#define RADDR(label) (RELOC_REGISTER | REG(label))
2580#define FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs)))
2581#define KVAR(which) (RELOC_KVAR | (which))
2582
2583#define SCR_DATA_ZERO 0xf00ff00f
2584
2585#ifdef RELOC_KVAR
2586#define SCRIPT_KVAR_JIFFIES (0)
2587#define SCRIPT_KVAR_FIRST SCRIPT_KVAR_JIFFIES
2588#define SCRIPT_KVAR_LAST SCRIPT_KVAR_JIFFIES
2589
2590
2591
2592
2593static void *script_kvars[] __initdata =
2594 { (void *)&jiffies };
2595#endif
2596
2597static struct script script0 __initdata = {
2598 {
2599
2600
2601
2602
2603 SCR_NO_OP,
2604 0,
2605
2606
2607
2608 SCR_FROM_REG (ctest2),
2609 0,
2610
2611
2612
2613
2614
2615
2616 SCR_FROM_REG (istat),
2617 0,
2618
2619
2620
2621
2622
2623 SCR_LOAD_ABS (scratcha, 4),
2624 PADDRH (startpos),
2625 SCR_INT ^ IFTRUE (MASK (SEM, SEM)),
2626 SIR_SCRIPT_STOPPED,
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642 SCR_LOAD_ABS (dsa, 4),
2643 PADDRH (startpos),
2644 SCR_LOAD_REL (temp, 4),
2645 4,
2646},{
2647 SCR_STORE_ABS (temp, 4),
2648 PADDRH (startpos),
2649 SCR_LOAD_REL (dsa, 4),
2650 0,
2651},{
2652 SCR_LOAD_REL (temp, 4),
2653 0,
2654 SCR_RETURN,
2655 0,
2656
2657},{
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670 SCR_CLR (SCR_TRG),
2671 0,
2672
2673
2674
2675 SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select),
2676 PADDR (ungetjob),
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710 SCR_LOAD_REL (temp, 4),
2711 offsetof (struct ccb, phys.header.savep),
2712
2713
2714
2715 SCR_LOAD_REL (scr0, 4),
2716 offsetof (struct ccb, phys.header.status),
2717
2718},{
2719 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
2720 SIR_SEL_ATN_NO_MSG_OUT,
2721},{
2722
2723
2724
2725
2726
2727 SCR_MOVE_TBL ^ SCR_MSG_OUT,
2728 offsetof (struct dsb, smsg),
2729},{
2730#ifdef SCSI_NCR_IARB_SUPPORT
2731
2732
2733
2734
2735 SCR_FROM_REG (HF_REG),
2736 0,
2737 SCR_JUMPR ^ IFFALSE (MASK (HF_HINT_IARB, HF_HINT_IARB)),
2738 8,
2739 SCR_REG_REG (scntl1, SCR_OR, IARB),
2740 0,
2741#endif
2742
2743
2744
2745
2746 SCR_JUMP ^ IFFALSE (WHEN (SCR_COMMAND)),
2747 PADDR (sel_no_cmd),
2748
2749},{
2750
2751
2752
2753 SCR_MOVE_TBL ^ SCR_COMMAND,
2754 offsetof (struct dsb, cmd),
2755
2756},{
2757
2758
2759
2760
2761
2762 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),
2763 PADDR (msg_in),
2764 SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT)),
2765 PADDR (datao_phase),
2766 SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN)),
2767 PADDR (datai_phase),
2768 SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)),
2769 PADDR (status),
2770 SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)),
2771 PADDR (command),
2772 SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)),
2773 PADDRH (msg_out),
2774
2775
2776
2777
2778 SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_OUT)),
2779 16,
2780 SCR_MOVE_ABS (1) ^ SCR_ILG_OUT,
2781 NADDR (scratch),
2782 SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_OUT)),
2783 -16,
2784 SCR_JUMPR ^ IFFALSE (WHEN (SCR_ILG_IN)),
2785 16,
2786 SCR_MOVE_ABS (1) ^ SCR_ILG_IN,
2787 NADDR (scratch),
2788 SCR_JUMPR ^ IFTRUE (WHEN (SCR_ILG_IN)),
2789 -16,
2790 SCR_INT,
2791 SIR_BAD_PHASE,
2792 SCR_JUMP,
2793 PADDR (dispatch),
2794},{
2795
2796
2797
2798
2799
2800
2801
2802 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)),
2803 PADDRH (resend_ident),
2804
2805
2806
2807
2808
2809 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),
2810 PADDR (dispatch),
2811 SCR_FROM_REG (HS_REG),
2812 0,
2813 SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)),
2814 SIR_NEGO_FAILED,
2815
2816
2817
2818 SCR_JUMP,
2819 PADDR (dispatch),
2820
2821},{
2822
2823
2824
2825
2826
2827
2828 SCR_FROM_REG (sstat0),
2829 0,
2830 SCR_JUMPR ^ IFTRUE (MASK (IRST, IRST)),
2831 -16,
2832 SCR_JUMP,
2833 PADDR (start),
2834},{
2835
2836
2837
2838 SCR_CLR (SCR_ACK),
2839 0,
2840 SCR_JUMP,
2841 PADDR (dispatch),
2842
2843},{
2844
2845
2846
2847
2848
2849
2850 SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)),
2851 PADDR (status),
2852 SCR_JUMP,
2853 PADDR (dispatch),
2854
2855},{
2856
2857
2858
2859
2860 SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_IN)),
2861 PADDRH (data_ovrun),
2862
2863
2864
2865
2866
2867
2868 SCR_FROM_REG (scntl2),
2869 0,
2870 SCR_JUMP ^ IFFALSE (MASK (WSR, WSR)),
2871 PADDR (disp_status),
2872
2873
2874
2875
2876 SCR_REG_REG (scntl2, SCR_OR, WSR),
2877 0,
2878
2879
2880
2881
2882
2883 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),
2884 SIR_SWIDE_OVERRUN,
2885 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
2886 PADDR (disp_status),
2887
2888
2889
2890
2891
2892
2893
2894 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
2895 NADDR (msgin[0]),
2896 SCR_INT ^ IFFALSE (DATA (M_IGN_RESIDUE)),
2897 SIR_SWIDE_OVERRUN,
2898 SCR_JUMP ^ IFFALSE (DATA (M_IGN_RESIDUE)),
2899 PADDR (msg_in2),
2900
2901
2902
2903
2904
2905 SCR_CLR (SCR_ACK),
2906 0,
2907 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
2908 NADDR (msgin[1]),
2909 SCR_CLR (SCR_ACK),
2910 0,
2911 SCR_JUMP,
2912 PADDR (disp_status),
2913
2914},{
2915
2916
2917
2918
2919 SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
2920 PADDRH (data_ovrun),
2921
2922
2923
2924
2925 SCR_FROM_REG (scntl2),
2926 0,
2927 SCR_JUMP ^ IFFALSE (MASK (WSS, WSS)),
2928 PADDR (disp_status),
2929
2930
2931
2932 SCR_REG_REG (scntl2, SCR_OR, WSS),
2933 0,
2934
2935
2936
2937
2938 SCR_INT,
2939 SIR_SODL_UNDERRUN,
2940 SCR_JUMP,
2941 PADDR (dispatch),
2942
2943},{
2944
2945
2946
2947
2948
2949
2950
2951 SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
2952 NADDR (scratch),
2953
2954
2955
2956 SCR_JUMP,
2957 PADDR (clrack),
2958
2959},{
2960 SCR_RETURN,
2961 0,
2962},{
2963
2964
2965
2966
2967
2968
2969
2970 SCR_NO_OP,
2971 0,
2972 SCR_RETURN,
2973 0,
2974},{
2975
2976
2977
2978
2979
2980
2981 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
2982 NADDR (msgin[0]),
2983},{
2984
2985
2986
2987
2988 SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)),
2989 PADDR (complete),
2990 SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),
2991 PADDR (disconnect),
2992 SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)),
2993 PADDR (save_dp),
2994 SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)),
2995 PADDR (restore_dp),
2996
2997
2998
2999
3000
3001 SCR_JUMP,
3002 PADDRH (msg_in_etc),
3003
3004},{
3005
3006
3007
3008 SCR_MOVE_ABS (1) ^ SCR_STATUS,
3009 NADDR (scratch),
3010#ifdef SCSI_NCR_IARB_SUPPORT
3011
3012
3013
3014
3015
3016 SCR_JUMPR ^ IFTRUE (DATA (S_GOOD)),
3017 8,
3018 SCR_REG_REG (scntl1, SCR_AND, ~IARB),
3019 0,
3020#endif
3021
3022
3023
3024
3025 SCR_TO_REG (SS_REG),
3026 0,
3027 SCR_LOAD_REG (HS_REG, HS_COMPLETE),
3028 0,
3029
3030
3031
3032
3033 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)),
3034 PADDR (msg_in),
3035 SCR_JUMP,
3036 PADDR (dispatch),
3037
3038},{
3039
3040
3041
3042
3043
3044 SCR_STORE_REL (temp, 4),
3045 offsetof (struct ccb, phys.header.lastp),
3046
3047
3048
3049
3050
3051
3052
3053
3054 SCR_REG_REG (scntl2, SCR_AND, 0x7f),
3055 0,
3056
3057
3058
3059 SCR_CLR (SCR_ACK|SCR_ATN),
3060 0,
3061
3062
3063
3064 SCR_WAIT_DISC,
3065 0,
3066},{
3067
3068
3069
3070 SCR_STORE_REL (scr0, 4),
3071 offsetof (struct ccb, phys.header.status),
3072
3073#ifdef SCSI_NCR_PCIQ_MAY_REORDER_WRITES
3074
3075
3076
3077
3078
3079
3080
3081
3082 SCR_LOAD_REL (scr0, 4),
3083 offsetof (struct ccb, phys.header.status),
3084#endif
3085
3086
3087
3088
3089 SCR_FROM_REG (SS_REG),
3090 0,
3091 SCR_CALL ^ IFFALSE (DATA (S_GOOD)),
3092 PADDRH (bad_status),
3093
3094
3095
3096
3097
3098
3099 SCR_FROM_REG (HF_REG),
3100 0,
3101 SCR_INT ^ IFTRUE (MASK (HF_AUTO_SENSE, HF_AUTO_SENSE)),
3102 SIR_AUTO_SENSE_DONE,
3103
3104},{
3105#ifdef SCSI_NCR_PCIQ_SYNC_ON_INTR
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118 SCR_FROM_REG (istat),
3119 0,
3120 SCR_INT ^ IFTRUE (MASK (INTF, INTF)),
3121 SIR_DUMMY_INTERRUPT,
3122#endif
3123
3124
3125
3126
3127
3128
3129
3130 SCR_STORE_ABS (dsa, 4),
3131 PADDRH (saved_dsa),
3132 SCR_LOAD_ABS (dsa, 4),
3133 PADDRH (done_pos),
3134 SCR_LOAD_ABS (scratcha, 4),
3135 PADDRH (saved_dsa),
3136 SCR_STORE_REL (scratcha, 4),
3137 0,
3138
3139
3140
3141
3142
3143
3144
3145 SCR_LOAD_REL (temp, 4),
3146 4,
3147 SCR_INT_FLY,
3148 0,
3149 SCR_STORE_ABS (temp, 4),
3150 PADDRH (done_pos),
3151},{
3152 SCR_JUMP,
3153 PADDR (start),
3154
3155},{
3156
3157
3158
3159
3160 SCR_CLR (SCR_ACK),
3161 0,
3162
3163
3164
3165
3166
3167
3168 SCR_REG_REG (HF_REG, SCR_OR, HF_DP_SAVED),
3169 0,
3170
3171
3172
3173
3174 SCR_STORE_REL (temp, 4),
3175 offsetof (struct ccb, phys.header.savep),
3176 SCR_JUMP,
3177 PADDR (dispatch),
3178},{
3179
3180
3181
3182
3183 SCR_LOAD_REL (temp, 4),
3184 offsetof (struct ccb, phys.header.savep),
3185 SCR_JUMP,
3186 PADDR (clrack),
3187
3188},{
3189
3190
3191
3192
3193
3194
3195 SCR_REG_REG (scntl2, SCR_AND, 0x7f),
3196 0,
3197 SCR_CLR (SCR_ACK|SCR_ATN),
3198 0,
3199
3200
3201
3202 SCR_WAIT_DISC,
3203 0,
3204
3205
3206
3207 SCR_LOAD_REG (HS_REG, HS_DISCONNECT),
3208 0,
3209
3210
3211
3212 SCR_STORE_REL (scr0, 4),
3213 offsetof (struct ccb, phys.header.status),
3214
3215
3216
3217
3218 SCR_FROM_REG (QU_REG),
3219 0,
3220 SCR_JUMP ^ IFFALSE (MASK (QUIRK_AUTOSAVE, QUIRK_AUTOSAVE)),
3221 PADDR (start),
3222
3223
3224
3225
3226
3227 SCR_REG_REG (HF_REG, SCR_OR, HF_DP_SAVED),
3228 0,
3229 SCR_STORE_REL (temp, 4),
3230 offsetof (struct ccb, phys.header.savep),
3231 SCR_JUMP,
3232 PADDR (start),
3233
3234},{
3235
3236
3237
3238
3239
3240
3241 SCR_NO_OP,
3242 0,
3243#ifdef SCSI_NCR_IARB_SUPPORT
3244 SCR_JUMPR,
3245 8,
3246#endif
3247},{
3248#ifdef SCSI_NCR_IARB_SUPPORT
3249
3250
3251
3252
3253
3254 SCR_REG_REG (scntl1, SCR_OR, IARB),
3255 0,
3256#endif
3257
3258
3259
3260
3261
3262
3263 SCR_LOAD_REG (dsa, 0xff),
3264 0,
3265 SCR_STORE_ABS (scratcha, 4),
3266 PADDRH (startpos),
3267},{
3268
3269
3270
3271 SCR_CLR (SCR_TRG),
3272 0,
3273
3274
3275
3276
3277
3278
3279 SCR_WAIT_RESEL,
3280 PADDR(start),
3281},{
3282
3283
3284
3285
3286 SCR_NO_OP,
3287 0,
3288
3289
3290
3291 SCR_REG_SFBR (ssid, SCR_AND, 0x8F),
3292 0,
3293 SCR_TO_REG (sdid),
3294 0,
3295
3296
3297
3298 SCR_LOAD_ABS (dsa, 4),
3299 PADDRH (targtbl),
3300 SCR_SFBR_REG (dsa, SCR_SHL, 0),
3301 0,
3302 SCR_REG_REG (dsa, SCR_SHL, 0),
3303 0,
3304 SCR_REG_REG (dsa, SCR_AND, 0x3c),
3305 0,
3306 SCR_LOAD_REL (dsa, 4),
3307 0,
3308
3309
3310
3311 SCR_LOAD_REL (scntl3, 1),
3312 offsetof(struct tcb, wval),
3313 SCR_LOAD_REL (sxfer, 1),
3314 offsetof(struct tcb, sval),
3315},{
3316
3317
3318
3319
3320
3321
3322
3323
3324 SCR_NO_OP,
3325 0,
3326
3327
3328
3329
3330 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_IN)),
3331 SIR_RESEL_NO_MSG_IN,
3332 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
3333 NADDR (msgin),
3334
3335
3336
3337
3338
3339 SCR_JUMPR ^ IFTRUE (MASK (0x80, 0xbf)),
3340 56,
3341
3342
3343
3344
3345 SCR_INT ^ IFFALSE (MASK (0x80, 0x80)),
3346 SIR_RESEL_NO_IDENTIFY,
3347
3348
3349
3350
3351 SCR_LOAD_REL (dsa, 4),
3352 offsetof(struct tcb, b_luntbl),
3353 SCR_SFBR_REG (dsa, SCR_SHL, 0),
3354 0,
3355 SCR_REG_REG (dsa, SCR_SHL, 0),
3356 0,
3357 SCR_REG_REG (dsa, SCR_AND, 0xfc),
3358 0,
3359 SCR_LOAD_REL (dsa, 4),
3360 0,
3361 SCR_JUMPR,
3362 8,
3363
3364
3365
3366 SCR_LOAD_REL (dsa, 4),
3367 offsetof(struct tcb, b_lun0),
3368
3369
3370
3371
3372
3373
3374 SCR_LOAD_REL (temp, 4),
3375 offsetof(struct lcb, resel_task),
3376 SCR_LOAD_REL (dsa, 4),
3377 offsetof(struct lcb, b_tasktbl),
3378 SCR_RETURN,
3379 0,
3380},{
3381
3382
3383
3384
3385 SCR_CLR (SCR_ACK),
3386 0,
3387
3388
3389
3390
3391
3392
3393 SCR_MOVE_ABS (2) ^ SCR_MSG_IN,
3394 NADDR (msgin),
3395
3396
3397
3398
3399
3400
3401
3402 SCR_REG_SFBR (sidl, SCR_SHL, 0),
3403 0,
3404#if MAX_TASKS*4 > 512
3405 SCR_JUMPR ^ IFFALSE (CARRYSET),
3406 8,
3407 SCR_REG_REG (dsa1, SCR_OR, 2),
3408 0,
3409 SCR_REG_REG (sfbr, SCR_SHL, 0),
3410 0,
3411 SCR_JUMPR ^ IFFALSE (CARRYSET),
3412 8,
3413 SCR_REG_REG (dsa1, SCR_OR, 1),
3414 0,
3415#elif MAX_TASKS*4 > 256
3416 SCR_JUMPR ^ IFFALSE (CARRYSET),
3417 8,
3418 SCR_REG_REG (dsa1, SCR_OR, 1),
3419 0,
3420#endif
3421
3422
3423
3424
3425 SCR_SFBR_REG (dsa, SCR_AND, 0xfc),
3426 0,
3427},{
3428 SCR_LOAD_REL (dsa, 4),
3429 0,
3430 SCR_LOAD_REL (temp, 4),
3431 offsetof(struct ccb, phys.header.go.restart),
3432 SCR_RETURN,
3433 0,
3434
3435},{
3436
3437
3438
3439 SCR_JUMP,
3440 PADDR (resel_go),
3441
3442},{
3443
3444
3445
3446 SCR_CLR (SCR_ACK),
3447 0,
3448
3449
3450
3451
3452 SCR_LOAD_REL (temp, 4),
3453 offsetof (struct ccb, phys.header.savep),
3454
3455
3456
3457 SCR_LOAD_REL (scr0, 4),
3458 offsetof (struct ccb, phys.header.status),
3459
3460
3461
3462 SCR_JUMP,
3463 PADDR (dispatch),
3464
3465},{
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
34780
3479},{
3480 SCR_CALL,
3481 PADDR (datai_done),
3482 SCR_JUMP,
3483 PADDRH (data_ovrun),
3484},{
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
34970
3498},{
3499 SCR_CALL,
3500 PADDR (datao_done),
3501 SCR_JUMP,
3502 PADDRH (data_ovrun),
3503
3504},{
3505
3506
3507
3508
3509 SCR_FROM_REG (HF_REG),
3510 0,
3511
3512
3513
3514 SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),
3515 PADDR (pm0_data_out),
3516
3517
3518
3519
3520 SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),
3521 PADDRH (data_ovrun),
3522
3523
3524
3525
3526 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0),
3527 0,
3528
3529
3530
3531 SCR_CHMOV_TBL ^ SCR_DATA_IN,
3532 offsetof (struct ccb, phys.pm0.sg),
3533 SCR_JUMP,
3534 PADDR (pm0_data_end),
3535},{
3536
3537
3538
3539
3540 SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),
3541 PADDRH (data_ovrun),
3542
3543
3544
3545
3546 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM0),
3547 0,
3548
3549
3550
3551 SCR_CHMOV_TBL ^ SCR_DATA_OUT,
3552 offsetof (struct ccb, phys.pm0.sg),
3553},{
3554
3555
3556
3557
3558 SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM0)),
3559 0,
3560
3561
3562
3563
3564
3565 SCR_LOAD_REL (temp, 4),
3566 offsetof (struct ccb, phys.pm0.ret),
3567 SCR_RETURN,
3568 0,
3569},{
3570
3571
3572
3573
3574 SCR_FROM_REG (HF_REG),
3575 0,
3576
3577
3578
3579 SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)),
3580 PADDR (pm1_data_out),
3581
3582
3583
3584
3585 SCR_JUMP ^ IFFALSE (MASK (HF_DATA_IN, HF_DATA_IN)),
3586 PADDRH (data_ovrun),
3587
3588
3589
3590
3591 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1),
3592 0,
3593
3594
3595
3596 SCR_CHMOV_TBL ^ SCR_DATA_IN,
3597 offsetof (struct ccb, phys.pm1.sg),
3598 SCR_JUMP,
3599 PADDR (pm1_data_end),
3600},{
3601
3602
3603
3604
3605 SCR_JUMP ^ IFTRUE (MASK (HF_DATA_IN, HF_DATA_IN)),
3606 PADDRH (data_ovrun),
3607
3608
3609
3610
3611 SCR_REG_REG (HF_REG, SCR_OR, HF_IN_PM1),
3612 0,
3613
3614
3615
3616 SCR_CHMOV_TBL ^ SCR_DATA_OUT,
3617 offsetof (struct ccb, phys.pm1.sg),
3618},{
3619
3620
3621
3622
3623 SCR_REG_REG (HF_REG, SCR_AND, (~HF_IN_PM1)),
3624 0,
3625
3626
3627
3628
3629
3630 SCR_LOAD_REL (temp, 4),
3631 offsetof (struct ccb, phys.pm1.ret),
3632 SCR_RETURN,
3633 0,
3634}
3635};
3636
3637
3638static struct scripth scripth0 __initdata = {
3639{
3640
3641
3642
3643
3644
3645 SCR_JUMP,
3646 PADDR (init),
3647},{
3648 SCR_JUMP,
3649 PADDRH (data_ovrun),
3650},{
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662 SCR_CLR (SCR_TRG),
3663 0,
3664
3665
3666
3667 SCR_SEL_TBL_ATN ^ offsetof (struct ncb, abrt_sel),
3668 PADDR (reselect),
3669
3670
3671
3672
3673
3674 SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)),
3675 -8,
3676
3677
3678
3679 SCR_INT,
3680 SIR_TARGET_SELECTED,
3681
3682
3683
3684
3685
3686
3687 SCR_REG_REG (scntl2, SCR_AND, 0x7f),
3688 0,
3689 SCR_MOVE_TBL ^ SCR_MSG_OUT,
3690 offsetof (struct ncb, abrt_tbl),
3691 SCR_CLR (SCR_ACK|SCR_ATN),
3692 0,
3693 SCR_WAIT_DISC,
3694 0,
3695
3696
3697
3698 SCR_INT,
3699 SIR_ABORT_SENT,
3700},{
3701
3702
3703
3704 SCR_JUMP,
3705 PADDR (start),
3706
3707},{
3708
3709
3710
3711
3712
3713 SCR_CLR (SCR_TRG),
3714 0,
3715 SCR_SEL_TBL ^ offsetof (struct dsb, select),
3716 PADDR (ungetjob),
3717
3718
3719
3720
3721 SCR_LOAD_REL (temp, 4),
3722 offsetof (struct ccb, phys.header.savep),
3723
3724
3725
3726 SCR_LOAD_REL (scr0, 4),
3727 offsetof (struct ccb, phys.header.status),
3728
3729},{
3730
3731
3732
3733
3734 SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_OUT)),
3735 0,
3736 SCR_JUMP,
3737 PADDR (select2),
3738
3739},{
3740
3741
3742
3743
3744 SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),
3745 PADDRH (msg_extended),
3746
3747
3748
3749
3750 SCR_JUMP ^ IFTRUE (MASK (0x00, 0xf0)),
3751 PADDRH (msg_received),
3752 SCR_JUMP ^ IFTRUE (MASK (0x10, 0xf0)),
3753 PADDRH (msg_received),
3754
3755
3756
3757
3758 SCR_JUMP ^ IFFALSE (MASK (0x20, 0xf0)),
3759 PADDRH (msg_weird_seen),
3760 SCR_CLR (SCR_ACK),
3761 0,
3762 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
3763 NADDR (msgin[1]),
3764 SCR_JUMP,
3765 PADDRH (msg_received),
3766
3767},{
3768 SCR_LOAD_REL (scratcha, 4),
3769 0,
3770 SCR_INT,
3771 SIR_MSG_RECEIVED,
3772
3773},{
3774 SCR_LOAD_REL (scratcha, 4),
3775 0,
3776 SCR_INT,
3777 SIR_MSG_WEIRD,
3778
3779},{
3780
3781
3782
3783
3784 SCR_CLR (SCR_ACK),
3785 0,
3786 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
3787 NADDR (msgin[1]),
3788
3789
3790
3791
3792 SCR_JUMP ^ IFTRUE (DATA (0)),
3793 PADDRH (msg_weird_seen),
3794 SCR_TO_REG (scratcha),
3795 0,
3796 SCR_REG_REG (sfbr, SCR_ADD, (256-8)),
3797 0,
3798 SCR_JUMP ^ IFTRUE (CARRYSET),
3799 PADDRH (msg_weird_seen),
3800
3801
3802
3803
3804
3805 SCR_STORE_REL (scratcha, 1),
3806 offsetof (struct dsb, smsg_ext.size),
3807 SCR_CLR (SCR_ACK),
3808 0,
3809 SCR_MOVE_TBL ^ SCR_MSG_IN,
3810 offsetof (struct dsb, smsg_ext),
3811 SCR_JUMP,
3812 PADDRH (msg_received),
3813
3814},{
3815
3816
3817
3818 SCR_INT,
3819 SIR_REJECT_TO_SEND,
3820 SCR_SET (SCR_ATN),
3821 0,
3822 SCR_JUMP,
3823 PADDR (clrack),
3824
3825},{
3826
3827
3828
3829
3830 SCR_INT,
3831 SIR_REJECT_TO_SEND,
3832 SCR_SET (SCR_ATN),
3833 0,
3834},{
3835 SCR_CLR (SCR_ACK),
3836 0,
3837 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)),
3838 PADDR (dispatch),
3839 SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
3840 NADDR (scratch),
3841 SCR_JUMP,
3842 PADDRH (msg_weird1),
3843},{
3844
3845
3846
3847 SCR_SET (SCR_ATN),
3848 0,
3849 SCR_CLR (SCR_ACK),
3850 0,
3851 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),
3852 PADDRH (nego_bad_phase),
3853
3854},{
3855
3856
3857
3858 SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,
3859 NADDR (msgout),
3860 SCR_JUMP,
3861 PADDRH (msg_out_done),
3862
3863},{
3864
3865
3866
3867 SCR_SET (SCR_ATN),
3868 0,
3869 SCR_CLR (SCR_ACK),
3870 0,
3871 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),
3872 PADDRH (nego_bad_phase),
3873
3874},{
3875
3876
3877
3878 SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,
3879 NADDR (msgout),
3880 SCR_JUMP,
3881 PADDRH (msg_out_done),
3882
3883},{
3884
3885
3886
3887 SCR_SET (SCR_ATN),
3888 0,
3889 SCR_CLR (SCR_ACK),
3890 0,
3891 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_OUT)),
3892 PADDRH (nego_bad_phase),
3893
3894},{
3895
3896
3897
3898 SCR_MOVE_ABS (8) ^ SCR_MSG_OUT,
3899 NADDR (msgout),
3900 SCR_JUMP,
3901 PADDRH (msg_out_done),
3902
3903},{
3904 SCR_INT,
3905 SIR_NEGO_PROTO,
3906 SCR_JUMP,
3907 PADDR (dispatch),
3908
3909},{
3910
3911
3912
3913 SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,
3914 NADDR (msgout),
3915
3916
3917
3918
3919 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)),
3920 PADDRH (msg_out),
3921},{
3922
3923
3924
3925 SCR_INT,
3926 SIR_MSG_OUT_DONE,
3927
3928
3929
3930 SCR_JUMP,
3931 PADDR (dispatch),
3932
3933},{
3934
3935
3936
3937 SCR_LOAD_ABS (scratcha, 4),
3938 PADDRH (zero),
3939},{
3940
3941
3942
3943
3944
3945 SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)),
3946 16,
3947 SCR_CHMOV_ABS (1) ^ SCR_DATA_OUT,
3948 NADDR (scratch),
3949 SCR_JUMP,
3950 PADDRH (data_ovrun2),
3951
3952
3953
3954
3955 SCR_FROM_REG (scntl2),
3956 0,
3957 SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)),
3958 16,
3959 SCR_REG_REG (scntl2, SCR_OR, WSR),
3960 0,
3961 SCR_JUMP,
3962 PADDRH (data_ovrun2),
3963
3964
3965
3966
3967
3968
3969 SCR_JUMPR ^ IFTRUE (WHEN (SCR_DATA_IN)),
3970 16,
3971 SCR_INT,
3972 SIR_DATA_OVERRUN,
3973 SCR_JUMP,
3974 PADDR (dispatch),
3975 SCR_CHMOV_ABS (1) ^ SCR_DATA_IN,
3976 NADDR (scratch),
3977},{
3978
3979
3980
3981
3982
3983 SCR_REG_REG (scratcha, SCR_ADD, 0x01),
3984 0,
3985 SCR_REG_REG (scratcha1, SCR_ADDC, 0),
3986 0,
3987 SCR_REG_REG (scratcha2, SCR_ADDC, 0),
3988 0,
3989
3990
3991
3992 SCR_JUMP,
3993 PADDRH (data_ovrun1),
3994
3995},{
3996 SCR_SET (SCR_ATN),
3997 0,
3998 SCR_CLR (SCR_ACK),
3999 0,
4000
4001
4002
4003
4004 SCR_REG_REG (scntl2, SCR_AND, 0x7f),
4005 0,
4006 SCR_MOVE_ABS (1) ^ SCR_MSG_OUT,
4007 NADDR (msgout),
4008 SCR_CLR (SCR_ACK|SCR_ATN),
4009 0,
4010 SCR_WAIT_DISC,
4011 0,
4012 SCR_INT,
4013 SIR_RESEL_ABORTED,
4014 SCR_JUMP,
4015 PADDR (start),
4016},{
4017
4018
4019
4020
4021
4022
4023 SCR_SET (SCR_ATN),
4024 0,
4025 SCR_JUMP,
4026 PADDR (send_ident),
4027},{
4028 SCR_CLR (SCR_ATN),
4029 0,
4030 SCR_JUMP,
4031 PADDR (select2),
4032},{
4033 SCR_SET (SCR_ATN),
4034 0,
4035 SCR_JUMP,
4036 PADDR (select2),
4037},{
4038 SCR_CHMOV_TBL ^ SCR_DATA_IN,
4039 offsetof (struct dsb, sense),
4040 SCR_CALL,
4041 PADDR (datai_done),
4042 SCR_JUMP,
4043 PADDRH (data_ovrun),
4044},{
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057 SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
4058 PADDRH(data_io_out),
4059},{
4060
4061
4062
4063
4064 SCR_LOAD_REL (scratcha, 4),
4065 offsetof (struct ccb, phys.header.lastp),
4066 SCR_STORE_REL (scratcha, 4),
4067 offsetof (struct ccb, phys.header.savep),
4068
4069
4070
4071
4072 SCR_LOAD_REL (temp, 4),
4073 offsetof (struct ccb, phys.header.savep),
4074 SCR_RETURN,
4075 0,
4076},{
4077
4078
4079
4080 SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
4081 0,
4082 SCR_LOAD_REL (scratcha, 4),
4083 offsetof (struct ccb, phys.header.wlastp),
4084 SCR_STORE_REL (scratcha, 4),
4085 offsetof (struct ccb, phys.header.lastp),
4086 SCR_LOAD_REL (scratcha, 4),
4087 offsetof (struct ccb, phys.header.wgoalp),
4088 SCR_STORE_REL (scratcha, 4),
4089 offsetof (struct ccb, phys.header.goalp),
4090 SCR_JUMP,
4091 PADDRH(data_io_com),
4092
4093},{
4094
4095
4096
4097
4098
4099 SCR_INT,
4100 SIR_RESEL_BAD_LUN,
4101 SCR_JUMP,
4102 PADDRH (abort_resel),
4103},{
4104
4105
4106
4107
4108
4109 SCR_INT,
4110 SIR_RESEL_BAD_I_T_L,
4111 SCR_JUMP,
4112 PADDRH (abort_resel),
4113},{
4114
4115
4116
4117
4118
4119 SCR_INT,
4120 SIR_RESEL_BAD_I_T_L_Q,
4121 SCR_JUMP,
4122 PADDRH (abort_resel),
4123},{
4124
4125
4126
4127
4128
4129
4130 SCR_LOAD_ABS (scratcha, 4),
4131 PADDRH (startpos),
4132 SCR_INT ^ IFFALSE (DATA (S_COND_MET)),
4133 SIR_BAD_STATUS,
4134 SCR_RETURN,
4135 0,
4136
4137},{
4138
4139
4140
4141
4142
4143 SCR_FROM_REG(HF_REG),
4144 0,
4145 SCR_JUMPR ^ IFTRUE (MASK (HF_PM_TO_C, HF_PM_TO_C)),
4146 16,
4147 SCR_REG_REG (ccntl0, SCR_OR, ENPMJ),
4148 0,
4149 SCR_RETURN,
4150 0,
4151 SCR_REG_REG (ccntl0, SCR_AND, (~ENPMJ)),
4152 0,
4153 SCR_RETURN,
4154 0,
4155
4156},{
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168 SCR_FROM_REG (HF_REG),
4169 0,
4170
4171
4172
4173
4174
4175 SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED))),
4176 PADDRH (pm_handle1),
4177
4178
4179
4180
4181
4182 SCR_JUMPR ^ IFFALSE (MASK (HF_DP_SAVED, HF_DP_SAVED)),
4183 8,
4184 SCR_REG_REG (sfbr, SCR_XOR, HF_ACT_PM),
4185 0,
4186
4187
4188
4189
4190
4191
4192
4193 SCR_JUMP ^ IFTRUE (MASK (0, (HF_IN_PM0 | HF_IN_PM1))),
4194 PADDRH (pm_handle1),
4195 SCR_JUMPR ^ IFFALSE (MASK (HF_IN_PM0, HF_IN_PM0)),
4196 16,
4197 SCR_LOAD_REL (ia, 4),
4198 offsetof(struct ccb, phys.pm0.ret),
4199 SCR_JUMP,
4200 PADDRH (pm_save),
4201 SCR_LOAD_REL (ia, 4),
4202 offsetof(struct ccb, phys.pm1.ret),
4203 SCR_JUMP,
4204 PADDRH (pm_save),
4205},{
4206
4207
4208
4209
4210
4211 SCR_REG_REG (ia, SCR_ADD, 8),
4212 0,
4213 SCR_REG_REG (ia1, SCR_ADDC, 0),
4214 0,
4215},{
4216
4217
4218
4219
4220
4221 SCR_SFBR_REG (HF_REG, SCR_AND, (~(HF_IN_PM0|HF_IN_PM1|HF_DP_SAVED))),
4222 0,
4223
4224
4225
4226 SCR_JUMP ^ IFTRUE (MASK (HF_ACT_PM, HF_ACT_PM)),
4227 PADDRH (pm1_save),
4228},{
4229 SCR_STORE_REL (ia, 4),
4230 offsetof(struct ccb, phys.pm0.ret),
4231
4232
4233
4234
4235
4236 SCR_FROM_REG (scntl2),
4237 0,
4238 SCR_CALL ^ IFTRUE (MASK (WSR, WSR)),
4239 PADDRH (pm_wsr_handle),
4240
4241
4242
4243
4244 SCR_STORE_REL (rbc, 4),
4245 offsetof(struct ccb, phys.pm0.sg.size),
4246 SCR_STORE_REL (ua, 4),
4247 offsetof(struct ccb, phys.pm0.sg.addr),
4248
4249
4250
4251 SCR_LOAD_ABS (temp, 4),
4252 PADDRH (pm0_data_addr),
4253 SCR_JUMP,
4254 PADDR (dispatch),
4255},{
4256 SCR_STORE_REL (ia, 4),
4257 offsetof(struct ccb, phys.pm1.ret),
4258
4259
4260
4261
4262
4263 SCR_FROM_REG (scntl2),
4264 0,
4265 SCR_CALL ^ IFTRUE (MASK (WSR, WSR)),
4266 PADDRH (pm_wsr_handle),
4267
4268
4269
4270
4271 SCR_STORE_REL (rbc, 4),
4272 offsetof(struct ccb, phys.pm1.sg.size),
4273 SCR_STORE_REL (ua, 4),
4274 offsetof(struct ccb, phys.pm1.sg.addr),
4275
4276
4277
4278 SCR_LOAD_ABS (temp, 4),
4279 PADDRH (pm1_data_addr),
4280 SCR_JUMP,
4281 PADDR (dispatch),
4282},{
4283
4284
4285
4286
4287
4288
4289#ifdef SYM_DEBUG_PM_WITH_WSR
4290
4291
4292
4293 SCR_INT,
4294 SIR_PM_WITH_WSR,
4295#endif
4296
4297
4298
4299
4300
4301
4302
4303 SCR_STORE_REL (ua, 4),
4304 offsetof (struct ccb, phys.wresid.addr),
4305
4306
4307
4308 SCR_REG_REG (ua, SCR_ADD, 1),
4309 0,
4310 SCR_REG_REG (ua1, SCR_ADDC, 0),
4311 0,
4312 SCR_REG_REG (ua2, SCR_ADDC, 0),
4313 0,
4314 SCR_REG_REG (ua3, SCR_ADDC, 0),
4315 0,
4316
4317
4318
4319
4320
4321 SCR_LOAD_ABS (scratcha, 4),
4322 PADDRH (zero),
4323 SCR_REG_REG (scratcha, SCR_OR, 1),
4324 0,
4325 SCR_FROM_REG (rbc3),
4326 0,
4327 SCR_TO_REG (scratcha3),
4328 0,
4329
4330
4331
4332 SCR_STORE_REL (scratcha, 4),
4333 offsetof (struct ccb, phys.wresid.size),
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343 SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_IN)),
4344 0,
4345
4346
4347
4348 SCR_CHMOV_TBL ^ SCR_DATA_IN,
4349 offsetof (struct ccb, phys.wresid),
4350
4351
4352
4353
4354
4355 SCR_FROM_REG (rbc),
4356 0,
4357 SCR_RETURN ^ IFFALSE (DATA (0)),
4358 0,
4359 SCR_FROM_REG (rbc1),
4360 0,
4361 SCR_RETURN ^ IFFALSE (DATA (0)),
4362 0,
4363 SCR_FROM_REG (rbc2),
4364 0,
4365 SCR_RETURN ^ IFFALSE (DATA (0)),
4366 0,
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376 SCR_STORE_ABS (ia, 4),
4377 PADDRH (scratch),
4378 SCR_LOAD_ABS (temp, 4),
4379 PADDRH (scratch),
4380 SCR_JUMP,
4381 PADDR (dispatch),
4382},{
4383
4384
4385
4386
4387 SCR_CHMOV_TBL ^ SCR_DATA_IN,
4388 offsetof (struct ccb, phys.wresid),
4389 SCR_JUMP,
4390 PADDR (dispatch),
4391},{
4392 SCR_DATA_ZERO,
4393},{
4394 SCR_DATA_ZERO,
4395},{
4396 SCR_DATA_ZERO,
4397},{
4398 SCR_DATA_ZERO,
4399},{
4400 SCR_DATA_ZERO,
4401},{
4402 SCR_DATA_ZERO,
4403},{
4404 SCR_DATA_ZERO,
4405},{
4406 SCR_DATA_ZERO,
4407},{
4408 SCR_DATA_ZERO,
4409},{
4410 SCR_DATA_ZERO,
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
4421
4422},{
4423
4424
4425
4426
4427 SCR_COPY (sizeof (struct script)),
4428},{
4429 0,
4430 PADDR (start),
4431 SCR_JUMP,
4432 PADDR (init),
4433
4434},{
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445 SCR_LOAD_REL (mmws, 4),
4446 offsetof (struct ncb, scr_ram_seg),
4447 SCR_COPY (sizeof(struct script)),
4448},{
4449 0,
4450 PADDR (start),
4451 SCR_COPY (sizeof(struct scripth)),
4452},{
4453 0,
4454 PADDRH (start64),
4455 SCR_LOAD_REL (mmrs, 4),
4456 offsetof (struct ncb, scr_ram_seg),
4457 SCR_JUMP64,
4458 PADDRH (start64),
4459},{
4460 0,
4461
4462#endif
4463
4464},{
4465
4466
4467
4468 SCR_LOAD_REL (scratcha, 4),
4469 offsetof(struct ncb, ncr_cache),
4470 SCR_STORE_REL (temp, 4),
4471 offsetof(struct ncb, ncr_cache),
4472 SCR_LOAD_REL (temp, 4),
4473 offsetof(struct ncb, ncr_cache),
4474},{
4475
4476
4477
4478 SCR_INT,
4479 99,
4480}
4481};
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492void __init ncr_script_fill (struct script * scr, struct scripth * scrh)
4493{
4494 int i;
4495 ncrcmd *p;
4496
4497 p = scr->data_in;
4498 for (i=0; i<MAX_SCATTER; i++) {
4499 *p++ =SCR_CHMOV_TBL ^ SCR_DATA_IN;
4500 *p++ =offsetof (struct dsb, data[i]);
4501 };
4502
4503 assert ((u_long)p == (u_long)&scr->data_in + sizeof (scr->data_in));
4504
4505 p = scr->data_out;
4506
4507 for (i=0; i<MAX_SCATTER; i++) {
4508 *p++ =SCR_CHMOV_TBL ^ SCR_DATA_OUT;
4509 *p++ =offsetof (struct dsb, data[i]);
4510 };
4511
4512 assert ((u_long)p == (u_long)&scr->data_out + sizeof (scr->data_out));
4513}
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524static void __init
4525ncr_script_copy_and_bind (ncb_p np,ncrcmd *src,ncrcmd *dst,int len)
4526{
4527 ncrcmd opcode, new, old, tmp1, tmp2;
4528 ncrcmd *start, *end;
4529 int relocs;
4530 int opchanged = 0;
4531
4532 start = src;
4533 end = src + len/4;
4534
4535 while (src < end) {
4536
4537 opcode = *src++;
4538 *dst++ = cpu_to_scr(opcode);
4539
4540
4541
4542
4543
4544
4545
4546
4547 if (opcode == 0) {
4548 printk (KERN_INFO "%s: ERROR0 IN SCRIPT at %d.\n",
4549 ncr_name(np), (int) (src-start-1));
4550 MDELAY (10000);
4551 continue;
4552 };
4553
4554
4555
4556
4557
4558 if (opcode == SCR_DATA_ZERO) {
4559 dst[-1] = 0;
4560 continue;
4561 }
4562
4563 if (DEBUG_FLAGS & DEBUG_SCRIPT)
4564 printk (KERN_INFO "%p: <%x>\n",
4565 (src-1), (unsigned)opcode);
4566
4567
4568
4569
4570 switch (opcode >> 28) {
4571
4572 case 0xf:
4573
4574
4575
4576 relocs = 0;
4577 break;
4578 case 0xe:
4579
4580
4581
4582 relocs = 1;
4583 break;
4584 case 0xc:
4585
4586
4587
4588 relocs = 2;
4589 tmp1 = src[0];
4590 tmp2 = src[1];
4591#ifdef RELOC_KVAR
4592 if ((tmp1 & RELOC_MASK) == RELOC_KVAR)
4593 tmp1 = 0;
4594 if ((tmp2 & RELOC_MASK) == RELOC_KVAR)
4595 tmp2 = 0;
4596#endif
4597 if ((tmp1 ^ tmp2) & 3) {
4598 printk (KERN_ERR"%s: ERROR1 IN SCRIPT at %d.\n",
4599 ncr_name(np), (int) (src-start-1));
4600 MDELAY (1000);
4601 }
4602
4603
4604
4605
4606 if ((opcode & SCR_NO_FLUSH) &&
4607 !(np->features & FE_PFEN)) {
4608 dst[-1] = cpu_to_scr(opcode & ~SCR_NO_FLUSH);
4609 ++opchanged;
4610 }
4611 break;
4612
4613 case 0x0:
4614
4615
4616
4617 if (!(np->features & FE_WIDE))
4618 dst[-1] = cpu_to_scr(opcode | OPC_MOVE);
4619 relocs = 1;
4620 break;
4621
4622 case 0x1:
4623
4624
4625
4626 if (!(np->features & FE_WIDE))
4627 dst[-1] = cpu_to_scr(opcode | OPC_MOVE);
4628 relocs = 0;
4629 break;
4630
4631 case 0x8:
4632
4633
4634
4635
4636 if (opcode & 0x00800000)
4637 relocs = 0;
4638 else if ((opcode & 0xf8400000) == 0x80400000)
4639 relocs = 2;
4640 else
4641 relocs = 1;
4642 break;
4643
4644 case 0x4:
4645 case 0x5:
4646 case 0x6:
4647 case 0x7:
4648 relocs = 1;
4649 break;
4650
4651 default:
4652 relocs = 0;
4653 break;
4654 };
4655
4656 if (!relocs) {
4657 *dst++ = cpu_to_scr(*src++);
4658 continue;
4659 }
4660 while (relocs--) {
4661 old = *src++;
4662
4663 switch (old & RELOC_MASK) {
4664 case RELOC_REGISTER:
4665 new = (old & ~RELOC_MASK) + np->base_ba;
4666 break;
4667 case RELOC_LABEL:
4668 new = (old & ~RELOC_MASK) + np->p_script;
4669 break;
4670 case RELOC_LABELH:
4671 new = (old & ~RELOC_MASK) + np->p_scripth;
4672 break;
4673 case RELOC_SOFTC:
4674 new = (old & ~RELOC_MASK) + np->p_ncb;
4675 break;
4676#ifdef RELOC_KVAR
4677 case RELOC_KVAR:
4678 new=0;
4679 if (((old & ~RELOC_MASK) < SCRIPT_KVAR_FIRST) ||
4680 ((old & ~RELOC_MASK) > SCRIPT_KVAR_LAST))
4681 panic("ncr KVAR out of range");
4682 new = vtobus(script_kvars[old & ~RELOC_MASK]);
4683#endif
4684 break;
4685 case 0:
4686
4687 if (old == 0) {
4688 new = old;
4689 break;
4690 }
4691
4692 default:
4693 new = 0;
4694 panic("ncr_script_copy_and_bind: "
4695 "weird relocation %x\n", old);
4696 break;
4697 }
4698
4699 *dst++ = cpu_to_scr(new);
4700 }
4701 };
4702}
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717struct host_data {
4718 struct ncb *ncb;
4719};
4720
4721
4722
4723
4724
4725
4726static void PRINT_TARGET(ncb_p np, int target)
4727{
4728 printk(KERN_INFO "%s-<%d,*>: ", ncr_name(np), target);
4729}
4730
4731static void PRINT_LUN(ncb_p np, int target, int lun)
4732{
4733 printk(KERN_INFO "%s-<%d,%d>: ", ncr_name(np), target, lun);
4734}
4735
4736static void PRINT_ADDR(Scsi_Cmnd *cmd)
4737{
4738 struct host_data *host_data = (struct host_data *) cmd->host->hostdata;
4739 PRINT_LUN(host_data->ncb, cmd->target, cmd->lun);
4740}
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751#define _5M 5000000
4752static u_long div_10M[] =
4753 {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M};
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780#define burst_length(bc) (!(bc))? 0 : 1 << (bc)
4781
4782
4783
4784
4785#define burst_code(dmode, ctest4, ctest5) \
4786 (ctest4) & 0x80? 0 : (((dmode) & 0xc0) >> 6) + ((ctest5) & 0x04) + 1
4787
4788
4789
4790
4791static inline void ncr_init_burst(ncb_p np, u_char bc)
4792{
4793 np->rv_ctest4 &= ~0x80;
4794 np->rv_dmode &= ~(0x3 << 6);
4795 np->rv_ctest5 &= ~0x4;
4796
4797 if (!bc) {
4798 np->rv_ctest4 |= 0x80;
4799 }
4800 else {
4801 --bc;
4802 np->rv_dmode |= ((bc & 0x3) << 6);
4803 np->rv_ctest5 |= (bc & 0x4);
4804 }
4805}
4806
4807#ifdef SCSI_NCR_NVRAM_SUPPORT
4808
4809
4810
4811
4812
4813static void __init
4814ncr_Symbios_setup_target(ncb_p np, int target, Symbios_nvram *nvram)
4815{
4816 tcb_p tp = &np->target[target];
4817 Symbios_target *tn = &nvram->target[target];
4818
4819 tp->usrsync = tn->sync_period ? (tn->sync_period + 3) / 4 : 255;
4820 tp->usrwide = tn->bus_width == 0x10 ? 1 : 0;
4821 tp->usrtags =
4822 (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? MAX_TAGS : 0;
4823
4824 if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
4825 tp->usrflag |= UF_NODISC;
4826 if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
4827 tp->usrflag |= UF_NOSCAN;
4828}
4829
4830
4831
4832
4833
4834static void __init
4835ncr_Tekram_setup_target(ncb_p np, int target, Tekram_nvram *nvram)
4836{
4837 tcb_p tp = &np->target[target];
4838 struct Tekram_target *tn = &nvram->target[target];
4839 int i;
4840
4841 if (tn->flags & TEKRAM_SYNC_NEGO) {
4842 i = tn->sync_index & 0xf;
4843 tp->usrsync = Tekram_sync[i];
4844 }
4845
4846 tp->usrwide = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0;
4847
4848 if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
4849 tp->usrtags = 2 << nvram->max_tags_index;
4850 }
4851
4852 if (!(tn->flags & TEKRAM_DISCONNECT_ENABLE))
4853 tp->usrflag = UF_NODISC;
4854
4855
4856 if (!(tn->flags & TEKRAM_PARITY_CHECK))
4857 np->rv_scntl0 &= ~0x0a;
4858}
4859#endif
4860
4861
4862
4863
4864
4865static void __init ncr_save_initial_setting(ncb_p np)
4866{
4867 np->sv_scntl0 = INB(nc_scntl0) & 0x0a;
4868 np->sv_dmode = INB(nc_dmode) & 0xce;
4869 np->sv_dcntl = INB(nc_dcntl) & 0xa8;
4870 np->sv_ctest3 = INB(nc_ctest3) & 0x01;
4871 np->sv_ctest4 = INB(nc_ctest4) & 0x80;
4872 np->sv_gpcntl = INB(nc_gpcntl);
4873 np->sv_stest2 = INB(nc_stest2) & 0x20;
4874 np->sv_stest4 = INB(nc_stest4);
4875 np->sv_stest1 = INB(nc_stest1);
4876
4877 np->sv_scntl3 = INB(nc_scntl3) & 0x07;
4878
4879 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
4880 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66) ){
4881
4882
4883
4884
4885 np->sv_ctest5 = INB(nc_ctest5) & 0x04 ;
4886 np->sv_scntl4 = INB(nc_scntl4);
4887 }
4888 else {
4889 np->sv_ctest5 = INB(nc_ctest5) & 0x24 ;
4890 np->sv_scntl4 = 0;
4891 }
4892}
4893
4894
4895
4896
4897
4898static int __init ncr_prepare_setting(ncb_p np, ncr_nvram *nvram)
4899{
4900 u_char burst_max;
4901 u_long period;
4902 int i;
4903
4904
4905
4906
4907
4908 np->maxwide = (np->features & FE_WIDE)? 1 : 0;
4909
4910
4911
4912
4913 if (np->features & (FE_ULTRA3 | FE_ULTRA2))
4914 np->clock_khz = 160000;
4915 else if (np->features & FE_ULTRA)
4916 np->clock_khz = 80000;
4917 else
4918 np->clock_khz = 40000;
4919
4920
4921
4922
4923 if (np->features & FE_QUAD)
4924 np->multiplier = 4;
4925 else if (np->features & FE_DBLR)
4926 np->multiplier = 2;
4927 else
4928 np->multiplier = 1;
4929
4930
4931
4932
4933
4934 if (np->features & FE_VARCLK)
4935 ncr_getclock(np, np->multiplier);
4936
4937
4938
4939
4940
4941
4942
4943
4944 if ( (np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
4945 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
4946
4947 np->rv_scntl3 = 0;
4948 }
4949 else
4950 {
4951 i = np->clock_divn - 1;
4952 while (--i >= 0) {
4953 if (10ul * SCSI_NCR_MIN_ASYNC * np->clock_khz
4954 > div_10M[i]) {
4955 ++i;
4956 break;
4957 }
4958 }
4959 np->rv_scntl3 = i+1;
4960 }
4961
4962
4963
4964
4965
4966
4967 np->rv_scntl4 = np->sv_scntl4;
4968
4969
4970
4971
4972
4973
4974 period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
4975 if (period <= 250) np->minsync = 10;
4976 else if (period <= 303) np->minsync = 11;
4977 else if (period <= 500) np->minsync = 12;
4978 else np->minsync = (period + 40 - 1) / 40;
4979
4980
4981
4982
4983
4984
4985
4986
4987 if (np->features & FE_ULTRA3) {
4988 if (np->minsync == 10)
4989 np->minsync = 9;
4990 np->maxoffs_st = 31;
4991 }
4992 else
4993 np->maxoffs_st = np->maxoffs;
4994
4995
4996
4997
4998
4999
5000
5001
5002 if (np->minsync < 25 && !(np->features & (FE_ULTRA|FE_ULTRA2|FE_ULTRA3)))
5003 np->minsync = 25;
5004 else if (np->minsync < 12 && (np->features & FE_ULTRA))
5005 np->minsync = 12;
5006 else if (np->minsync < 10 && (np->features & FE_ULTRA2))
5007 np->minsync = 10;
5008 else if (np->minsync < 9 && (np->features & FE_ULTRA3))
5009 np->minsync = 9;
5010
5011
5012
5013
5014
5015 period = (11 * div_10M[np->clock_divn - 1]) / (4 * np->clock_khz);
5016 np->maxsync = period > 2540 ? 254 : period / 10;
5017
5018
5019
5020
5021 if (np->features & FE_DAC) {
5022 if (np->features & FE_DAC_IN_USE)
5023 np->rv_ccntl1 |= (XTIMOD | EXTIBMV);
5024 else
5025 np->rv_ccntl1 |= (DDAC);
5026 }
5027
5028
5029
5030
5031 if (np->features & FE_NOPM)
5032 np->rv_ccntl0 |= (ENPMJ);
5033
5034
5035
5036
5037#if defined SCSI_NCR_TRUST_BIOS_SETTING
5038 np->rv_scntl0 = np->sv_scntl0;
5039 np->rv_dmode = np->sv_dmode;
5040 np->rv_dcntl = np->sv_dcntl;
5041 np->rv_ctest3 = np->sv_ctest3;
5042 np->rv_ctest4 = np->sv_ctest4;
5043 np->rv_ctest5 = np->sv_ctest5;
5044 burst_max = burst_code(np->sv_dmode, np->sv_ctest4, np->sv_ctest5);
5045#else
5046
5047
5048
5049
5050 burst_max = driver_setup.burst_max;
5051 if (burst_max == 255)
5052 burst_max = burst_code(np->sv_dmode, np->sv_ctest4, np->sv_ctest5);
5053 if (burst_max > 7)
5054 burst_max = 7;
5055 if (burst_max > np->maxburst)
5056 burst_max = np->maxburst;
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066 if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 &&
5067 np->revision_id >= 0x10 && np->revision_id <= 0x11) ||
5068 (np->device_id == PCI_DEVICE_ID_NCR_53C860 &&
5069 np->revision_id <= 0x1))
5070 np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP);
5071
5072
5073
5074
5075
5076 if ( ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) && (np->revision_id < 0x02) )
5077 || (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 ) )
5078 np->rv_ccntl1 |= 0x10;
5079
5080
5081
5082
5083
5084
5085
5086 if (np->features & FE_ERL)
5087 np->rv_dmode |= ERL;
5088 if (np->features & FE_BOF)
5089 np->rv_dmode |= BOF;
5090 if (np->features & FE_ERMP)
5091 np->rv_dmode |= ERMP;
5092#if 1
5093 if ((np->features & FE_PFEN) && !np->base2_ba)
5094#else
5095 if (np->features & FE_PFEN)
5096#endif
5097 np->rv_dcntl |= PFEN;
5098 if (np->features & FE_CLSE)
5099 np->rv_dcntl |= CLSE;
5100 if (np->features & FE_WRIE)
5101 np->rv_ctest3 |= WRIE;
5102
5103
5104 if ( (np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
5105 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66) &&
5106 (np->features & FE_DFS))
5107 np->rv_ctest5 |= DFS;
5108
5109
5110
5111
5112
5113 if (driver_setup.master_parity)
5114 np->rv_ctest4 |= MPEE;
5115 if (driver_setup.scsi_parity)
5116 np->rv_scntl0 |= 0x0a;
5117
5118#ifdef SCSI_NCR_NVRAM_SUPPORT
5119
5120
5121
5122 if (nvram) {
5123 switch(nvram->type) {
5124 case SCSI_NCR_TEKRAM_NVRAM:
5125 np->myaddr = nvram->data.Tekram.host_id & 0x0f;
5126 break;
5127 case SCSI_NCR_SYMBIOS_NVRAM:
5128 if (!(nvram->data.Symbios.flags & SYMBIOS_PARITY_ENABLE))
5129 np->rv_scntl0 &= ~0x0a;
5130 np->myaddr = nvram->data.Symbios.host_id & 0x0f;
5131 if (nvram->data.Symbios.flags & SYMBIOS_VERBOSE_MSGS)
5132 np->verbose += 1;
5133 break;
5134 }
5135 }
5136#endif
5137
5138
5139
5140 if (np->myaddr == 255) {
5141 np->myaddr = INB(nc_scid) & 0x07;
5142 if (!np->myaddr)
5143 np->myaddr = SCSI_NCR_MYADDR;
5144 }
5145
5146#endif
5147
5148
5149
5150
5151 ncr_init_burst(np, burst_max);
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163 np->scsi_mode = SMODE_SE;
5164 if (np->features & (FE_ULTRA2 | FE_ULTRA3))
5165 np->scsi_mode = (np->sv_stest4 & SMODE);
5166 else if (np->features & FE_DIFF) {
5167 switch(driver_setup.diff_support) {
5168 case 4:
5169 if (np->sv_scntl3) {
5170 if (np->sv_stest2 & 0x20)
5171 np->scsi_mode = SMODE_HVD;
5172 break;
5173 }
5174 case 3:
5175 if (nvram && nvram->type != SCSI_NCR_SYMBIOS_NVRAM)
5176 break;
5177 if (INB(nc_gpreg) & 0x08)
5178 break;
5179 case 2:
5180 np->scsi_mode = SMODE_HVD;
5181 case 1:
5182 if (np->sv_stest2 & 0x20)
5183 np->scsi_mode = SMODE_HVD;
5184 break;
5185 default:
5186 break;
5187 }
5188 }
5189 if (np->scsi_mode == SMODE_HVD)
5190 np->rv_stest2 |= 0x20;
5191
5192
5193
5194
5195
5196
5197
5198
5199 if ((driver_setup.led_pin ||
5200 (nvram && nvram->type == SCSI_NCR_SYMBIOS_NVRAM)) &&
5201 !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01))
5202 np->features |= FE_LED0;
5203
5204
5205
5206
5207 switch(driver_setup.irqm & 3) {
5208 case 2:
5209 np->rv_dcntl |= IRQM;
5210 break;
5211 case 1:
5212 np->rv_dcntl |= (np->sv_dcntl & IRQM);
5213 break;
5214 default:
5215 break;
5216 }
5217
5218
5219
5220
5221
5222
5223
5224 for (i = 0 ; i < MAX_TARGET ; i++) {
5225 tcb_p tp = &np->target[i];
5226
5227 tp->usrsync = 255;
5228#ifdef SCSI_NCR_NVRAM_SUPPORT
5229 if (nvram) {
5230 switch(nvram->type) {
5231 case SCSI_NCR_TEKRAM_NVRAM:
5232 ncr_Tekram_setup_target(np, i, &nvram->data.Tekram);
5233 break;
5234 case SCSI_NCR_SYMBIOS_NVRAM:
5235 ncr_Symbios_setup_target(np, i, &nvram->data.Symbios);
5236 break;
5237 }
5238 if (driver_setup.use_nvram & 0x2)
5239 tp->usrsync = driver_setup.default_sync;
5240 if (driver_setup.use_nvram & 0x4)
5241 tp->usrwide = driver_setup.max_wide;
5242 if (driver_setup.use_nvram & 0x8)
5243 tp->usrflag &= ~UF_NOSCAN;
5244 }
5245 else {
5246#else
5247 if (1) {
5248#endif
5249 tp->usrsync = driver_setup.default_sync;
5250 tp->usrwide = driver_setup.max_wide;
5251 tp->usrtags = MAX_TAGS;
5252 if (!driver_setup.disconnection)
5253 np->target[i].usrflag = UF_NODISC;
5254 }
5255 }
5256
5257
5258
5259
5260
5261 i = nvram ? nvram->type : 0;
5262 printk(KERN_INFO "%s: %sID %d, Fast-%d%s%s\n", ncr_name(np),
5263 i == SCSI_NCR_SYMBIOS_NVRAM ? "Symbios format NVRAM, " :
5264 (i == SCSI_NCR_TEKRAM_NVRAM ? "Tekram format NVRAM, " : ""),
5265 np->myaddr,
5266 np->minsync < 10 ? 80 :
5267 (np->minsync < 12 ? 40 : (np->minsync < 25 ? 20 : 10) ),
5268 (np->rv_scntl0 & 0xa) ? ", Parity Checking" : ", NO Parity",
5269 (np->rv_stest2 & 0x20) ? ", Differential" : "");
5270
5271 if (bootverbose > 1) {
5272 printk (KERN_INFO "%s: initial SCNTL3/DMODE/DCNTL/CTEST3/4/5 = "
5273 "(hex) %02x/%02x/%02x/%02x/%02x/%02x\n",
5274 ncr_name(np), np->sv_scntl3, np->sv_dmode, np->sv_dcntl,
5275 np->sv_ctest3, np->sv_ctest4, np->sv_ctest5);
5276
5277 printk (KERN_INFO "%s: final SCNTL3/DMODE/DCNTL/CTEST3/4/5 = "
5278 "(hex) %02x/%02x/%02x/%02x/%02x/%02x\n",
5279 ncr_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
5280 np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
5281 }
5282
5283 if (bootverbose && np->base2_ba)
5284 printk (KERN_INFO "%s: on-chip RAM at 0x%lx\n",
5285 ncr_name(np), np->base2_ba);
5286
5287 return 0;
5288}
5289
5290
5291#ifdef SCSI_NCR_DEBUG_NVRAM
5292
5293void __init ncr_display_Symbios_nvram(ncb_p np, Symbios_nvram *nvram)
5294{
5295 int i;
5296
5297
5298 printk(KERN_DEBUG "%s: HOST ID=%d%s%s%s%s%s\n",
5299 ncr_name(np), nvram->host_id & 0x0f,
5300 (nvram->flags & SYMBIOS_SCAM_ENABLE) ? " SCAM" :"",
5301 (nvram->flags & SYMBIOS_PARITY_ENABLE) ? " PARITY" :"",
5302 (nvram->flags & SYMBIOS_VERBOSE_MSGS) ? " VERBOSE" :"",
5303 (nvram->flags & SYMBIOS_CHS_MAPPING) ? " CHS_ALT" :"",
5304 (nvram->flags1 & SYMBIOS_SCAN_HI_LO) ? " HI_LO" :"");
5305
5306
5307 for (i = 0 ; i < 15 ; i++) {
5308 struct Symbios_target *tn = &nvram->target[i];
5309 printk(KERN_DEBUG "%s-%d:%s%s%s%s WIDTH=%d SYNC=%d TMO=%d\n",
5310 ncr_name(np), i,
5311 (tn->flags & SYMBIOS_DISCONNECT_ENABLE) ? " DISC" : "",
5312 (tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME) ? " SCAN_BOOT" : "",
5313 (tn->flags & SYMBIOS_SCAN_LUNS) ? " SCAN_LUNS" : "",
5314 (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? " TCQ" : "",
5315 tn->bus_width,
5316 tn->sync_period / 4,
5317 tn->timeout);
5318 }
5319}
5320
5321static u_char Tekram_boot_delay[7] __initdata = {3, 5, 10, 20, 30, 60, 120};
5322
5323void __init ncr_display_Tekram_nvram(ncb_p np, Tekram_nvram *nvram)
5324{
5325 int i, tags, boot_delay;
5326 char *rem;
5327
5328
5329 tags = 2 << nvram->max_tags_index;
5330 boot_delay = 0;
5331 if (nvram->boot_delay_index < 6)
5332 boot_delay = Tekram_boot_delay[nvram->boot_delay_index];
5333 switch((nvram->flags & TEKRAM_REMOVABLE_FLAGS) >> 6) {
5334 default:
5335 case 0: rem = ""; break;
5336 case 1: rem = " REMOVABLE=boot device"; break;
5337 case 2: rem = " REMOVABLE=all"; break;
5338 }
5339
5340 printk(KERN_DEBUG
5341 "%s: HOST ID=%d%s%s%s%s%s%s%s%s%s BOOT DELAY=%d tags=%d\n",
5342 ncr_name(np), nvram->host_id & 0x0f,
5343 (nvram->flags1 & SYMBIOS_SCAM_ENABLE) ? " SCAM" :"",
5344 (nvram->flags & TEKRAM_MORE_THAN_2_DRIVES) ? " >2DRIVES" :"",
5345 (nvram->flags & TEKRAM_DRIVES_SUP_1GB) ? " >1GB" :"",
5346 (nvram->flags & TEKRAM_RESET_ON_POWER_ON) ? " RESET" :"",
5347 (nvram->flags & TEKRAM_ACTIVE_NEGATION) ? " ACT_NEG" :"",
5348 (nvram->flags & TEKRAM_IMMEDIATE_SEEK) ? " IMM_SEEK" :"",
5349 (nvram->flags & TEKRAM_SCAN_LUNS) ? " SCAN_LUNS" :"",
5350 (nvram->flags1 & TEKRAM_F2_F6_ENABLED) ? " F2_F6" :"",
5351 rem, boot_delay, tags);
5352
5353
5354 for (i = 0; i <= 15; i++) {
5355 int sync, j;
5356 struct Tekram_target *tn = &nvram->target[i];
5357 j = tn->sync_index & 0xf;
5358 sync = Tekram_sync[j];
5359 printk(KERN_DEBUG "%s-%d:%s%s%s%s%s%s PERIOD=%d\n",
5360 ncr_name(np), i,
5361 (tn->flags & TEKRAM_PARITY_CHECK) ? " PARITY" : "",
5362 (tn->flags & TEKRAM_SYNC_NEGO) ? " SYNC" : "",
5363 (tn->flags & TEKRAM_DISCONNECT_ENABLE) ? " DISC" : "",
5364 (tn->flags & TEKRAM_START_CMD) ? " START" : "",
5365 (tn->flags & TEKRAM_TAGGED_COMMANDS) ? " TCQ" : "",
5366 (tn->flags & TEKRAM_WIDE_NEGO) ? " WIDE" : "",
5367 sync);
5368 }
5369}
5370#endif
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382static int __init
5383ncr_attach (Scsi_Host_Template *tpnt, int unit, ncr_device *device)
5384{
5385 struct host_data *host_data;
5386 ncb_p np = 0;
5387 struct Scsi_Host *instance = 0;
5388 u_long flags = 0;
5389 ncr_nvram *nvram = device->nvram;
5390 int i;
5391
5392 printk(KERN_INFO NAME53C "%s-%d: rev 0x%x on pci bus %d device %d function %d "
5393#ifdef __sparc__
5394 "irq %s\n",
5395#else
5396 "irq %d\n",
5397#endif
5398 device->chip.name, unit, device->chip.revision_id,
5399 device->slot.bus, (device->slot.device_fn & 0xf8) >> 3,
5400 device->slot.device_fn & 7,
5401#ifdef __sparc__
5402 __irq_itoa(device->slot.irq));
5403#else
5404 device->slot.irq);
5405#endif
5406
5407
5408
5409
5410 if (!(instance = scsi_register(tpnt, sizeof(*host_data))))
5411 goto attach_error;
5412 host_data = (struct host_data *) instance->hostdata;
5413
5414
5415
5416
5417 np = __m_calloc_dma(device->pdev, sizeof(struct ncb), "NCB");
5418 if (!np)
5419 goto attach_error;
5420 NCR_INIT_LOCK_NCB(np);
5421 np->pdev = device->pdev;
5422 np->p_ncb = vtobus(np);
5423 host_data->ncb = np;
5424
5425
5426
5427
5428 strncpy(np->chip_name, device->chip.name, sizeof(np->chip_name) - 1);
5429 np->unit = unit;
5430 np->verbose = driver_setup.verbose;
5431 sprintf(np->inst_name, NAME53C "%s-%d", np->chip_name, np->unit);
5432 np->device_id = device->chip.device_id;
5433 np->revision_id = device->chip.revision_id;
5434 np->bus = device->slot.bus;
5435 np->device_fn = device->slot.device_fn;
5436 np->features = device->chip.features;
5437 np->clock_divn = device->chip.nr_divisor;
5438 np->maxoffs = device->chip.offset_max;
5439 np->maxburst = device->chip.burst_max;
5440 np->myaddr = device->host_id;
5441
5442
5443
5444
5445 np->squeue = (ncrcmd *)
5446 m_calloc_dma(sizeof(ncrcmd)*(MAX_START*2), "SQUEUE");
5447 if (!np->squeue)
5448 goto attach_error;
5449 np->p_squeue = vtobus(np->squeue);
5450
5451
5452
5453
5454 np->dqueue = (ncrcmd *)
5455 m_calloc_dma(sizeof(ncrcmd)*(MAX_START*2), "DQUEUE");
5456 if (!np->dqueue)
5457 goto attach_error;
5458
5459
5460
5461
5462 np->targtbl = (u_int32 *) m_calloc_dma(256, "TARGTBL");
5463 if (!np->targtbl)
5464 goto attach_error;
5465
5466
5467
5468
5469 np->script0 = (struct script *)
5470 m_calloc_dma(sizeof(struct script), "SCRIPT");
5471 if (!np->script0)
5472 goto attach_error;
5473 np->scripth0 = (struct scripth *)
5474 m_calloc_dma(sizeof(struct scripth), "SCRIPTH");
5475 if (!np->scripth0)
5476 goto attach_error;
5477
5478
5479
5480
5481
5482 xpt_que_init(&np->free_ccbq);
5483 xpt_que_init(&np->b0_ccbq);
5484 if (!ncr_alloc_ccb(np))
5485 goto attach_error;
5486
5487
5488
5489
5490
5491 init_timer(&np->timer);
5492 np->timer.data = (unsigned long) np;
5493 np->timer.function = sym53c8xx_timeout;
5494
5495
5496
5497
5498
5499
5500 np->base_ba = device->slot.base;
5501 np->base_ws = (np->features & FE_IO256)? 256 : 128;
5502 np->base2_ba = (np->features & FE_RAM)? device->slot.base_2 : 0;
5503
5504#ifndef SCSI_NCR_IOMAPPED
5505 np->base_va = remap_pci_mem(device->slot.base_c, np->base_ws);
5506 if (!np->base_va) {
5507 printk(KERN_ERR "%s: can't map PCI MMIO region\n",ncr_name(np));
5508 goto attach_error;
5509 }
5510 else if (bootverbose > 1)
5511 printk(KERN_INFO "%s: using memory mapped IO\n", ncr_name(np));
5512
5513
5514
5515
5516
5517
5518
5519 np->reg = (struct ncr_reg *) np->base_va;
5520
5521#endif
5522
5523
5524
5525
5526 if (np->base2_ba && sizeof(struct script) > 4096) {
5527 printk(KERN_ERR "%s: script too large.\n", ncr_name(np));
5528 goto attach_error;
5529 }
5530
5531
5532
5533
5534
5535 if (device->slot.io_port) {
5536 request_region(device->slot.io_port, np->base_ws, NAME53C8XX);
5537 np->base_io = device->slot.io_port;
5538 }
5539
5540#ifdef SCSI_NCR_NVRAM_SUPPORT
5541 if (nvram) {
5542 switch(nvram->type) {
5543 case SCSI_NCR_SYMBIOS_NVRAM:
5544#ifdef SCSI_NCR_DEBUG_NVRAM
5545 ncr_display_Symbios_nvram(np, &nvram->data.Symbios);
5546#endif
5547 break;
5548 case SCSI_NCR_TEKRAM_NVRAM:
5549#ifdef SCSI_NCR_DEBUG_NVRAM
5550 ncr_display_Tekram_nvram(np, &nvram->data.Tekram);
5551#endif
5552 break;
5553 default:
5554 nvram = 0;
5555#ifdef SCSI_NCR_DEBUG_NVRAM
5556 printk(KERN_DEBUG "%s: NVRAM: None or invalid data.\n", ncr_name(np));
5557#endif
5558 }
5559 }
5560#endif
5561
5562
5563
5564
5565
5566 ncr_save_initial_setting (np);
5567
5568
5569
5570
5571
5572
5573 ncr_chip_reset (np);
5574
5575
5576
5577
5578 (void) ncr_prepare_setting(np, nvram);
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618 i = np->pciclock_max ? ncr_getpciclock(np) : 0;
5619 if (i && (i < np->pciclock_min || i > np->pciclock_max)) {
5620 printk(KERN_ERR "%s: PCI clock (%u KHz) is out of range "
5621 "[%u KHz - %u KHz].\n",
5622 ncr_name(np), i, np->pciclock_min, np->pciclock_max);
5623 goto attach_error;
5624 }
5625
5626
5627
5628
5629 ncr_script_fill (&script0, &scripth0);
5630
5631 np->p_script = vtobus(np->script0);
5632 np->p_scripth = vtobus(np->scripth0);
5633 np->p_scripth0 = np->p_scripth;
5634
5635 if (np->base2_ba) {
5636 np->p_script = np->base2_ba;
5637 if (np->features & FE_RAM8K) {
5638 np->base2_ws = 8192;
5639 np->p_scripth = np->p_script + 4096;
5640#if BITS_PER_LONG > 32
5641 np->scr_ram_seg = cpu_to_scr(np->base2_ba >> 32);
5642#endif
5643 }
5644 else
5645 np->base2_ws = 4096;
5646#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
5647 np->base2_va =
5648 remap_pci_mem(device->slot.base_2_c, np->base2_ws);
5649 if (!np->base2_va) {
5650 printk(KERN_ERR "%s: can't map PCI MEMORY region\n",
5651 ncr_name(np));
5652 goto attach_error;
5653 }
5654#endif
5655 }
5656
5657 ncr_script_copy_and_bind (np, (ncrcmd *) &script0, (ncrcmd *) np->script0, sizeof(struct script));
5658 ncr_script_copy_and_bind (np, (ncrcmd *) &scripth0, (ncrcmd *) np->scripth0, sizeof(struct scripth));
5659
5660
5661
5662
5663 np->scripth0->pm0_data_addr[0] =
5664 cpu_to_scr(NCB_SCRIPT_PHYS(np, pm0_data));
5665 np->scripth0->pm1_data_addr[0] =
5666 cpu_to_scr(NCB_SCRIPT_PHYS(np, pm1_data));
5667
5668
5669
5670
5671 if (np->features & FE_ULTRA3) {
5672 np->script0->resel_scntl4[0] = cpu_to_scr(SCR_LOAD_REL (scntl4, 1));
5673 np->script0->resel_scntl4[1] = cpu_to_scr(offsetof(struct tcb, uval));
5674 }
5675
5676
5677#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
5678 np->scripth0->script0_ba[0] = cpu_to_scr(vtobus(np->script0));
5679 np->scripth0->script0_ba64[0] = cpu_to_scr(vtobus(np->script0));
5680 np->scripth0->scripth0_ba64[0] = cpu_to_scr(vtobus(np->scripth0));
5681 np->scripth0->ram_seg64[0] = np->scr_ram_seg;
5682#endif
5683
5684
5685
5686 np->idletask.start = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
5687 np->idletask.restart = cpu_to_scr(NCB_SCRIPTH_PHYS (np, bad_i_t_l));
5688 np->p_idletask = NCB_PHYS(np, idletask);
5689
5690 np->notask.start = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
5691 np->notask.restart = cpu_to_scr(NCB_SCRIPTH_PHYS (np, bad_i_t_l));
5692 np->p_notask = NCB_PHYS(np, notask);
5693
5694 np->bad_i_t_l.start = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
5695 np->bad_i_t_l.restart = cpu_to_scr(NCB_SCRIPTH_PHYS (np, bad_i_t_l));
5696 np->p_bad_i_t_l = NCB_PHYS(np, bad_i_t_l);
5697
5698 np->bad_i_t_l_q.start = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
5699 np->bad_i_t_l_q.restart = cpu_to_scr(NCB_SCRIPTH_PHYS (np,bad_i_t_l_q));
5700 np->p_bad_i_t_l_q = NCB_PHYS(np, bad_i_t_l_q);
5701
5702
5703
5704
5705 np->badluntbl = m_calloc_dma(256, "BADLUNTBL");
5706 if (!np->badluntbl)
5707 goto attach_error;
5708
5709 assert (offsetof(struct lcb, resel_task) == 0);
5710 np->resel_badlun = cpu_to_scr(NCB_SCRIPTH_PHYS(np, resel_bad_lun));
5711
5712 for (i = 0 ; i < 64 ; i++)
5713 np->badluntbl[i] = cpu_to_scr(NCB_PHYS(np, resel_badlun));
5714
5715
5716
5717
5718 np->scripth0->targtbl[0] = cpu_to_scr(vtobus(np->targtbl));
5719 for (i = 0 ; i < MAX_TARGET ; i++) {
5720 np->targtbl[i] = cpu_to_scr(NCB_PHYS(np, target[i]));
5721 np->target[i].b_luntbl = cpu_to_scr(vtobus(np->badluntbl));
5722 np->target[i].b_lun0 = cpu_to_scr(NCB_PHYS(np, resel_badlun));
5723 }
5724
5725
5726
5727
5728
5729 if (np->features & FE_LED0) {
5730 np->script0->idle[0] =
5731 cpu_to_scr(SCR_REG_REG(gpreg, SCR_OR, 0x01));
5732 np->script0->reselected[0] =
5733 cpu_to_scr(SCR_REG_REG(gpreg, SCR_AND, 0xfe));
5734 np->script0->start[0] =
5735 cpu_to_scr(SCR_REG_REG(gpreg, SCR_AND, 0xfe));
5736 }
5737
5738
5739
5740
5741
5742
5743 if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 &&
5744 np->revision_id < 1){
5745 np->script0->datao_phase[0] =
5746 cpu_to_scr(SCR_REG_REG(scntl4, SCR_OR, 0x0c));
5747 }
5748
5749#ifdef SCSI_NCR_IARB_SUPPORT
5750
5751
5752
5753
5754
5755 if (!(driver_setup.iarb & 1))
5756 np->script0->ungetjob[0] = cpu_to_scr(SCR_NO_OP);
5757
5758
5759
5760
5761
5762
5763 np->iarb_max = (driver_setup.iarb >> 4);
5764#endif
5765
5766
5767
5768
5769 if (np->device_id == PCI_DEVICE_ID_NCR_53C896 &&
5770 np->revision_id <= 0x1 && (np->features & FE_NOPM)) {
5771 np->scatter = ncr_scatter_896R1;
5772 np->script0->datai_phase[0] = cpu_to_scr(SCR_JUMP);
5773 np->script0->datai_phase[1] =
5774 cpu_to_scr(NCB_SCRIPTH_PHYS (np, tweak_pmj));
5775 np->script0->datao_phase[0] = cpu_to_scr(SCR_JUMP);
5776 np->script0->datao_phase[1] =
5777 cpu_to_scr(NCB_SCRIPTH_PHYS (np, tweak_pmj));
5778 }
5779 else
5780#ifdef DEBUG_896R1
5781 np->scatter = ncr_scatter_896R1;
5782#else
5783 np->scatter = ncr_scatter;
5784#endif
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795 ncr_chip_reset(np);
5796
5797
5798
5799
5800
5801 if (ncr_snooptest (np)) {
5802 printk (KERN_ERR "CACHE INCORRECTLY CONFIGURED.\n");
5803 goto attach_error;
5804 };
5805
5806
5807
5808
5809
5810
5811 if (request_irq(device->slot.irq, sym53c8xx_intr,
5812#ifdef SCSI_NCR_PCIQ_SYNC_ON_INTR
5813 ((driver_setup.irqm & 0x20) ? 0 : SA_INTERRUPT),
5814#else
5815 ((driver_setup.irqm & 0x10) ? 0 : SA_SHIRQ) |
5816#if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)
5817 ((driver_setup.irqm & 0x20) ? 0 : SA_INTERRUPT),
5818#else
5819 0,
5820#endif
5821#endif
5822 NAME53C8XX, np)) {
5823 printk(KERN_ERR "%s: request irq %d failure\n",
5824 ncr_name(np), device->slot.irq);
5825 goto attach_error;
5826 }
5827 np->irq = device->slot.irq;
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837 NCR_LOCK_NCB(np, flags);
5838 if (ncr_reset_scsi_bus(np, 0, driver_setup.settle_delay) != 0) {
5839 printk(KERN_ERR "%s: FATAL ERROR: CHECK SCSI BUS - CABLES, TERMINATION, DEVICE POWER etc.!\n", ncr_name(np));
5840
5841 NCR_UNLOCK_NCB(np, flags);
5842 goto attach_error;
5843 }
5844 ncr_exception (np);
5845
5846
5847
5848
5849
5850
5851 if (driver_setup.settle_delay > 2) {
5852 printk(KERN_INFO "%s: waiting %d seconds for scsi devices to settle...\n",
5853 ncr_name(np), driver_setup.settle_delay);
5854 MDELAY (1000 * driver_setup.settle_delay);
5855 }
5856
5857
5858
5859
5860 np->lasttime=0;
5861 ncr_timeout (np);
5862
5863
5864
5865
5866#ifdef SCSI_NCR_ALWAYS_SIMPLE_TAG
5867 np->order = M_SIMPLE_TAG;
5868#endif
5869
5870
5871
5872
5873
5874
5875 instance->max_channel = 0;
5876 instance->this_id = np->myaddr;
5877 instance->max_id = np->maxwide ? 16 : 8;
5878 instance->max_lun = MAX_LUN;
5879#ifndef SCSI_NCR_IOMAPPED
5880#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,29)
5881 instance->base = (unsigned long) np->reg;
5882#else
5883 instance->base = (char *) np->reg;
5884#endif
5885#endif
5886 instance->irq = np->irq;
5887 instance->unique_id = np->base_io;
5888 instance->io_port = np->base_io;
5889 instance->n_io_port = np->base_ws;
5890 instance->dma_channel = 0;
5891 instance->cmd_per_lun = MAX_TAGS;
5892 instance->can_queue = (MAX_START-4);
5893 scsi_set_pci_device(instance, device->pdev);
5894
5895 np->check_integrity = 0;
5896
5897#ifdef SCSI_NCR_INTEGRITY_CHECKING
5898 instance->check_integrity = 0;
5899
5900#ifdef SCSI_NCR_ENABLE_INTEGRITY_CHECK
5901 if ( !(driver_setup.bus_check & 0x04) ) {
5902 np->check_integrity = 1;
5903 instance->check_integrity = 1;
5904 }
5905#endif
5906#endif
5907
5908 NCR_UNLOCK_NCB(np, flags);
5909
5910
5911
5912
5913
5914 return 0;
5915
5916attach_error:
5917 if (!instance) return -1;
5918 printk(KERN_INFO "%s: giving up ...\n", ncr_name(np));
5919 if (np)
5920 ncr_free_resources(np);
5921 scsi_unregister(instance);
5922
5923 return -1;
5924 }
5925
5926
5927
5928
5929
5930static void ncr_free_resources(ncb_p np)
5931{
5932 ccb_p cp;
5933 tcb_p tp;
5934 lcb_p lp;
5935 int target, lun;
5936
5937 if (np->irq)
5938 free_irq(np->irq, np);
5939 if (np->base_io)
5940 release_region(np->base_io, np->base_ws);
5941#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
5942 if (np->base_va)
5943 unmap_pci_mem(np->base_va, np->base_ws);
5944 if (np->base2_va)
5945 unmap_pci_mem(np->base2_va, np->base2_ws);
5946#endif
5947 if (np->scripth0)
5948 m_free_dma(np->scripth0, sizeof(struct scripth), "SCRIPTH");
5949 if (np->script0)
5950 m_free_dma(np->script0, sizeof(struct script), "SCRIPT");
5951 if (np->squeue)
5952 m_free_dma(np->squeue, sizeof(ncrcmd)*(MAX_START*2), "SQUEUE");
5953 if (np->dqueue)
5954 m_free_dma(np->dqueue, sizeof(ncrcmd)*(MAX_START*2),"DQUEUE");
5955
5956 while ((cp = np->ccbc) != NULL) {
5957 np->ccbc = cp->link_ccb;
5958 m_free_dma(cp, sizeof(*cp), "CCB");
5959 }
5960
5961 if (np->badluntbl)
5962 m_free_dma(np->badluntbl, 256,"BADLUNTBL");
5963
5964 for (target = 0; target < MAX_TARGET ; target++) {
5965 tp = &np->target[target];
5966 for (lun = 0 ; lun < MAX_LUN ; lun++) {
5967 lp = ncr_lp(np, tp, lun);
5968 if (!lp)
5969 continue;
5970 if (lp->tasktbl != &lp->tasktbl_0)
5971 m_free_dma(lp->tasktbl, MAX_TASKS*4, "TASKTBL");
5972 if (lp->cb_tags)
5973 m_free(lp->cb_tags, MAX_TAGS, "CB_TAGS");
5974 m_free_dma(lp, sizeof(*lp), "LCB");
5975 }
5976#if MAX_LUN > 1
5977 if (tp->lmp)
5978 m_free(tp->lmp, MAX_LUN * sizeof(lcb_p), "LMP");
5979 if (tp->luntbl)
5980 m_free_dma(tp->luntbl, 256, "LUNTBL");
5981#endif
5982 }
5983
5984 if (np->targtbl)
5985 m_free_dma(np->targtbl, 256, "TARGTBL");
5986
5987 m_free_dma(np, sizeof(*np), "NCB");
5988}
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009static inline void ncr_queue_done_cmd(ncb_p np, Scsi_Cmnd *cmd)
6010{
6011 unmap_scsi_data(np, cmd);
6012 cmd->host_scribble = (char *) np->done_list;
6013 np->done_list = cmd;
6014}
6015
6016static inline void ncr_flush_done_cmds(Scsi_Cmnd *lcmd)
6017{
6018 Scsi_Cmnd *cmd;
6019
6020 while (lcmd) {
6021 cmd = lcmd;
6022 lcmd = (Scsi_Cmnd *) cmd->host_scribble;
6023 cmd->scsi_done(cmd);
6024 }
6025}
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043#ifdef SCSI_NCR_INTEGRITY_CHECKING
6044static int ncr_ic_nego(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd, u_char *msgptr)
6045{
6046 tcb_p tp = &np->target[cp->target];
6047 int msglen = 0;
6048 int nego = 0;
6049 u_char new_width, new_offset, new_period;
6050 u_char no_increase;
6051
6052 if (tp->ppr_negotiation == 1)
6053 tp->ppr_negotiation = 2;
6054
6055 if (tp->inq_done) {
6056
6057 if (!tp->ic_maximums_set) {
6058 tp->ic_maximums_set = 1;
6059
6060
6061
6062
6063 if ( (tp->inq_byte7 & INQ7_WIDE16) &&
6064 np->maxwide && tp->usrwide)
6065 tp->ic_max_width = 1;
6066 else
6067 tp->ic_max_width = 0;
6068
6069
6070 if ((tp->inq_byte7 & INQ7_SYNC) && tp->maxoffs)
6071 tp->ic_min_sync = (tp->minsync < np->minsync) ?
6072 np->minsync : tp->minsync;
6073 else
6074 tp->ic_min_sync = 255;
6075
6076 tp->period = 1;
6077 tp->widedone = 1;
6078
6079
6080
6081
6082
6083
6084#if 0
6085 if (tp->ic_max_width && (tp->ic_min_sync != 255 ))
6086 tp->ppr_negotiation = 1;
6087#endif
6088 tp->ppr_negotiation = 0;
6089 if (np->features & FE_ULTRA3) {
6090 if (tp->ic_max_width && (tp->ic_min_sync == 0x09))
6091 tp->ppr_negotiation = 1;
6092 }
6093
6094 if (!tp->ppr_negotiation)
6095 cmd->ic_nego &= ~NS_PPR;
6096 }
6097
6098 if (DEBUG_FLAGS & DEBUG_IC) {
6099 printk("%s: cmd->ic_nego %d, 1st byte 0x%2X\n",
6100 ncr_name(np), cmd->ic_nego, cmd->cmnd[0]);
6101 }
6102
6103
6104
6105
6106
6107
6108
6109 if (np->check_integ_par) {
6110 printk("%s: Parity Error. Target set to narrow.\n",
6111 ncr_name(np));
6112 tp->ic_max_width = 0;
6113 tp->widedone = tp->period = 0;
6114 }
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127 if (!tp->ppr_negotiation && (cmd->ic_nego == NS_PPR )) {
6128 tp->ppr_negotiation = 0;
6129 cmd->ic_nego &= ~NS_PPR;
6130 tp->widedone = tp->period = 1;
6131 return msglen;
6132 }
6133 else if (( tp->ppr_negotiation && !(cmd->ic_nego & NS_PPR )) ||
6134 (!tp->ppr_negotiation && (cmd->ic_nego & NS_PPR )) ) {
6135 tp->ppr_negotiation = 0;
6136 cmd->ic_nego &= ~NS_PPR;
6137 }
6138
6139
6140
6141
6142
6143
6144
6145 if ((tp->ppr_negotiation) && (!(cmd->ic_nego & NS_PPR)))
6146 tp->ppr_negotiation = 0;
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156 no_increase = 0;
6157
6158 if (tp->ppr_negotiation && (!tp->widedone) && (!tp->period) ) {
6159 cmd->ic_nego = NS_PPR;
6160 tp->widedone = tp->period = 1;
6161 no_increase = 1;
6162 }
6163 else if (!tp->widedone) {
6164 cmd->ic_nego = NS_WIDE;
6165 tp->widedone = 1;
6166 no_increase = 1;
6167 }
6168 else if (!tp->period) {
6169 cmd->ic_nego = NS_SYNC;
6170 tp->period = 1;
6171 no_increase = 1;
6172 }
6173
6174 new_width = cmd->ic_nego_width & tp->ic_max_width;
6175
6176 switch (cmd->ic_nego_sync) {
6177 case 2:
6178 if (!no_increase) {
6179 if (tp->ic_min_sync <= 0x09)
6180 tp->ic_min_sync = 0x0A;
6181 else if (tp->ic_min_sync <= 0x0A)
6182 tp->ic_min_sync = 0x0C;
6183 else if (tp->ic_min_sync <= 0x0C)
6184 tp->ic_min_sync = 0x19;
6185 else if (tp->ic_min_sync <= 0x19)
6186 tp->ic_min_sync *= 2;
6187 else {
6188 tp->ic_min_sync = 255;
6189 cmd->ic_nego_sync = 0;
6190 tp->maxoffs = 0;
6191 }
6192 }
6193 new_period = tp->maxoffs?tp->ic_min_sync:0;
6194 new_offset = tp->maxoffs;
6195 break;
6196
6197 case 1:
6198 new_period = tp->maxoffs?tp->ic_min_sync:0;
6199 new_offset = tp->maxoffs;
6200 break;
6201
6202 case 0:
6203 default:
6204 new_period = 0;
6205 new_offset = 0;
6206 break;
6207 };
6208
6209
6210 nego = NS_NOCHANGE;
6211 if (tp->ppr_negotiation) {
6212 u_char options_byte = 0;
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226 if ( (new_period==0x09) && new_offset) {
6227 if (new_width)
6228 options_byte = 0x02;
6229 else {
6230 tp->ic_min_sync = 0x0A;
6231 new_period = 0x0A;
6232 cmd->ic_nego_width = 1;
6233 new_width = 1;
6234 }
6235 }
6236 if (!options_byte && new_offset > np->maxoffs_st)
6237 new_offset = np->maxoffs_st;
6238
6239 nego = NS_PPR;
6240
6241 msgptr[msglen++] = M_EXTENDED;
6242 msgptr[msglen++] = 6;
6243 msgptr[msglen++] = M_X_PPR_REQ;
6244 msgptr[msglen++] = new_period;
6245 msgptr[msglen++] = 0;
6246 msgptr[msglen++] = new_offset;
6247 msgptr[msglen++] = new_width;
6248 msgptr[msglen++] = options_byte;
6249
6250 }
6251 else {
6252 switch (cmd->ic_nego & ~NS_PPR) {
6253 case NS_WIDE:
6254
6255
6256
6257
6258
6259
6260 cmd->ic_nego_width &= tp->ic_max_width;
6261
6262 if (tp->ic_max_width | np->check_integ_par) {
6263 nego = NS_WIDE;
6264 msgptr[msglen++] = M_EXTENDED;
6265 msgptr[msglen++] = 2;
6266 msgptr[msglen++] = M_X_WIDE_REQ;
6267 msgptr[msglen++] = new_width;
6268 }
6269 break;
6270
6271 case NS_SYNC:
6272
6273
6274
6275
6276
6277
6278 if (tp->inq_byte7 & INQ7_SYNC) {
6279
6280 if (new_offset && (new_period < 0x0A)) {
6281 tp->ic_min_sync = 0x0A;
6282 new_period = 0x0A;
6283 }
6284 if (new_offset > np->maxoffs_st)
6285 new_offset = np->maxoffs_st;
6286 nego = NS_SYNC;
6287 msgptr[msglen++] = M_EXTENDED;
6288 msgptr[msglen++] = 3;
6289 msgptr[msglen++] = M_X_SYNC_REQ;
6290 msgptr[msglen++] = new_period;
6291 msgptr[msglen++] = new_offset;
6292 }
6293 else
6294 cmd->ic_nego_sync = 0;
6295 break;
6296
6297 case NS_NOCHANGE:
6298 break;
6299 }
6300 }
6301
6302 };
6303
6304 cp->nego_status = nego;
6305 np->check_integ_par = 0;
6306
6307 if (nego) {
6308 tp->nego_cp = cp;
6309 if (DEBUG_FLAGS & DEBUG_NEGO) {
6310 ncr_print_msg(cp, nego == NS_WIDE ?
6311 "wide/narrow msgout":
6312 (nego == NS_SYNC ? "sync/async msgout" : "ppr msgout"),
6313 msgptr);
6314 };
6315 };
6316
6317 return msglen;
6318}
6319#endif
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335static int ncr_prepare_nego(ncb_p np, ccb_p cp, u_char *msgptr)
6336{
6337 tcb_p tp = &np->target[cp->target];
6338 int msglen = 0;
6339 int nego = 0;
6340 u_char width, offset, factor, last_byte;
6341
6342 if (!np->check_integrity) {
6343
6344
6345
6346 if (tp->ppr_negotiation == 1)
6347 tp->ppr_negotiation = 2;
6348
6349 if ((tp->inq_done) && (!tp->ic_maximums_set)) {
6350 tp->ic_maximums_set = 1;
6351
6352
6353
6354
6355
6356 tp->ppr_negotiation = 0;
6357 if ( (np->features & FE_ULTRA3) &&
6358 (tp->usrwide) && (tp->maxoffs) &&
6359 (tp->minsync == 0x09) )
6360 tp->ppr_negotiation = 1;
6361 }
6362 }
6363
6364 if (tp->inq_done) {
6365
6366
6367
6368 ncr_get_xfer_info( np, tp, &factor,
6369 &offset, &width);
6370
6371
6372
6373
6374
6375 if (!tp->widedone) {
6376 if (tp->inq_byte7 & INQ7_WIDE16) {
6377 if (tp->ppr_negotiation)
6378 nego = NS_PPR;
6379 else
6380 nego = NS_WIDE;
6381
6382 width = tp->usrwide;
6383#ifdef SCSI_NCR_INTEGRITY_CHECKING
6384 if (tp->ic_done)
6385 width &= tp->ic_max_width;
6386#endif
6387 } else
6388 tp->widedone=1;
6389
6390 };
6391
6392
6393
6394
6395
6396 if ((nego != NS_WIDE) && !tp->period) {
6397 if (tp->inq_byte7 & INQ7_SYNC) {
6398 if (tp->ppr_negotiation)
6399 nego = NS_PPR;
6400 else
6401 nego = NS_SYNC;
6402
6403
6404 if (tp->maxoffs == 0) {
6405 offset = 0;
6406 factor = 0;
6407 }
6408 else {
6409 offset = tp->maxoffs;
6410 factor = tp->minsync;
6411#ifdef SCSI_NCR_INTEGRITY_CHECKING
6412 if ((tp->ic_done) &&
6413 (factor < tp->ic_min_sync))
6414 factor = tp->ic_min_sync;
6415#endif
6416 }
6417
6418 } else {
6419 offset = 0;
6420 factor = 0;
6421 tp->period =0xffff;
6422 PRINT_TARGET(np, cp->target);
6423 printk ("target did not report SYNC.\n");
6424 };
6425 };
6426 };
6427
6428 switch (nego) {
6429 case NS_PPR:
6430
6431
6432
6433
6434
6435
6436 last_byte = 0;
6437 if ( (factor==9) && offset) {
6438 if (!width) {
6439 factor = 0x0A;
6440 }
6441 else
6442 last_byte = 0x02;
6443 }
6444 if (!last_byte && offset > np->maxoffs_st)
6445 offset = np->maxoffs_st;
6446
6447 msgptr[msglen++] = M_EXTENDED;
6448 msgptr[msglen++] = 6;
6449 msgptr[msglen++] = M_X_PPR_REQ;
6450 msgptr[msglen++] = factor;
6451 msgptr[msglen++] = 0;
6452 msgptr[msglen++] = offset;
6453 msgptr[msglen++] = width;
6454 msgptr[msglen++] = last_byte;
6455 break;
6456 case NS_SYNC:
6457
6458
6459
6460 if (offset && (factor < 0x0A)) {
6461 factor = 0x0A;
6462 tp->minsync = 0x0A;
6463 }
6464 if (offset > np->maxoffs_st)
6465 offset = np->maxoffs_st;
6466
6467 msgptr[msglen++] = M_EXTENDED;
6468 msgptr[msglen++] = 3;
6469 msgptr[msglen++] = M_X_SYNC_REQ;
6470 msgptr[msglen++] = factor;
6471 msgptr[msglen++] = offset;
6472 break;
6473 case NS_WIDE:
6474 msgptr[msglen++] = M_EXTENDED;
6475 msgptr[msglen++] = 2;
6476 msgptr[msglen++] = M_X_WIDE_REQ;
6477 msgptr[msglen++] = width;
6478 break;
6479 };
6480
6481 cp->nego_status = nego;
6482
6483 if (nego) {
6484 tp->nego_cp = cp;
6485 if (DEBUG_FLAGS & DEBUG_NEGO) {
6486 ncr_print_msg(cp, nego == NS_WIDE ?
6487 "wide msgout":
6488 (nego == NS_SYNC ? "sync msgout" : "ppr msgout"),
6489 msgptr);
6490 };
6491 };
6492
6493 return msglen;
6494}
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd)
6506{
6507
6508 tcb_p tp = &np->target[cmd->target];
6509 lcb_p lp = ncr_lp(np, tp, cmd->lun);
6510 ccb_p cp;
6511
6512 u_char idmsg, *msgptr;
6513 u_int msglen;
6514 int direction;
6515 u_int32 lastp, goalp;
6516
6517
6518
6519
6520
6521
6522
6523 if ((cmd->target == np->myaddr ) ||
6524 (cmd->target >= MAX_TARGET) ||
6525 (cmd->lun >= MAX_LUN )) {
6526 return(DID_BAD_TARGET);
6527 }
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538 if ((cmd->cmnd[0] == 0 || cmd->cmnd[0] == 0x12) &&
6539 (tp->usrflag & UF_NOSCAN)) {
6540 tp->usrflag &= ~UF_NOSCAN;
6541 return DID_BAD_TARGET;
6542 }
6543
6544 if (DEBUG_FLAGS & DEBUG_TINY) {
6545 PRINT_ADDR(cmd);
6546 printk ("CMD=%x ", cmd->cmnd[0]);
6547 }
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559 if (np->settle_time && cmd->timeout_per_command >= HZ) {
6560 u_long tlimit = ktime_get(cmd->timeout_per_command - HZ);
6561 if (ktime_dif(np->settle_time, tlimit) > 0)
6562 np->settle_time = tlimit;
6563 }
6564
6565 if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) {
6566 insert_into_waiting_list(np, cmd);
6567 return(DID_OK);
6568 }
6569 cp->cmd = cmd;
6570
6571
6572
6573
6574
6575
6576
6577#if 0
6578 if (lp && !lp->numtags && cmd->device && cmd->device->tagged_queue) {
6579 lp->numtags = tp->usrtags;
6580 ncr_setup_tags (np, cp->target, cp->lun);
6581 }
6582#endif
6583
6584
6585
6586
6587
6588
6589
6590
6591 idmsg = M_IDENTIFY | cp->lun;
6592
6593 if (cp ->tag != NO_TAG || (lp && !(tp->usrflag & UF_NODISC)))
6594 idmsg |= 0x40;
6595
6596 msgptr = cp->scsi_smsg;
6597 msglen = 0;
6598 msgptr[msglen++] = idmsg;
6599
6600 if (cp->tag != NO_TAG) {
6601 char order = np->order;
6602
6603
6604
6605
6606
6607 if (lp && ktime_exp(lp->tags_stime)) {
6608 lp->tags_si = !(lp->tags_si);
6609 if (lp->tags_sum[lp->tags_si]) {
6610 order = M_ORDERED_TAG;
6611 if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>0){
6612 PRINT_ADDR(cmd);
6613 printk("ordered tag forced.\n");
6614 }
6615 }
6616 lp->tags_stime = ktime_get(3*HZ);
6617 }
6618
6619 if (order == 0) {
6620
6621
6622
6623 switch (cmd->cmnd[0]) {
6624 case 0x08:
6625 case 0x28:
6626 case 0xa8:
6627 order = M_SIMPLE_TAG;
6628 break;
6629 default:
6630 order = M_ORDERED_TAG;
6631 }
6632 }
6633 msgptr[msglen++] = order;
6634
6635
6636
6637
6638
6639
6640
6641#if MAX_TASKS > (512/4)
6642 msgptr[msglen++] = cp->tag;
6643#else
6644 msgptr[msglen++] = (cp->tag << 1) + 1;
6645#endif
6646 }
6647
6648 cp->host_flags = 0;
6649
6650
6651
6652
6653
6654
6655
6656
6657 direction = scsi_data_direction(cmd);
6658 if (direction != SCSI_DATA_NONE) {
6659 cp->segments = np->scatter (np, cp, cp->cmd);
6660 if (cp->segments < 0) {
6661 ncr_free_ccb(np, cp);
6662 return(DID_ERROR);
6663 }
6664 }
6665 else {
6666 cp->data_len = 0;
6667 cp->segments = 0;
6668 }
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679 cp->nego_status = 0;
6680
6681#ifdef SCSI_NCR_INTEGRITY_CHECKING
6682 if ((np->check_integrity && tp->ic_done) || !np->check_integrity) {
6683 if ((!tp->widedone || !tp->period) && !tp->nego_cp && lp) {
6684 msglen += ncr_prepare_nego (np, cp, msgptr + msglen);
6685 }
6686 }
6687 else if (np->check_integrity && (cmd->ic_in_progress)) {
6688 msglen += ncr_ic_nego (np, cp, cmd, msgptr + msglen);
6689 }
6690 else if (np->check_integrity && cmd->ic_complete) {
6691 u_long current_period;
6692 u_char current_offset, current_width, current_factor;
6693
6694 ncr_get_xfer_info (np, tp, ¤t_factor,
6695 ¤t_offset, ¤t_width);
6696
6697 tp->ic_max_width = current_width;
6698 tp->ic_min_sync = current_factor;
6699
6700 if (current_factor == 9) current_period = 125;
6701 else if (current_factor == 10) current_period = 250;
6702 else if (current_factor == 11) current_period = 303;
6703 else if (current_factor == 12) current_period = 500;
6704 else current_period = current_factor * 40;
6705
6706
6707
6708
6709 tp->period = current_period;
6710 tp->widedone = 1;
6711 tp->ic_done = 1;
6712
6713 printk("%s: Integrity Check Complete: \n", ncr_name(np));
6714
6715 printk("%s: %s %s SCSI", ncr_name(np),
6716 current_offset?"SYNC":"ASYNC",
6717 tp->ic_max_width?"WIDE":"NARROW");
6718 if (current_offset) {
6719 u_long mbs = 10000 * (tp->ic_max_width + 1);
6720
6721 printk(" %d.%d MB/s",
6722 (int) (mbs / current_period), (int) (mbs % current_period));
6723
6724 printk(" (%d ns, %d offset)\n",
6725 (int) current_period/10, current_offset);
6726 }
6727 else
6728 printk(" %d MB/s. \n ", (tp->ic_max_width+1)*5);
6729 }
6730#else
6731 if ((!tp->widedone || !tp->period) && !tp->nego_cp && lp) {
6732 msglen += ncr_prepare_nego (np, cp, msgptr + msglen);
6733 }
6734#endif
6735
6736
6737
6738
6739
6740
6741
6742
6743 if (!cp->data_len)
6744 direction = SCSI_DATA_NONE;
6745
6746
6747
6748
6749
6750
6751
6752 switch(direction) {
6753 case SCSI_DATA_UNKNOWN:
6754 case SCSI_DATA_WRITE:
6755 goalp = NCB_SCRIPT_PHYS (np, data_out2) + 8;
6756 lastp = goalp - 8 - (cp->segments * (SCR_SG_SIZE*4));
6757 if (direction != SCSI_DATA_UNKNOWN)
6758 break;
6759 cp->phys.header.wgoalp = cpu_to_scr(goalp);
6760 cp->phys.header.wlastp = cpu_to_scr(lastp);
6761
6762 case SCSI_DATA_READ:
6763 cp->host_flags |= HF_DATA_IN;
6764 goalp = NCB_SCRIPT_PHYS (np, data_in2) + 8;
6765 lastp = goalp - 8 - (cp->segments * (SCR_SG_SIZE*4));
6766 break;
6767 default:
6768 case SCSI_DATA_NONE:
6769 lastp = goalp = NCB_SCRIPTH_PHYS (np, no_data);
6770 break;
6771 }
6772
6773
6774
6775
6776
6777 cp->phys.header.lastp = cpu_to_scr(lastp);
6778 cp->phys.header.goalp = cpu_to_scr(goalp);
6779
6780 if (direction == SCSI_DATA_UNKNOWN)
6781 cp->phys.header.savep =
6782 cpu_to_scr(NCB_SCRIPTH_PHYS (np, data_io));
6783 else
6784 cp->phys.header.savep= cpu_to_scr(lastp);
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794 cp->startp = cp->phys.header.savep;
6795 cp->lastp0 = cp->phys.header.lastp;
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811 cp->phys.header.go.start = cpu_to_scr(NCB_SCRIPT_PHYS (np,select));
6812 cp->phys.header.go.restart = cpu_to_scr(NCB_SCRIPT_PHYS (np,resel_dsa));
6813
6814
6815
6816 cp->phys.select.sel_id = cp->target;
6817 cp->phys.select.sel_scntl3 = tp->wval;
6818 cp->phys.select.sel_sxfer = tp->sval;
6819 cp->phys.select.sel_scntl4 = tp->uval;
6820
6821
6822
6823 cp->phys.smsg.addr = cpu_to_scr(CCB_PHYS (cp, scsi_smsg));
6824 cp->phys.smsg.size = cpu_to_scr(msglen);
6825
6826
6827
6828
6829 memcpy(cp->cdb_buf, cmd->cmnd, MIN(cmd->cmd_len, sizeof(cp->cdb_buf)));
6830 cp->phys.cmd.addr = cpu_to_scr(CCB_PHYS (cp, cdb_buf[0]));
6831 cp->phys.cmd.size = cpu_to_scr(cmd->cmd_len);
6832
6833
6834
6835
6836 cp->actualquirks = tp->quirks;
6837 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
6838 cp->scsi_status = S_ILLEGAL;
6839 cp->xerr_status = 0;
6840 cp->extra_bytes = 0;
6841
6842
6843
6844
6845
6846 cp->ext_sg = -1;
6847 cp->ext_ofs = 0;
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864 if (lp)
6865 ncr_start_next_ccb(np, lp, 2);
6866 else
6867 ncr_put_start_queue(np, cp);
6868
6869
6870
6871
6872
6873 return(DID_OK);
6874}
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887static void ncr_start_next_ccb(ncb_p np, lcb_p lp, int maxn)
6888{
6889 XPT_QUEHEAD *qp;
6890 ccb_p cp;
6891
6892 while (maxn-- && lp->queuedccbs < lp->queuedepth) {
6893 qp = xpt_remque_head(&lp->wait_ccbq);
6894 if (!qp)
6895 break;
6896 ++lp->queuedccbs;
6897 cp = xpt_que_entry(qp, struct ccb, link_ccbq);
6898 xpt_insque_tail(qp, &lp->busy_ccbq);
6899 lp->tasktbl[cp->tag == NO_TAG ? 0 : cp->tag] =
6900 cpu_to_scr(cp->p_ccb);
6901 ncr_put_start_queue(np, cp);
6902 }
6903}
6904
6905static void ncr_put_start_queue(ncb_p np, ccb_p cp)
6906{
6907 u_short qidx;
6908
6909#ifdef SCSI_NCR_IARB_SUPPORT
6910
6911
6912
6913
6914
6915
6916
6917
6918 if (np->last_cp && np->iarb_count < np->iarb_max) {
6919 np->last_cp->host_flags |= HF_HINT_IARB;
6920 ++np->iarb_count;
6921 }
6922 else
6923 np->iarb_count = 0;
6924 np->last_cp = cp;
6925#endif
6926
6927
6928
6929
6930 qidx = np->squeueput + 2;
6931 if (qidx >= MAX_START*2) qidx = 0;
6932
6933 np->squeue [qidx] = cpu_to_scr(np->p_idletask);
6934 MEMORY_BARRIER();
6935 np->squeue [np->squeueput] = cpu_to_scr(cp->p_ccb);
6936
6937 np->squeueput = qidx;
6938 cp->queued = 1;
6939
6940 if (DEBUG_FLAGS & DEBUG_QUEUE)
6941 printk ("%s: queuepos=%d.\n", ncr_name (np), np->squeueput);
6942
6943
6944
6945
6946
6947 MEMORY_BARRIER();
6948 OUTB (nc_istat, SIGP|np->istat_sem);
6949}
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965static void ncr_chip_reset (ncb_p np)
6966{
6967 OUTB (nc_istat, SRST);
6968 UDELAY (10);
6969 OUTB (nc_istat, 0);
6970}
6971
6972static void ncr_soft_reset(ncb_p np)
6973{
6974 u_char istat;
6975 int i;
6976
6977 if (!(np->features & FE_ISTAT1) || !(INB (nc_istat1) & SRUN))
6978 goto do_chip_reset;
6979
6980 OUTB (nc_istat, CABRT);
6981 for (i = 100000 ; i ; --i) {
6982 istat = INB (nc_istat);
6983 if (istat & SIP) {
6984 INW (nc_sist);
6985 }
6986 else if (istat & DIP) {
6987 if (INB (nc_dstat) & ABRT);
6988 break;
6989 }
6990 UDELAY(5);
6991 }
6992 OUTB (nc_istat, 0);
6993 if (!i)
6994 printk("%s: unable to abort current chip operation, "
6995 "ISTAT=0x%02x.\n", ncr_name(np), istat);
6996do_chip_reset:
6997 ncr_chip_reset(np);
6998}
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011static void ncr_start_reset(ncb_p np)
7012{
7013 (void) ncr_reset_scsi_bus(np, 1, driver_setup.settle_delay);
7014}
7015
7016static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay)
7017{
7018 u_int32 term;
7019 int retv = 0;
7020
7021 np->settle_time = ktime_get(settle_delay * HZ);
7022
7023 if (bootverbose > 1)
7024 printk("%s: resetting, "
7025 "command processing suspended for %d seconds\n",
7026 ncr_name(np), settle_delay);
7027
7028 ncr_soft_reset(np);
7029 UDELAY (2000);
7030 if (enab_int)
7031 OUTW (nc_sien, RST);
7032
7033
7034
7035
7036 OUTB (nc_stest3, TE);
7037 OUTB (nc_dcntl, (np->rv_dcntl & IRQM));
7038 OUTB (nc_scntl1, CRST);
7039 UDELAY (200);
7040
7041 if (!driver_setup.bus_check)
7042 goto out;
7043
7044
7045
7046
7047
7048
7049 term = INB(nc_sstat0);
7050 term = ((term & 2) << 7) + ((term & 1) << 17);
7051 term |= ((INB(nc_sstat2) & 0x01) << 26) |
7052 ((INW(nc_sbdl) & 0xff) << 9) |
7053 ((INW(nc_sbdl) & 0xff00) << 10) |
7054 INB(nc_sbcl);
7055
7056 if (!(np->features & FE_WIDE))
7057 term &= 0x3ffff;
7058
7059 if (term != (2<<7)) {
7060 printk("%s: suspicious SCSI data while resetting the BUS.\n",
7061 ncr_name(np));
7062 printk("%s: %sdp0,d7-0,rst,req,ack,bsy,sel,atn,msg,c/d,i/o = "
7063 "0x%lx, expecting 0x%lx\n",
7064 ncr_name(np),
7065 (np->features & FE_WIDE) ? "dp1,d15-8," : "",
7066 (u_long)term, (u_long)(2<<7));
7067 if (driver_setup.bus_check == 1)
7068 retv = 1;
7069 }
7070out:
7071 OUTB (nc_scntl1, 0);
7072 return retv;
7073}
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084static int ncr_reset_bus (ncb_p np, Scsi_Cmnd *cmd, int sync_reset)
7085{
7086
7087 ccb_p cp;
7088 int found;
7089
7090
7091
7092
7093 if (np->settle_time) {
7094 return SCSI_RESET_PUNT;
7095 }
7096
7097
7098
7099
7100
7101
7102 ncr_start_reset(np);
7103
7104
7105
7106 for (found=0, cp=np->ccbc; cp; cp=cp->link_ccb) {
7107
7108
7109
7110 if (cp->host_status == HS_IDLE) continue;
7111 if (cp->cmd == cmd) {
7112 found = 1;
7113 break;
7114 }
7115 }
7116
7117
7118
7119 if (!found && retrieve_from_waiting_list(0, np, cmd))
7120 found = 1;
7121
7122
7123
7124 reset_waiting_list(np);
7125
7126
7127
7128 ncr_wakeup(np, HS_RESET);
7129
7130
7131
7132
7133
7134
7135 if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) {
7136 SetScsiResult(cmd, DID_RESET, 0);
7137 ncr_queue_done_cmd(np, cmd);
7138 }
7139
7140 return SCSI_RESET_SUCCESS;
7141}
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152static int ncr_abort_command (ncb_p np, Scsi_Cmnd *cmd)
7153{
7154
7155 ccb_p cp;
7156
7157
7158
7159
7160 if (remove_from_waiting_list(np, cmd)) {
7161 SetScsiAbortResult(cmd);
7162 ncr_queue_done_cmd(np, cmd);
7163 return SCSI_ABORT_SUCCESS;
7164 }
7165
7166
7167
7168
7169 for (cp=np->ccbc; cp; cp=cp->link_ccb) {
7170
7171
7172
7173 if (cp->host_status == HS_IDLE) continue;
7174 if (cp->cmd == cmd)
7175 break;
7176 }
7177
7178 if (!cp) {
7179 return SCSI_ABORT_NOT_RUNNING;
7180 }
7181
7182
7183
7184
7185 cp->to_abort = 1;
7186
7187
7188
7189
7190
7191 np->istat_sem = SEM;
7192
7193
7194
7195
7196
7197
7198 OUTB (nc_istat, SIGP|SEM);
7199
7200
7201
7202
7203 return SCSI_ABORT_PENDING;
7204}
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217#ifdef MODULE
7218static int ncr_detach(ncb_p np)
7219{
7220 int i;
7221
7222 printk("%s: detaching ...\n", ncr_name(np));
7223
7224
7225
7226
7227
7228 np->release_stage = 1;
7229 for (i = 50 ; i && np->release_stage != 2 ; i--) MDELAY (100);
7230 if (np->release_stage != 2)
7231 printk("%s: the timer seems to be already stopped\n",
7232 ncr_name(np));
7233 else np->release_stage = 2;
7234
7235
7236
7237
7238
7239
7240
7241 printk("%s: resetting chip\n", ncr_name(np));
7242 ncr_chip_reset(np);
7243
7244
7245
7246
7247 OUTB(nc_dmode, np->sv_dmode);
7248 OUTB(nc_dcntl, np->sv_dcntl);
7249 OUTB(nc_ctest3, np->sv_ctest3);
7250 OUTB(nc_ctest4, np->sv_ctest4);
7251 OUTB(nc_ctest5, np->sv_ctest5);
7252 OUTB(nc_gpcntl, np->sv_gpcntl);
7253 OUTB(nc_stest2, np->sv_stest2);
7254
7255 ncr_selectclock(np, np->sv_scntl3);
7256
7257
7258
7259 ncr_free_resources(np);
7260
7261 return 1;
7262}
7263#endif
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275void ncr_complete (ncb_p np, ccb_p cp)
7276{
7277 Scsi_Cmnd *cmd;
7278 tcb_p tp;
7279 lcb_p lp;
7280
7281
7282
7283
7284 if (!cp || !cp->cmd)
7285 return;
7286
7287
7288
7289
7290
7291 if (DEBUG_FLAGS & DEBUG_TINY)
7292 printk ("CCB=%lx STAT=%x/%x\n", (unsigned long)cp,
7293 cp->host_status,cp->scsi_status);
7294
7295
7296
7297
7298
7299 cmd = cp->cmd;
7300 cp->cmd = NULL;
7301 tp = &np->target[cp->target];
7302 lp = ncr_lp(np, tp, cp->lun);
7303
7304
7305
7306
7307
7308
7309
7310 if (cp == tp->nego_cp)
7311 tp->nego_cp = 0;
7312
7313#ifdef SCSI_NCR_IARB_SUPPORT
7314
7315
7316
7317
7318 if (cp == np->last_cp)
7319 np->last_cp = 0;
7320#endif
7321
7322
7323
7324
7325
7326 if (cp->host_flags & HF_AUTO_SENSE) {
7327 cp->scsi_status = cp->sv_scsi_status;
7328 cp->xerr_status = cp->sv_xerr_status;
7329 }
7330 else {
7331 cp->resid = 0;
7332 if (cp->xerr_status ||
7333 cp->phys.header.lastp != cp->phys.header.goalp)
7334 cp->resid = ncr_compute_residual(np, cp);
7335 }
7336
7337
7338
7339
7340
7341 if (cp->xerr_status) {
7342 if (cp->xerr_status & XE_PARITY_ERR) {
7343 PRINT_ADDR(cmd);
7344 printk ("unrecovered SCSI parity error.\n");
7345 }
7346 if (cp->xerr_status & XE_EXTRA_DATA) {
7347 PRINT_ADDR(cmd);
7348 printk ("extraneous data discarded.\n");
7349 }
7350 if (cp->xerr_status & XE_BAD_PHASE) {
7351 PRINT_ADDR(cmd);
7352 printk ("illegal scsi phase (4/5).\n");
7353 }
7354 if (cp->xerr_status & XE_SODL_UNRUN) {
7355 PRINT_ADDR(cmd);
7356 printk ("ODD transfer in DATA OUT phase.\n");
7357 }
7358 if (cp->xerr_status & XE_SWIDE_OVRUN){
7359 PRINT_ADDR(cmd);
7360 printk ("ODD transfer in DATA IN phase.\n");
7361 }
7362
7363 if (cp->host_status==HS_COMPLETE)
7364 cp->host_status = HS_FAIL;
7365 }
7366
7367
7368
7369
7370 if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
7371 if (cp->host_status!=HS_COMPLETE || cp->scsi_status!=S_GOOD ||
7372 cp->resid) {
7373 PRINT_ADDR(cmd);
7374 printk ("ERROR: cmd=%x host_status=%x scsi_status=%x "
7375 "data_len=%d residual=%d\n",
7376 cmd->cmnd[0], cp->host_status, cp->scsi_status,
7377 cp->data_len, cp->resid);
7378 }
7379 }
7380
7381#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,99)
7382
7383
7384
7385 cmd->resid = cp->resid;
7386#endif
7387
7388
7389
7390 if ( (cp->host_status == HS_COMPLETE)
7391 && (cp->scsi_status == S_GOOD ||
7392 cp->scsi_status == S_COND_MET)) {
7393
7394
7395
7396
7397
7398 SetScsiResult(cmd, DID_OK, cp->scsi_status);
7399
7400
7401
7402
7403 if (!lp)
7404 ncr_alloc_lcb (np, cp->target, cp->lun);
7405
7406
7407
7408
7409
7410
7411 if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3) &&
7412 cmd->request_bufflen - cp->resid > 7 && !cmd->use_sg) {
7413 sync_scsi_data(np, cmd);
7414 ncr_setup_lcb (np, cp->target, cp->lun,
7415 (char *) cmd->request_buffer);
7416 }
7417
7418
7419
7420
7421
7422 if (lp && lp->usetags && lp->numtags < lp->maxtags) {
7423 ++lp->num_good;
7424 if (lp->num_good >= 1000) {
7425 lp->num_good = 0;
7426 ++lp->numtags;
7427 ncr_setup_tags (np, cp->target, cp->lun);
7428 }
7429 }
7430 } else if ((cp->host_status == HS_COMPLETE)
7431 && (cp->scsi_status == S_CHECK_COND)) {
7432
7433
7434
7435 SetScsiResult(cmd, DID_OK, S_CHECK_COND);
7436
7437 if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
7438 PRINT_ADDR(cmd);
7439 ncr_printl_hex("sense data:", cmd->sense_buffer, 14);
7440 }
7441 } else if ((cp->host_status == HS_COMPLETE)
7442 && (cp->scsi_status == S_CONFLICT)) {
7443
7444
7445
7446 SetScsiResult(cmd, DID_OK, S_CONFLICT);
7447
7448 } else if ((cp->host_status == HS_COMPLETE)
7449 && (cp->scsi_status == S_BUSY ||
7450 cp->scsi_status == S_QUEUE_FULL)) {
7451
7452
7453
7454
7455 SetScsiResult(cmd, DID_OK, cp->scsi_status);
7456
7457 } else if ((cp->host_status == HS_SEL_TIMEOUT)
7458 || (cp->host_status == HS_TIMEOUT)) {
7459
7460
7461
7462
7463 SetScsiResult(cmd, DID_TIME_OUT, cp->scsi_status);
7464
7465 } else if (cp->host_status == HS_RESET) {
7466
7467
7468
7469
7470 SetScsiResult(cmd, DID_RESET, cp->scsi_status);
7471
7472 } else if (cp->host_status == HS_ABORTED) {
7473
7474
7475
7476
7477 SetScsiAbortResult(cmd);
7478
7479 } else {
7480 int did_status;
7481
7482
7483
7484
7485 PRINT_ADDR(cmd);
7486 printk ("COMMAND FAILED (%x %x) @%p.\n",
7487 cp->host_status, cp->scsi_status, cp);
7488
7489 did_status = DID_ERROR;
7490 if (cp->xerr_status & XE_PARITY_ERR)
7491 did_status = DID_PARITY;
7492
7493 SetScsiResult(cmd, did_status, cp->scsi_status);
7494 }
7495
7496
7497
7498
7499
7500 if (tp->usrflag & UF_TRACE) {
7501 PRINT_ADDR(cmd);
7502 printk (" CMD:");
7503 ncr_print_hex(cmd->cmnd, cmd->cmd_len);
7504
7505 if (cp->host_status==HS_COMPLETE) {
7506 switch (cp->scsi_status) {
7507 case S_GOOD:
7508 printk (" GOOD");
7509 break;
7510 case S_CHECK_COND:
7511 printk (" SENSE:");
7512 ncr_print_hex(cmd->sense_buffer, 14);
7513 break;
7514 default:
7515 printk (" STAT: %x\n", cp->scsi_status);
7516 break;
7517 }
7518 } else printk (" HOSTERROR: %x", cp->host_status);
7519 printk ("\n");
7520 }
7521
7522
7523
7524
7525 ncr_free_ccb (np, cp);
7526
7527
7528
7529
7530 if (lp && lp->queuedccbs < lp->queuedepth &&
7531 !xpt_que_empty(&lp->wait_ccbq))
7532 ncr_start_next_ccb(np, lp, 2);
7533
7534
7535
7536
7537 if (np->waiting_list)
7538 requeue_waiting_list(np);
7539
7540
7541
7542
7543 ncr_queue_done_cmd(np, cmd);
7544}
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563int ncr_wakeup_done (ncb_p np)
7564{
7565 ccb_p cp;
7566 int i, n;
7567 u_long dsa;
7568
7569 n = 0;
7570 i = np->dqueueget;
7571 while (1) {
7572 dsa = scr_to_cpu(np->dqueue[i]);
7573 if (!dsa)
7574 break;
7575 np->dqueue[i] = 0;
7576 if ((i = i+2) >= MAX_START*2)
7577 i = 0;
7578
7579 cp = ncr_ccb_from_dsa(np, dsa);
7580 if (cp) {
7581 MEMORY_BARRIER();
7582 ncr_complete (np, cp);
7583 ++n;
7584 }
7585 else
7586 printk (KERN_ERR "%s: bad DSA (%lx) in done queue.\n",
7587 ncr_name(np), dsa);
7588 }
7589 np->dqueueget = i;
7590
7591 return n;
7592}
7593
7594
7595
7596
7597void ncr_wakeup (ncb_p np, u_long code)
7598{
7599 ccb_p cp = np->ccbc;
7600
7601 while (cp) {
7602 if (cp->host_status != HS_IDLE) {
7603 cp->host_status = code;
7604 ncr_complete (np, cp);
7605 }
7606 cp = cp->link_ccb;
7607 }
7608}
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619void ncr_init (ncb_p np, int reset, char * msg, u_long code)
7620{
7621 int i;
7622 u_long phys;
7623
7624
7625
7626
7627
7628 if (reset)
7629 ncr_soft_reset(np);
7630 else {
7631 OUTB (nc_stest3, TE|CSF);
7632 OUTONB (nc_ctest3, CLF);
7633 }
7634
7635
7636
7637
7638
7639 if (msg) printk (KERN_INFO "%s: restart (%s).\n", ncr_name (np), msg);
7640
7641
7642
7643
7644 phys = np->p_squeue;
7645 np->queuedepth = MAX_START - 1;
7646 for (i = 0; i < MAX_START*2; i += 2) {
7647 np->squeue[i] = cpu_to_scr(np->p_idletask);
7648 np->squeue[i+1] = cpu_to_scr(phys + (i+2)*4);
7649 }
7650 np->squeue[MAX_START*2-1] = cpu_to_scr(phys);
7651
7652
7653
7654
7655
7656 np->squeueput = 0;
7657 np->scripth0->startpos[0] = cpu_to_scr(phys);
7658
7659
7660
7661
7662 phys = vtobus(np->dqueue);
7663 for (i = 0; i < MAX_START*2; i += 2) {
7664 np->dqueue[i] = 0;
7665 np->dqueue[i+1] = cpu_to_scr(phys + (i+2)*4);
7666 }
7667 np->dqueue[MAX_START*2-1] = cpu_to_scr(phys);
7668
7669
7670
7671
7672 np->scripth0->done_pos[0] = cpu_to_scr(phys);
7673 np->dqueueget = 0;
7674
7675
7676
7677
7678 ncr_wakeup (np, code);
7679
7680
7681
7682
7683
7684 OUTB (nc_istat, 0x00 );
7685 UDELAY (2000);
7686
7687 OUTB (nc_scntl0, np->rv_scntl0 | 0xc0);
7688
7689 OUTB (nc_scntl1, 0x00);
7690
7691 ncr_selectclock(np, np->rv_scntl3);
7692
7693 OUTB (nc_scid , RRE|np->myaddr);
7694 OUTW (nc_respid, 1ul<<np->myaddr);
7695 OUTB (nc_istat , SIGP );
7696 OUTB (nc_dmode , np->rv_dmode);
7697 OUTB (nc_ctest5, np->rv_ctest5);
7698
7699 OUTB (nc_dcntl , NOCOM|np->rv_dcntl);
7700 OUTB (nc_ctest3, np->rv_ctest3);
7701 OUTB (nc_ctest4, np->rv_ctest4);
7702
7703 if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
7704 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66)){
7705 OUTB (nc_stest2, EXT|np->rv_stest2);
7706
7707 }
7708 OUTB (nc_stest3, TE);
7709 OUTB (nc_stime0, 0x0c);
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719 if (np->device_id == PCI_DEVICE_ID_NCR_53C875)
7720 OUTB (nc_ctest0, (1<<5));
7721 else if (np->device_id == PCI_DEVICE_ID_NCR_53C896 ||
7722 np->device_id == PCI_DEVICE_ID_LSI_53C1010 ||
7723 np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 )
7724 np->rv_ccntl0 |= DPR;
7725
7726
7727
7728
7729 if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)
7730 OUTB(nc_aipcntl1, (1<<3));
7731
7732
7733
7734
7735
7736
7737 if (np->features & (FE_DAC | FE_NOPM)) {
7738 OUTB (nc_ccntl0, np->rv_ccntl0);
7739 OUTB (nc_ccntl1, np->rv_ccntl1);
7740 }
7741
7742
7743
7744
7745
7746
7747 if (np->features & FE_NOPM) {
7748 printk(KERN_INFO "%s: handling phase mismatch from SCRIPTS.\n",
7749 ncr_name(np));
7750 OUTL (nc_pmjad1, NCB_SCRIPTH_PHYS (np, pm_handle));
7751 OUTL (nc_pmjad2, NCB_SCRIPTH_PHYS (np, pm_handle));
7752 }
7753
7754
7755
7756
7757
7758
7759 if (np->features & FE_LED0)
7760 OUTB(nc_gpcntl, INB(nc_gpcntl) & ~0x01);
7761 else if (np->features & FE_LEDC)
7762 OUTB(nc_gpcntl, (INB(nc_gpcntl) & ~0x41) | 0x20);
7763
7764
7765
7766
7767
7768
7769 OUTW (nc_sien , STO|HTH|MA|SGE|UDC|RST|PAR);
7770 OUTB (nc_dien , MDPE|BF|SSI|SIR|IID);
7771
7772
7773
7774
7775
7776 if ( (np->features & FE_ULTRA2) || (np->features & FE_ULTRA3) ) {
7777 OUTONW (nc_sien, SBMC);
7778 np->scsi_mode = INB (nc_stest4) & SMODE;
7779 }
7780
7781
7782
7783
7784
7785
7786
7787
7788 for (i=0;i<MAX_TARGET;i++) {
7789 tcb_p tp = &np->target[i];
7790
7791 tp->to_reset = 0;
7792
7793 tp->sval = 0;
7794 tp->wval = np->rv_scntl3;
7795 tp->uval = np->rv_scntl4;
7796
7797 if (tp->usrsync != 255) {
7798 if (tp->usrsync <= np->maxsync) {
7799 if (tp->usrsync < np->minsync) {
7800 tp->usrsync = np->minsync;
7801 }
7802 }
7803 else
7804 tp->usrsync = 255;
7805 };
7806
7807 if (tp->usrwide > np->maxwide)
7808 tp->usrwide = np->maxwide;
7809
7810 ncr_negotiate (np, tp);
7811 }
7812
7813
7814
7815
7816
7817
7818
7819
7820 if (np->base2_ba) {
7821 if (bootverbose)
7822 printk ("%s: Downloading SCSI SCRIPTS.\n",
7823 ncr_name(np));
7824#ifdef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
7825 if (np->base2_ws == 8192)
7826 phys = NCB_SCRIPTH0_PHYS (np, start_ram64);
7827 else
7828 phys = NCB_SCRIPTH_PHYS (np, start_ram);
7829#else
7830 if (np->base2_ws == 8192) {
7831 memcpy_to_pci(np->base2_va + 4096,
7832 np->scripth0, sizeof(struct scripth));
7833 OUTL (nc_mmws, np->scr_ram_seg);
7834 OUTL (nc_mmrs, np->scr_ram_seg);
7835 OUTL (nc_sfs, np->scr_ram_seg);
7836 phys = NCB_SCRIPTH_PHYS (np, start64);
7837 }
7838 else
7839 phys = NCB_SCRIPT_PHYS (np, init);
7840 memcpy_to_pci(np->base2_va, np->script0, sizeof(struct script));
7841#endif
7842 }
7843 else
7844 phys = NCB_SCRIPT_PHYS (np, init);
7845
7846 np->istat_sem = 0;
7847
7848 OUTL (nc_dsa, np->p_ncb);
7849 OUTL_DSP (phys);
7850}
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860static void ncr_negotiate (struct ncb* np, struct tcb* tp)
7861{
7862
7863
7864
7865
7866 u_long minsync = tp->usrsync;
7867
7868
7869
7870
7871
7872 if (np->scsi_mode && np->scsi_mode == SMODE_SE) {
7873 if (minsync < 12) minsync = 12;
7874 }
7875
7876
7877
7878
7879
7880 if (minsync < np->minsync)
7881 minsync = np->minsync;
7882
7883
7884
7885
7886
7887 if (minsync > np->maxsync)
7888 minsync = 255;
7889
7890 tp->minsync = minsync;
7891 tp->maxoffs = (minsync<255 ? np->maxoffs : 0);
7892
7893
7894
7895
7896
7897 tp->period=0;
7898
7899
7900
7901
7902 tp->widedone=0;
7903}
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915static void ncr_getsync(ncb_p np, u_char sfac, u_char *fakp, u_char *scntl3p)
7916{
7917 u_long clk = np->clock_khz;
7918 int div = np->clock_divn;
7919 u_long fak;
7920 u_long per;
7921 u_long kpc;
7922
7923
7924
7925
7926
7927
7928
7929
7930 if (sfac <= 10) per = 250;
7931 else if (sfac == 11) per = 303;
7932 else if (sfac == 12) per = 500;
7933 else per = 40 * sfac;
7934
7935
7936
7937
7938
7939 kpc = per * clk;
7940 while (--div >= 0)
7941 if (kpc >= (div_10M[div] << 2)) break;
7942
7943
7944
7945
7946
7947 fak = (kpc - 1) / div_10M[div] + 1;
7948
7949#if 0
7950
7951 per = (fak * div_10M[div]) / clk;
7952
7953
7954
7955
7956
7957
7958 if (div >= 1 && fak < 8) {
7959 u_long fak2, per2;
7960 fak2 = (kpc - 1) / div_10M[div-1] + 1;
7961 per2 = (fak2 * div_10M[div-1]) / clk;
7962 if (per2 < per && fak2 <= 8) {
7963 fak = fak2;
7964 per = per2;
7965 --div;
7966 }
7967 }
7968#endif
7969
7970 if (fak < 4) fak = 4;
7971
7972
7973
7974
7975 *fakp = fak - 4;
7976
7977
7978
7979
7980
7981
7982
7983 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
7984 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
7985 *scntl3p = (div+1) << 4;
7986 *fakp = 0;
7987 }
7988 else {
7989 *scntl3p = ((div+1) << 4) + (sfac < 25 ? 0x80 : 0);
7990 *fakp = fak - 4;
7991 }
7992}
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002static void ncr_get_xfer_info(ncb_p np, tcb_p tp, u_char *factor,
8003 u_char *offset, u_char *width)
8004{
8005
8006 u_char idiv;
8007 u_long period;
8008
8009 *width = (tp->wval & EWS) ? 1 : 0;
8010
8011 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8012 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
8013 *offset = (tp->sval & 0x3f);
8014 else
8015 *offset = (tp->sval & 0x1f);
8016
8017
8018
8019
8020
8021
8022
8023
8024 idiv = (tp->wval>>4) & 0x07;
8025
8026 if ( *offset && idiv ) {
8027 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8028 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)){
8029 if (tp->uval & 0x80)
8030 period = (2*div_10M[idiv-1])/np->clock_khz;
8031 else
8032 period = (4*div_10M[idiv-1])/np->clock_khz;
8033 }
8034 else
8035 period = (((tp->sval>>5)+4)*div_10M[idiv-1])/np->clock_khz;
8036 }
8037 else
8038 period = 0xffff;
8039
8040 if (period <= 125) *factor = 9;
8041 else if (period <= 250) *factor = 10;
8042 else if (period <= 303) *factor = 11;
8043 else if (period <= 500) *factor = 12;
8044 else *factor = (period + 40 - 1) / 40;
8045
8046}
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057static void ncr_set_sync_wide_status (ncb_p np, u_char target)
8058{
8059 ccb_p cp = np->ccbc;
8060 tcb_p tp = &np->target[target];
8061
8062
8063
8064
8065
8066
8067
8068 OUTB (nc_sxfer, tp->sval);
8069 OUTB (nc_scntl3, tp->wval);
8070 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8071 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
8072 OUTB (nc_scntl4, tp->uval);
8073
8074
8075
8076
8077 for (cp = np->ccbc; cp; cp = cp->link_ccb) {
8078 if (cp->host_status == HS_IDLE)
8079 continue;
8080 if (cp->target != target)
8081 continue;
8082 cp->phys.select.sel_scntl3 = tp->wval;
8083 cp->phys.select.sel_sxfer = tp->sval;
8084 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8085 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
8086 cp->phys.select.sel_scntl4 = tp->uval;
8087 };
8088}
8089
8090
8091
8092
8093
8094
8095
8096
8097static void ncr_setsync (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer,
8098 u_char scntl4)
8099{
8100 tcb_p tp;
8101 u_char target = INB (nc_sdid) & 0x0f;
8102 u_char idiv;
8103 u_char offset;
8104
8105 assert (cp);
8106 if (!cp) return;
8107
8108 assert (target == (cp->target & 0xf));
8109
8110 tp = &np->target[target];
8111
8112 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8113 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
8114 offset = sxfer & 0x3f;
8115 scntl3 = (scntl3 & 0xf0) | (tp->wval & EWS);
8116 scntl4 = (scntl4 & 0x80);
8117 }
8118 else {
8119 offset = sxfer & 0x1f;
8120 if (!scntl3 || !offset)
8121 scntl3 = np->rv_scntl3;
8122
8123 scntl3 = (scntl3 & 0xf0) | (tp->wval & EWS) |
8124 (np->rv_scntl3 & 0x07);
8125 }
8126
8127
8128
8129
8130
8131
8132
8133 idiv = ((scntl3 >> 4) & 0x7);
8134 if ( offset && idiv) {
8135 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8136 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
8137
8138
8139
8140
8141 if (scntl4 & 0x80)
8142 tp->period = (2*div_10M[idiv-1])/np->clock_khz;
8143 else
8144 tp->period = (4*div_10M[idiv-1])/np->clock_khz;
8145 }
8146 else
8147 tp->period = (((sxfer>>5)+4)*div_10M[idiv-1])/np->clock_khz;
8148 }
8149 else
8150 tp->period = 0xffff;
8151
8152
8153
8154
8155
8156 if (tp->sval == sxfer && tp->wval == scntl3 && tp->uval == scntl4) return;
8157 tp->sval = sxfer;
8158 tp->wval = scntl3;
8159 tp->uval = scntl4;
8160
8161
8162
8163
8164
8165
8166 if ( bootverbose < 2 && (cp->host_flags & HF_AUTO_SENSE))
8167 goto next;
8168 PRINT_TARGET(np, target);
8169 if (offset) {
8170 unsigned f10 = 100000 << (tp->widedone ? tp->widedone -1 : 0);
8171 unsigned mb10 = (f10 + tp->period/2) / tp->period;
8172 char *scsi;
8173
8174
8175
8176
8177 if ((tp->period <= 2000) &&
8178 (np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
8179 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
8180 OUTOFFB (nc_stest2, EXT);
8181
8182
8183
8184
8185 if (tp->period < 250) scsi = "FAST-80";
8186 else if (tp->period < 500) scsi = "FAST-40";
8187 else if (tp->period < 1000) scsi = "FAST-20";
8188 else if (tp->period < 2000) scsi = "FAST-10";
8189 else scsi = "FAST-5";
8190
8191 printk ("%s %sSCSI %d.%d MB/s (%d.%d ns, offset %d)\n", scsi,
8192 tp->widedone > 1 ? "WIDE " : "",
8193 mb10 / 10, mb10 % 10, tp->period / 10, tp->period % 10,
8194 offset);
8195 } else
8196 printk ("%sasynchronous.\n", tp->widedone > 1 ? "wide " : "");
8197next:
8198
8199
8200
8201
8202 ncr_set_sync_wide_status(np, target);
8203}
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide, u_char ack)
8217{
8218 u_short target = INB (nc_sdid) & 0x0f;
8219 tcb_p tp;
8220 u_char scntl3;
8221 u_char sxfer;
8222
8223 assert (cp);
8224 if (!cp) return;
8225
8226 assert (target == (cp->target & 0xf));
8227
8228 tp = &np->target[target];
8229 tp->widedone = wide+1;
8230 scntl3 = (tp->wval & (~EWS)) | (wide ? EWS : 0);
8231
8232 sxfer = ack ? 0 : tp->sval;
8233
8234
8235
8236
8237 if (tp->sval == sxfer && tp->wval == scntl3) return;
8238 tp->sval = sxfer;
8239 tp->wval = scntl3;
8240
8241
8242
8243
8244 if (bootverbose >= 2) {
8245 PRINT_TARGET(np, target);
8246 if (scntl3 & EWS)
8247 printk ("WIDE SCSI (16 bit) enabled.\n");
8248 else
8249 printk ("WIDE SCSI disabled.\n");
8250 }
8251
8252
8253
8254
8255
8256 ncr_set_sync_wide_status(np, target);
8257}
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268static void ncr_setsyncwide (ncb_p np, ccb_p cp, u_char scntl3, u_char sxfer,
8269 u_char scntl4, u_char wide)
8270{
8271 tcb_p tp;
8272 u_char target = INB (nc_sdid) & 0x0f;
8273 u_char idiv;
8274 u_char offset;
8275
8276 assert (cp);
8277 if (!cp) return;
8278
8279 assert (target == (cp->target & 0xf));
8280
8281 tp = &np->target[target];
8282 tp->widedone = wide+1;
8283
8284 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8285 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
8286 offset = sxfer & 0x3f;
8287 scntl3 = (scntl3 & 0xf0) | (wide ? EWS : 0);
8288 scntl4 = (scntl4 & 0x80);
8289 }
8290 else {
8291 offset = sxfer & 0x1f;
8292 if (!scntl3 || !offset)
8293 scntl3 = np->rv_scntl3;
8294
8295 scntl3 = (scntl3 & 0xf0) | (wide ? EWS : 0) |
8296 (np->rv_scntl3 & 0x07);
8297 }
8298
8299
8300
8301
8302
8303
8304
8305 idiv = ((scntl3 >> 4) & 0x7);
8306 if ( offset && idiv) {
8307 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8308 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
8309
8310
8311
8312
8313 if (scntl4 & 0x80)
8314 tp->period = (2*div_10M[idiv-1])/np->clock_khz;
8315 else
8316 tp->period = (4*div_10M[idiv-1])/np->clock_khz;
8317 }
8318 else
8319 tp->period = (((sxfer>>5)+4)*div_10M[idiv-1])/np->clock_khz;
8320 }
8321 else
8322 tp->period = 0xffff;
8323
8324
8325
8326
8327
8328 if (tp->sval == sxfer && tp->wval == scntl3 && tp->uval == scntl4) return;
8329 tp->sval = sxfer;
8330 tp->wval = scntl3;
8331 tp->uval = scntl4;
8332
8333
8334
8335
8336
8337
8338 if ( bootverbose < 2 && (cp->host_flags & HF_AUTO_SENSE))
8339 goto next;
8340 PRINT_TARGET(np, target);
8341 if (offset) {
8342 unsigned f10 = 100000 << (tp->widedone ? tp->widedone -1 : 0);
8343 unsigned mb10 = (f10 + tp->period/2) / tp->period;
8344 char *scsi;
8345
8346
8347
8348
8349 if ((tp->period <= 2000) &&
8350 (np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
8351 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
8352 OUTOFFB (nc_stest2, EXT);
8353
8354
8355
8356
8357 if (tp->period < 250) scsi = "FAST-80";
8358 else if (tp->period < 500) scsi = "FAST-40";
8359 else if (tp->period < 1000) scsi = "FAST-20";
8360 else if (tp->period < 2000) scsi = "FAST-10";
8361 else scsi = "FAST-5";
8362
8363 printk ("%s %sSCSI %d.%d MB/s (%d.%d ns, offset %d)\n", scsi,
8364 tp->widedone > 1 ? "WIDE " : "",
8365 mb10 / 10, mb10 % 10, tp->period / 10, tp->period % 10,
8366 offset);
8367 } else
8368 printk ("%sasynchronous.\n", tp->widedone > 1 ? "wide " : "");
8369next:
8370
8371
8372
8373
8374 ncr_set_sync_wide_status(np, target);
8375}
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387static void ncr_setup_tags (ncb_p np, u_char tn, u_char ln)
8388{
8389 tcb_p tp = &np->target[tn];
8390 lcb_p lp = ncr_lp(np, tp, ln);
8391 u_short reqtags, maxdepth;
8392
8393
8394
8395
8396 if ((!tp) || (!lp))
8397 return;
8398
8399
8400
8401
8402 if (!lp->scdev_depth)
8403 return;
8404
8405
8406
8407
8408
8409
8410 maxdepth = lp->scdev_depth;
8411 if (maxdepth > lp->maxnxs) maxdepth = lp->maxnxs;
8412 if (lp->maxtags > maxdepth) lp->maxtags = maxdepth;
8413 if (lp->numtags > maxdepth) lp->numtags = maxdepth;
8414
8415
8416
8417
8418
8419
8420 if ((lp->inq_byte7 & INQ7_QUEUE) && lp->numtags > 1) {
8421 reqtags = lp->numtags;
8422 } else {
8423 reqtags = 1;
8424 };
8425
8426
8427
8428
8429 lp->numtags = reqtags;
8430 if (lp->numtags > lp->maxtags)
8431 lp->maxtags = lp->numtags;
8432
8433
8434
8435
8436
8437 if (reqtags > 1 && lp->usetags) {
8438 if (lp->queuedepth == reqtags)
8439 return;
8440 lp->queuedepth = reqtags;
8441 }
8442 else if (reqtags <= 1 && !lp->usetags) {
8443 lp->queuedepth = reqtags;
8444 return;
8445 }
8446 else {
8447 if (lp->busyccbs)
8448 return;
8449 lp->queuedepth = reqtags;
8450 lp->usetags = reqtags > 1 ? 1 : 0;
8451 }
8452
8453
8454
8455
8456 lp->resel_task = lp->usetags?
8457 cpu_to_scr(NCB_SCRIPT_PHYS(np, resel_tag)) :
8458 cpu_to_scr(NCB_SCRIPT_PHYS(np, resel_notag));
8459
8460
8461
8462
8463 if (bootverbose) {
8464 PRINT_LUN(np, tn, ln);
8465 if (lp->usetags)
8466 printk("tagged command queue depth set to %d\n", reqtags);
8467 else
8468 printk("tagged command queueing disabled\n");
8469 }
8470}
8471
8472
8473
8474
8475
8476
8477
8478
8479#ifdef SCSI_NCR_USER_COMMAND_SUPPORT
8480
8481static void ncr_usercmd (ncb_p np)
8482{
8483 u_char t;
8484 tcb_p tp;
8485 int ln;
8486 u_long size;
8487
8488 switch (np->user.cmd) {
8489 case 0: return;
8490
8491 case UC_SETDEBUG:
8492#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
8493 ncr_debug = np->user.data;
8494#endif
8495 break;
8496
8497 case UC_SETORDER:
8498 np->order = np->user.data;
8499 break;
8500
8501 case UC_SETVERBOSE:
8502 np->verbose = np->user.data;
8503 break;
8504
8505 default:
8506
8507
8508
8509
8510
8511 for (t = 0; t < MAX_TARGET; t++) {
8512 if (!((np->user.target >> t) & 1))
8513 continue;
8514 tp = &np->target[t];
8515
8516 switch (np->user.cmd) {
8517
8518 case UC_SETSYNC:
8519 tp->usrsync = np->user.data;
8520 ncr_negotiate (np, tp);
8521 break;
8522
8523 case UC_SETWIDE:
8524 size = np->user.data;
8525 if (size > np->maxwide)
8526 size=np->maxwide;
8527 tp->usrwide = size;
8528 ncr_negotiate (np, tp);
8529 break;
8530
8531 case UC_SETTAGS:
8532 tp->usrtags = np->user.data;
8533 for (ln = 0; ln < MAX_LUN; ln++) {
8534 lcb_p lp;
8535 lp = ncr_lp(np, tp, ln);
8536 if (!lp)
8537 continue;
8538 lp->numtags = np->user.data;
8539 lp->maxtags = lp->numtags;
8540 ncr_setup_tags (np, t, ln);
8541 }
8542 break;
8543
8544 case UC_RESETDEV:
8545 tp->to_reset = 1;
8546 np->istat_sem = SEM;
8547 OUTB (nc_istat, SIGP|SEM);
8548 break;
8549
8550 case UC_CLEARDEV:
8551 for (ln = 0; ln < MAX_LUN; ln++) {
8552 lcb_p lp;
8553 lp = ncr_lp(np, tp, ln);
8554 if (lp)
8555 lp->to_clear = 1;
8556 }
8557 np->istat_sem = SEM;
8558 OUTB (nc_istat, SIGP|SEM);
8559 break;
8560
8561 case UC_SETFLAG:
8562 tp->usrflag = np->user.data;
8563 break;
8564 }
8565 }
8566 break;
8567 }
8568 np->user.cmd=0;
8569}
8570#endif
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586static void ncr_timeout (ncb_p np)
8587{
8588 u_long thistime = ktime_get(0);
8589
8590
8591
8592
8593
8594
8595
8596 if (np->release_stage) {
8597 if (np->release_stage == 1) np->release_stage = 2;
8598 return;
8599 }
8600
8601#ifdef SCSI_NCR_PCIQ_BROKEN_INTR
8602 np->timer.expires = ktime_get((HZ+9)/10);
8603#else
8604 np->timer.expires = ktime_get(SCSI_NCR_TIMER_INTERVAL);
8605#endif
8606 add_timer(&np->timer);
8607
8608
8609
8610
8611
8612 if (np->settle_time) {
8613 if (np->settle_time <= thistime) {
8614 if (bootverbose > 1)
8615 printk("%s: command processing resumed\n", ncr_name(np));
8616 np->settle_time = 0;
8617 requeue_waiting_list(np);
8618 }
8619 return;
8620 }
8621
8622
8623
8624
8625 if (np->lasttime + 4*HZ < thistime) {
8626 np->lasttime = thistime;
8627 }
8628
8629#ifdef SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
8630
8631
8632
8633
8634
8635
8636
8637
8638 ncr_wakeup_done(np);
8639#endif
8640
8641#ifdef SCSI_NCR_PCIQ_BROKEN_INTR
8642 if (INB(nc_istat) & (INTF|SIP|DIP)) {
8643
8644
8645
8646
8647 if (DEBUG_FLAGS & DEBUG_TINY) printk ("{");
8648 ncr_exception (np);
8649 if (DEBUG_FLAGS & DEBUG_TINY) printk ("}");
8650 }
8651#endif
8652}
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684static void ncr_log_hard_error(ncb_p np, u_short sist, u_char dstat)
8685{
8686 u_int32 dsp;
8687 int script_ofs;
8688 int script_size;
8689 char *script_name;
8690 u_char *script_base;
8691 int i;
8692
8693 dsp = INL (nc_dsp);
8694
8695 if (dsp > np->p_script && dsp <= np->p_script + sizeof(struct script)) {
8696 script_ofs = dsp - np->p_script;
8697 script_size = sizeof(struct script);
8698 script_base = (u_char *) np->script0;
8699 script_name = "script";
8700 }
8701 else if (np->p_scripth < dsp &&
8702 dsp <= np->p_scripth + sizeof(struct scripth)) {
8703 script_ofs = dsp - np->p_scripth;
8704 script_size = sizeof(struct scripth);
8705 script_base = (u_char *) np->scripth0;
8706 script_name = "scripth";
8707 } else {
8708 script_ofs = dsp;
8709 script_size = 0;
8710 script_base = 0;
8711 script_name = "mem";
8712 }
8713
8714 printk ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%s %x:%08x).\n",
8715 ncr_name (np), (unsigned)INB (nc_sdid)&0x0f, dstat, sist,
8716 (unsigned)INB (nc_socl), (unsigned)INB (nc_sbcl), (unsigned)INB (nc_sbdl),
8717 (unsigned)INB (nc_sxfer),(unsigned)INB (nc_scntl3), script_name, script_ofs,
8718 (unsigned)INL (nc_dbc));
8719
8720 if (((script_ofs & 3) == 0) &&
8721 (unsigned)script_ofs < script_size) {
8722 printk ("%s: script cmd = %08x\n", ncr_name(np),
8723 scr_to_cpu((int) *(ncrcmd *)(script_base + script_ofs)));
8724 }
8725
8726 printk ("%s: regdump:", ncr_name(np));
8727 for (i=0; i<24;i++)
8728 printk (" %02x", (unsigned)INB_OFF(i));
8729 printk (".\n");
8730}
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800void ncr_exception (ncb_p np)
8801{
8802 u_char istat, istatc;
8803 u_char dstat;
8804 u_short sist;
8805 int i;
8806
8807
8808
8809
8810
8811
8812
8813
8814 istat = INB (nc_istat);
8815 if (istat & INTF) {
8816 OUTB (nc_istat, (istat & SIGP) | INTF | np->istat_sem);
8817 istat = INB (nc_istat);
8818 if (DEBUG_FLAGS & DEBUG_TINY) printk ("F ");
8819 (void)ncr_wakeup_done (np);
8820 };
8821
8822 if (!(istat & (SIP|DIP)))
8823 return;
8824
8825#if 0
8826 if (istat & CABRT)
8827 OUTB (nc_istat, CABRT);
8828#endif
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846 sist = 0;
8847 dstat = 0;
8848 istatc = istat;
8849 do {
8850 if (istatc & SIP)
8851 sist |= INW (nc_sist);
8852 if (istatc & DIP)
8853 dstat |= INB (nc_dstat);
8854 istatc = INB (nc_istat);
8855 istat |= istatc;
8856 } while (istatc & (SIP|DIP));
8857
8858 if (DEBUG_FLAGS & DEBUG_TINY)
8859 printk ("<%d|%x:%x|%x:%x>",
8860 (int)INB(nc_scr0),
8861 dstat,sist,
8862 (unsigned)INL(nc_dsp),
8863 (unsigned)INL(nc_dbc));
8864
8865
8866
8867
8868
8869 MEMORY_BARRIER();
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886 if (!(sist & (STO|GEN|HTH|SGE|UDC|SBMC|RST)) &&
8887 !(dstat & (MDPE|BF|ABRT|IID))) {
8888 if (sist & PAR) ncr_int_par (np, sist);
8889 else if (sist & MA) ncr_int_ma (np);
8890 else if (dstat & SIR) ncr_int_sir (np);
8891 else if (dstat & SSI) OUTONB_STD ();
8892 else goto unknown_int;
8893 return;
8894 };
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909 if (sist & RST) {
8910 ncr_init (np, 1, bootverbose ? "scsi reset" : NULL, HS_RESET);
8911 return;
8912 };
8913
8914 OUTB (nc_ctest3, np->rv_ctest3 | CLF);
8915 OUTB (nc_stest3, TE|CSF);
8916
8917 if (!(sist & (GEN|HTH|SGE)) &&
8918 !(dstat & (MDPE|BF|ABRT|IID))) {
8919 if (sist & SBMC) ncr_int_sbmc (np);
8920 else if (sist & STO) ncr_int_sto (np);
8921 else if (sist & UDC) ncr_int_udc (np);
8922 else goto unknown_int;
8923 return;
8924 };
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934 if (ktime_exp(np->regtime)) {
8935 np->regtime = ktime_get(10*HZ);
8936 for (i = 0; i<sizeof(np->regdump); i++)
8937 ((char*)&np->regdump)[i] = INB_OFF(i);
8938 np->regdump.nc_dstat = dstat;
8939 np->regdump.nc_sist = sist;
8940 };
8941
8942 ncr_log_hard_error(np, sist, dstat);
8943
8944 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
8945 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)) {
8946 u_char ctest4_o, ctest4_m;
8947 u_char shadow;
8948
8949
8950
8951
8952
8953 ctest4_o = INB(nc_ctest4);
8954
8955 OUTB(nc_ctest4, ctest4_o | 0x10);
8956
8957 ctest4_m = INB(nc_ctest4);
8958 shadow = INW_OFF(0x42);
8959
8960 OUTB(nc_ctest4, ctest4_o);
8961
8962 printk("%s: ctest4/sist original 0x%x/0x%X mod: 0x%X/0x%x\n",
8963 ncr_name(np), ctest4_o, sist, ctest4_m, shadow);
8964 }
8965
8966 if ((sist & (GEN|HTH|SGE)) ||
8967 (dstat & (MDPE|BF|ABRT|IID))) {
8968 ncr_start_reset(np);
8969 return;
8970 };
8971
8972unknown_int:
8973
8974
8975
8976
8977
8978 printk( "%s: unknown interrupt(s) ignored, "
8979 "ISTAT=0x%x DSTAT=0x%x SIST=0x%x\n",
8980 ncr_name(np), istat, dstat, sist);
8981}
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015static void ncr_recover_scsi_int (ncb_p np, u_char hsts)
9016{
9017 u_int32 dsp = INL (nc_dsp);
9018 u_int32 dsa = INL (nc_dsa);
9019 ccb_p cp = ncr_ccb_from_dsa(np, dsa);
9020
9021
9022
9023
9024
9025
9026 if ((!(dsp > NCB_SCRIPT_PHYS (np, getjob_begin) &&
9027 dsp < NCB_SCRIPT_PHYS (np, getjob_end) + 1)) &&
9028 (!(dsp > NCB_SCRIPT_PHYS (np, ungetjob) &&
9029 dsp < NCB_SCRIPT_PHYS (np, reselect) + 1)) &&
9030 (!(dsp > NCB_SCRIPTH_PHYS (np, sel_for_abort) &&
9031 dsp < NCB_SCRIPTH_PHYS (np, sel_for_abort_1) + 1)) &&
9032 (!(dsp > NCB_SCRIPT_PHYS (np, done) &&
9033 dsp < NCB_SCRIPT_PHYS (np, done_end) + 1))) {
9034 if (cp) {
9035 cp->host_status = hsts;
9036 ncr_complete (np, cp);
9037 }
9038 OUTL (nc_dsa, DSA_INVALID);
9039 OUTB (nc_ctest3, np->rv_ctest3 | CLF);
9040 OUTB (nc_stest3, TE|CSF);
9041 OUTL_DSP (NCB_SCRIPT_PHYS (np, start));
9042 }
9043 else
9044 goto reset_all;
9045
9046 return;
9047
9048reset_all:
9049 ncr_start_reset(np);
9050}
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068void ncr_int_sto (ncb_p np)
9069{
9070 u_int32 dsp = INL (nc_dsp);
9071
9072 if (DEBUG_FLAGS & DEBUG_TINY) printk ("T");
9073
9074 if (dsp == NCB_SCRIPT_PHYS (np, wf_sel_done) + 8 ||
9075 !(driver_setup.recovery & 1))
9076 ncr_recover_scsi_int(np, HS_SEL_TIMEOUT);
9077 else
9078 ncr_start_reset(np);
9079}
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089void ncr_int_udc (ncb_p np)
9090{
9091 u_int32 dsa = INL (nc_dsa);
9092 ccb_p cp = ncr_ccb_from_dsa(np, dsa);
9093
9094
9095
9096
9097
9098
9099
9100 if (cp) {
9101 tcb_p tp = &np->target[cp->target];
9102 if (tp->ppr_negotiation == 1)
9103 tp->ppr_negotiation = 0;
9104 }
9105
9106 printk ("%s: unexpected disconnect\n", ncr_name(np));
9107 ncr_recover_scsi_int(np, HS_UNEXPECTED);
9108}
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127static void ncr_int_sbmc (ncb_p np)
9128{
9129 u_char scsi_mode = INB (nc_stest4) & SMODE;
9130
9131 printk("%s: SCSI bus mode change from %x to %x.\n",
9132 ncr_name(np), np->scsi_mode, scsi_mode);
9133
9134 np->scsi_mode = scsi_mode;
9135
9136
9137
9138
9139
9140
9141 np->settle_time = ktime_get(1*HZ);
9142 ncr_init (np, 0, bootverbose ? "scsi mode change" : NULL, HS_RESET);
9143}
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175static void ncr_int_par (ncb_p np, u_short sist)
9176{
9177 u_char hsts = INB (HS_PRT);
9178 u_int32 dsp = INL (nc_dsp);
9179 u_int32 dbc = INL (nc_dbc);
9180 u_int32 dsa = INL (nc_dsa);
9181 u_char sbcl = INB (nc_sbcl);
9182 u_char cmd = dbc >> 24;
9183 int phase = cmd & 7;
9184 ccb_p cp = ncr_ccb_from_dsa(np, dsa);
9185
9186 printk("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n",
9187 ncr_name(np), hsts, dbc, sbcl);
9188
9189
9190
9191
9192 if (!(INB (nc_scntl1) & ISCON)) {
9193 if (!(driver_setup.recovery & 1)) {
9194 ncr_recover_scsi_int(np, HS_FAIL);
9195 return;
9196 }
9197 goto reset_all;
9198 }
9199
9200
9201
9202
9203
9204 if (!cp)
9205 goto reset_all;
9206
9207
9208
9209
9210
9211 if ((cmd & 0xc0) || !(phase & 1) || !(sbcl & 0x8))
9212 goto reset_all;
9213
9214
9215
9216
9217 OUTONB (HF_PRT, HF_EXT_ERR);
9218 cp->xerr_status |= XE_PARITY_ERR;
9219
9220
9221
9222
9223 np->msgout[0] = (phase == 7) ? M_PARITY : M_ID_ERROR;
9224
9225#ifdef SCSI_NCR_INTEGRITY_CHECKING
9226
9227
9228
9229 if (np->check_integrity)
9230 np->check_integ_par = np->msgout[0];
9231#endif
9232
9233
9234
9235
9236
9237
9238
9239
9240 if ((phase == 1) || (phase == 5)) {
9241
9242 if (dsp == NCB_SCRIPTH_PHYS (np, pm_handle))
9243 OUTL_DSP (dsp);
9244
9245 else if (sist & MA)
9246 ncr_int_ma (np);
9247
9248 else {
9249 OUTL (nc_temp, dsp);
9250 OUTL_DSP (NCB_SCRIPT_PHYS (np, dispatch));
9251 }
9252 }
9253 else
9254 OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
9255 return;
9256
9257reset_all:
9258 ncr_start_reset(np);
9259 return;
9260}
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276static void ncr_int_ma (ncb_p np)
9277{
9278 u_int32 dbc;
9279 u_int32 rest;
9280 u_int32 dsp;
9281 u_int32 dsa;
9282 u_int32 nxtdsp;
9283 u_int32 *vdsp;
9284 u_int32 oadr, olen;
9285 u_int32 *tblp;
9286 u_int32 newcmd;
9287 u_int delta;
9288 u_char cmd;
9289 u_char hflags, hflags0;
9290 struct pm_ctx *pm;
9291 ccb_p cp;
9292
9293 dsp = INL (nc_dsp);
9294 dbc = INL (nc_dbc);
9295 dsa = INL (nc_dsa);
9296
9297 cmd = dbc >> 24;
9298 rest = dbc & 0xffffff;
9299 delta = 0;
9300
9301
9302
9303
9304 cp = ncr_ccb_from_dsa(np, dsa);
9305
9306 if (DEBUG_FLAGS & DEBUG_PHASE)
9307 printk("CCB = %2x %2x %2x %2x %2x %2x\n",
9308 cp->cmd->cmnd[0], cp->cmd->cmnd[1], cp->cmd->cmnd[2],
9309 cp->cmd->cmnd[3], cp->cmd->cmnd[4], cp->cmd->cmnd[5]);
9310
9311
9312
9313
9314
9315
9316
9317 if ((cmd & 7) != 1 && (cmd & 7) != 5) {
9318 u_int32 dfifo;
9319 u_char ss0, ss2;
9320
9321
9322
9323
9324
9325 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
9326 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
9327 delta = INL(nc_dfbc) & 0xffff;
9328 else {
9329 dfifo = INL(nc_dfifo);
9330
9331
9332
9333
9334
9335
9336 if (dfifo & (DFS << 16))
9337 delta = ((((dfifo >> 8) & 0x300) |
9338 (dfifo & 0xff)) - rest) & 0x3ff;
9339 else
9340 delta = ((dfifo & 0xff) - rest) & 0x7f;
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350 }
9351
9352 rest += delta;
9353 ss0 = INB (nc_sstat0);
9354 if (ss0 & OLF) rest++;
9355 if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
9356 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66) && (ss0 & ORF))
9357 rest++;
9358 if (cp && (cp->phys.select.sel_scntl3 & EWS)) {
9359 ss2 = INB (nc_sstat2);
9360 if (ss2 & OLF1) rest++;
9361 if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
9362 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66) && (ss2 & ORF))
9363 rest++;
9364 };
9365
9366
9367
9368
9369 OUTB (nc_ctest3, np->rv_ctest3 | CLF);
9370 OUTB (nc_stest3, TE|CSF);
9371 }
9372
9373
9374
9375
9376
9377 if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE))
9378 printk ("P%x%x RL=%d D=%d ", cmd&7, INB(nc_sbcl)&7,
9379 (unsigned) rest, (unsigned) delta);
9380
9381
9382
9383
9384
9385 vdsp = 0;
9386 nxtdsp = 0;
9387 if (dsp > np->p_script &&
9388 dsp <= np->p_script + sizeof(struct script)) {
9389 vdsp = (u_int32 *)((char*)np->script0 + (dsp-np->p_script-8));
9390 nxtdsp = dsp;
9391 }
9392 else if (dsp > np->p_scripth &&
9393 dsp <= np->p_scripth + sizeof(struct scripth)) {
9394 vdsp = (u_int32 *)((char*)np->scripth0 + (dsp-np->p_scripth-8));
9395 nxtdsp = dsp;
9396 }
9397
9398
9399
9400
9401 if (DEBUG_FLAGS & DEBUG_PHASE) {
9402 printk ("\nCP=%p DSP=%x NXT=%x VDSP=%p CMD=%x ",
9403 cp, (unsigned)dsp, (unsigned)nxtdsp, vdsp, cmd);
9404 };
9405
9406 if (!vdsp) {
9407 printk ("%s: interrupted SCRIPT address not found.\n",
9408 ncr_name (np));
9409 goto reset_all;
9410 }
9411
9412 if (!cp) {
9413 printk ("%s: SCSI phase error fixup: CCB already dequeued.\n",
9414 ncr_name (np));
9415 goto reset_all;
9416 }
9417
9418
9419
9420
9421
9422 oadr = scr_to_cpu(vdsp[1]);
9423
9424 if (cmd & 0x10) {
9425 tblp = (u_int32 *) ((char*) &cp->phys + oadr);
9426 olen = scr_to_cpu(tblp[0]);
9427 oadr = scr_to_cpu(tblp[1]);
9428 } else {
9429 tblp = (u_int32 *) 0;
9430 olen = scr_to_cpu(vdsp[0]) & 0xffffff;
9431 };
9432
9433 if (DEBUG_FLAGS & DEBUG_PHASE) {
9434 printk ("OCMD=%x\nTBLP=%p OLEN=%x OADR=%x\n",
9435 (unsigned) (scr_to_cpu(vdsp[0]) >> 24),
9436 tblp,
9437 (unsigned) olen,
9438 (unsigned) oadr);
9439 };
9440
9441
9442
9443
9444
9445
9446
9447 if (((cmd & 2) ? cmd : (cmd & ~4)) != (scr_to_cpu(vdsp[0]) >> 24)) {
9448 PRINT_ADDR(cp->cmd);
9449 printk ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
9450 (unsigned)cmd, (unsigned)scr_to_cpu(vdsp[0]) >> 24);
9451
9452 goto reset_all;
9453 };
9454
9455
9456
9457
9458
9459
9460 if (cmd & 0x02) {
9461 PRINT_ADDR(cp->cmd);
9462 printk ("phase change %x-%x %d@%08x resid=%d.\n",
9463 cmd&7, INB(nc_sbcl)&7, (unsigned)olen,
9464 (unsigned)oadr, (unsigned)rest);
9465 goto unexpected_phase;
9466 };
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477 hflags0 = INB (HF_PRT);
9478 hflags = hflags0;
9479
9480 if (hflags & (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED)) {
9481 if (hflags & HF_IN_PM0)
9482 nxtdsp = scr_to_cpu(cp->phys.pm0.ret);
9483 else if (hflags & HF_IN_PM1)
9484 nxtdsp = scr_to_cpu(cp->phys.pm1.ret);
9485
9486 if (hflags & HF_DP_SAVED)
9487 hflags ^= HF_ACT_PM;
9488 }
9489
9490 if (!(hflags & HF_ACT_PM)) {
9491 pm = &cp->phys.pm0;
9492 newcmd = NCB_SCRIPT_PHYS(np, pm0_data);
9493 }
9494 else {
9495 pm = &cp->phys.pm1;
9496 newcmd = NCB_SCRIPT_PHYS(np, pm1_data);
9497 }
9498
9499 hflags &= ~(HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED);
9500 if (hflags != hflags0)
9501 OUTB (HF_PRT, hflags);
9502
9503
9504
9505
9506
9507 pm->sg.addr = cpu_to_scr(oadr + olen - rest);
9508 pm->sg.size = cpu_to_scr(rest);
9509 pm->ret = cpu_to_scr(nxtdsp);
9510
9511
9512
9513
9514
9515
9516
9517 nxtdsp = NCB_SCRIPT_PHYS (np, dispatch);
9518 if ( ((cmd & 7) == 1 || (cmd & 7) == 5)
9519 && cp && (cp->phys.select.sel_scntl3 & EWS) &&
9520 (INB (nc_scntl2) & WSR)) {
9521 u32 tmp;
9522
9523#ifdef SYM_DEBUG_PM_WITH_WSR
9524 PRINT_ADDR(cp);
9525 printk ("MA interrupt with WSR set - "
9526 "pm->sg.addr=%x - pm->sg.size=%d\n",
9527 pm->sg.addr, pm->sg.size);
9528#endif
9529
9530
9531
9532
9533
9534 tmp = scr_to_cpu(pm->sg.addr);
9535 cp->phys.wresid.addr = cpu_to_scr(tmp);
9536 pm->sg.addr = cpu_to_scr(tmp + 1);
9537 tmp = scr_to_cpu(pm->sg.size);
9538 cp->phys.wresid.size = cpu_to_scr((tmp&0xff000000) | 1);
9539 pm->sg.size = cpu_to_scr(tmp - 1);
9540
9541
9542
9543
9544
9545 if ((tmp&0xffffff) == 1)
9546 newcmd = pm->ret;
9547
9548
9549
9550
9551
9552 nxtdsp = NCB_SCRIPTH_PHYS (np, wsr_ma_helper);
9553 }
9554
9555 if (DEBUG_FLAGS & DEBUG_PHASE) {
9556 PRINT_ADDR(cp->cmd);
9557 printk ("PM %x %x %x / %x %x %x.\n",
9558 hflags0, hflags, newcmd,
9559 (unsigned)scr_to_cpu(pm->sg.addr),
9560 (unsigned)scr_to_cpu(pm->sg.size),
9561 (unsigned)scr_to_cpu(pm->ret));
9562 }
9563
9564
9565
9566
9567
9568 OUTL (nc_temp, newcmd);
9569 OUTL_DSP (nxtdsp);
9570 return;
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599unexpected_phase:
9600 dsp -= 8;
9601 nxtdsp = 0;
9602
9603 switch (cmd & 7) {
9604 case 2:
9605 nxtdsp = NCB_SCRIPT_PHYS (np, dispatch);
9606 break;
9607#if 0
9608 case 3:
9609 nxtdsp = NCB_SCRIPT_PHYS (np, dispatch);
9610 break;
9611#endif
9612 case 6:
9613
9614
9615
9616
9617
9618
9619 if (dsp == NCB_SCRIPT_PHYS (np, send_ident)) {
9620 if (cp->tag != NO_TAG && olen - rest <= 3) {
9621 cp->host_status = HS_BUSY;
9622 np->msgout[0] = M_IDENTIFY | cp->lun;
9623 nxtdsp = NCB_SCRIPTH_PHYS (np, ident_break_atn);
9624 }
9625 else
9626 nxtdsp = NCB_SCRIPTH_PHYS (np, ident_break);
9627 }
9628 else if (dsp == NCB_SCRIPTH_PHYS (np, send_wdtr) ||
9629 dsp == NCB_SCRIPTH_PHYS (np, send_sdtr) ||
9630 dsp == NCB_SCRIPTH_PHYS (np, send_ppr)) {
9631 nxtdsp = NCB_SCRIPTH_PHYS (np, nego_bad_phase);
9632 }
9633 break;
9634#if 0
9635 case 7:
9636 nxtdsp = NCB_SCRIPT_PHYS (np, clrack);
9637 break;
9638#endif
9639 }
9640
9641 if (nxtdsp) {
9642 OUTL_DSP (nxtdsp);
9643 return;
9644 }
9645
9646reset_all:
9647 ncr_start_reset(np);
9648}
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681static void ncr_sir_to_redo(ncb_p np, int num, ccb_p cp)
9682{
9683 Scsi_Cmnd *cmd = cp->cmd;
9684 tcb_p tp = &np->target[cp->target];
9685 lcb_p lp = ncr_lp(np, tp, cp->lun);
9686 ccb_p cp2;
9687 int busyccbs = 1;
9688 u_int32 startp;
9689 u_char s_status = INB (SS_PRT);
9690 int msglen;
9691 int i, j;
9692
9693
9694
9695
9696
9697
9698 if (!lp)
9699 goto next;
9700
9701
9702
9703
9704 busyccbs = lp->queuedccbs;
9705 i = (INL (nc_scratcha) - np->p_squeue) / 4;
9706 j = i;
9707 while (i != np->squeueput) {
9708 cp2 = ncr_ccb_from_dsa(np, scr_to_cpu(np->squeue[i]));
9709 assert(cp2);
9710#ifdef SCSI_NCR_IARB_SUPPORT
9711
9712 cp2->host_flags &= ~HF_HINT_IARB;
9713#endif
9714 if (cp2 && cp2->target == cp->target && cp2->lun == cp->lun) {
9715 xpt_remque(&cp2->link_ccbq);
9716 xpt_insque_head(&cp2->link_ccbq, &lp->wait_ccbq);
9717 --lp->queuedccbs;
9718 cp2->queued = 0;
9719 }
9720 else {
9721 if (i != j)
9722 np->squeue[j] = np->squeue[i];
9723 if ((j += 2) >= MAX_START*2) j = 0;
9724 }
9725 if ((i += 2) >= MAX_START*2) i = 0;
9726 }
9727 if (i != j)
9728 np->squeue[j] = np->squeue[i];
9729 np->squeueput = j;
9730
9731
9732
9733
9734
9735 xpt_remque(&cp->link_ccbq);
9736 xpt_insque_head(&cp->link_ccbq, &lp->wait_ccbq);
9737 --lp->queuedccbs;
9738 cp->queued = 0;
9739
9740next:
9741
9742#ifdef SCSI_NCR_IARB_SUPPORT
9743
9744 cp->host_flags &= ~HF_HINT_IARB;
9745 if (np->last_cp)
9746 np->last_cp = 0;
9747#endif
9748
9749
9750
9751
9752 OUTL_DSP (NCB_SCRIPT_PHYS (np, start));
9753
9754 switch(s_status) {
9755 default:
9756 case S_BUSY:
9757 ncr_complete(np, cp);
9758 break;
9759 case S_QUEUE_FULL:
9760 if (!lp || !lp->queuedccbs) {
9761 ncr_complete(np, cp);
9762 break;
9763 }
9764 if (bootverbose >= 1) {
9765 PRINT_ADDR(cmd);
9766 printk ("QUEUE FULL! %d busy, %d disconnected CCBs\n",
9767 busyccbs, lp->queuedccbs);
9768 }
9769
9770
9771
9772
9773 if (lp->queuedccbs < lp->numtags) {
9774 lp->numtags = lp->queuedccbs;
9775 lp->num_good = 0;
9776 ncr_setup_tags (np, cp->target, cp->lun);
9777 }
9778
9779
9780
9781 cp->phys.header.savep = cp->startp;
9782 cp->phys.header.lastp = cp->lastp0;
9783 cp->host_status = HS_BUSY;
9784 cp->scsi_status = S_ILLEGAL;
9785 cp->xerr_status = 0;
9786 cp->extra_bytes = 0;
9787 cp->host_flags &= (HF_PM_TO_C|HF_DATA_IN);
9788
9789 break;
9790
9791 case S_TERMINATED:
9792 case S_CHECK_COND:
9793
9794
9795
9796 if (cp->host_flags & HF_AUTO_SENSE) {
9797 ncr_complete(np, cp);
9798 break;
9799 }
9800
9801
9802
9803
9804
9805 cp->sv_scsi_status = cp->scsi_status;
9806 cp->sv_xerr_status = cp->xerr_status;
9807 cp->resid = ncr_compute_residual(np, cp);
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818 cp->scsi_smsg2[0] = M_IDENTIFY | cp->lun;
9819 msglen = 1;
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836#ifdef SCSI_NCR_INTEGRITY_CHECKING
9837 if (DEBUG_FLAGS & DEBUG_IC) {
9838 printk("%s: ncr_sir_to_redo: ic_done %2X, in_progress %2X\n",
9839 ncr_name(np), tp->ic_done, cp->cmd->ic_in_progress);
9840 }
9841
9842
9843
9844
9845
9846
9847 if ( np->check_integ_par && np->check_integrity
9848 && cp->cmd->ic_in_progress ) {
9849 cp->nego_status = 0;
9850 msglen +=
9851 ncr_ic_nego (np, cp, cmd ,&cp->scsi_smsg2[msglen]);
9852 }
9853
9854 if (!np->check_integrity ||
9855 (np->check_integrity &&
9856 (!cp->cmd->ic_in_progress && !tp->ic_done)) ) {
9857 ncr_negotiate(np, tp);
9858 cp->nego_status = 0;
9859 {
9860 u_char sync_offset;
9861 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
9862 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66))
9863 sync_offset = tp->sval & 0x3f;
9864 else
9865 sync_offset = tp->sval & 0x1f;
9866
9867 if ((tp->wval & EWS) || sync_offset)
9868 msglen +=
9869 ncr_prepare_nego (np, cp, &cp->scsi_smsg2[msglen]);
9870 }
9871
9872 }
9873#else
9874 ncr_negotiate(np, tp);
9875 cp->nego_status = 0;
9876 if ((tp->wval & EWS) || (tp->sval & 0x1f))
9877 msglen +=
9878 ncr_prepare_nego (np, cp, &cp->scsi_smsg2[msglen]);
9879#endif
9880
9881
9882
9883
9884 cp->phys.smsg.addr = cpu_to_scr(CCB_PHYS (cp, scsi_smsg2));
9885 cp->phys.smsg.size = cpu_to_scr(msglen);
9886
9887
9888
9889
9890 cp->phys.cmd.addr = cpu_to_scr(CCB_PHYS (cp, sensecmd));
9891 cp->phys.cmd.size = cpu_to_scr(6);
9892
9893
9894
9895
9896 cp->sensecmd[0] = 0x03;
9897 cp->sensecmd[1] = cp->lun << 5;
9898 cp->sensecmd[4] = sizeof(cp->sense_buf);
9899
9900
9901
9902
9903 bzero(cp->sense_buf, sizeof(cp->sense_buf));
9904 cp->phys.sense.addr = cpu_to_scr(CCB_PHYS(cp,sense_buf[0]));
9905 cp->phys.sense.size = cpu_to_scr(sizeof(cp->sense_buf));
9906
9907
9908
9909
9910 startp = NCB_SCRIPTH_PHYS (np, sdata_in);
9911
9912 cp->phys.header.savep = cpu_to_scr(startp);
9913 cp->phys.header.goalp = cpu_to_scr(startp + 16);
9914 cp->phys.header.lastp = cpu_to_scr(startp);
9915 cp->phys.header.wgoalp = cpu_to_scr(startp + 16);
9916 cp->phys.header.wlastp = cpu_to_scr(startp);
9917
9918 cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
9919 cp->scsi_status = S_ILLEGAL;
9920 cp->host_flags = (HF_AUTO_SENSE|HF_DATA_IN);
9921
9922 cp->phys.header.go.start =
9923 cpu_to_scr(NCB_SCRIPT_PHYS (np, select));
9924
9925
9926
9927
9928 if (!lp)
9929 ncr_put_start_queue(np, cp);
9930 break;
9931 }
9932
9933
9934
9935
9936 if (lp)
9937 ncr_start_next_ccb(np, lp, 1);
9938
9939 return;
9940}
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957static int ncr_clear_tasks(ncb_p np, u_char hsts,
9958 int target, int lun, int task)
9959{
9960 int i = 0;
9961 ccb_p cp;
9962
9963 for (cp = np->ccbc; cp; cp = cp->link_ccb) {
9964 if (cp->host_status != HS_DISCONNECT)
9965 continue;
9966 if (cp->target != target)
9967 continue;
9968 if (lun != -1 && cp->lun != lun)
9969 continue;
9970 if (task != -1 && cp->tag != NO_TAG && cp->scsi_smsg[2] != task)
9971 continue;
9972 cp->host_status = hsts;
9973 cp->scsi_status = S_ILLEGAL;
9974 ncr_complete(np, cp);
9975 ++i;
9976 }
9977 return i;
9978}
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025static void ncr_sir_task_recovery(ncb_p np, int num)
10026{
10027 ccb_p cp;
10028 tcb_p tp;
10029 int target=-1, lun=-1, task;
10030 int i, k;
10031 u_char *p;
10032
10033 switch(num) {
10034
10035
10036
10037
10038
10039 case SIR_SCRIPT_STOPPED:
10040
10041
10042
10043
10044 for (i = 0 ; i < MAX_TARGET ; i++) {
10045 tp = &np->target[i];
10046 if (tp->to_reset || (tp->l0p && tp->l0p->to_clear)) {
10047 target = i;
10048 break;
10049 }
10050 if (!tp->lmp)
10051 continue;
10052 for (k = 1 ; k < MAX_LUN ; k++) {
10053 if (tp->lmp[k] && tp->lmp[k]->to_clear) {
10054 target = i;
10055 break;
10056 }
10057 }
10058 if (target != -1)
10059 break;
10060 }
10061
10062
10063
10064
10065
10066 if (target == -1) {
10067 for (cp = np->ccbc; cp; cp = cp->link_ccb) {
10068 if (cp->host_status != HS_DISCONNECT)
10069 continue;
10070 if (cp->to_abort) {
10071 target = cp->target;
10072 break;
10073 }
10074 }
10075 }
10076
10077
10078
10079
10080
10081 if (target != -1) {
10082 tp = &np->target[target];
10083 np->abrt_sel.sel_id = target;
10084 np->abrt_sel.sel_scntl3 = tp->wval;
10085 np->abrt_sel.sel_sxfer = tp->sval;
10086 np->abrt_sel.sel_scntl4 = tp->uval;
10087 OUTL(nc_dsa, np->p_ncb);
10088 OUTL_DSP (NCB_SCRIPTH_PHYS (np, sel_for_abort));
10089 return;
10090 }
10091
10092
10093
10094
10095
10096
10097 np->istat_sem = 0;
10098 OUTB (nc_istat, SIGP);
10099
10100
10101
10102
10103
10104
10105
10106
10107 for (cp = np->ccbc; cp; cp = cp->link_ccb) {
10108 if (cp->host_status != HS_BUSY &&
10109 cp->host_status != HS_NEGOTIATE)
10110 continue;
10111 if (!cp->to_abort)
10112 continue;
10113#ifdef SCSI_NCR_IARB_SUPPORT
10114
10115
10116
10117
10118
10119 if (cp == np->last_cp) {
10120 cp->to_abort = 0;
10121 continue;
10122 }
10123#endif
10124
10125
10126
10127
10128 i = (INL (nc_scratcha) - np->p_squeue) / 4;
10129
10130
10131
10132
10133 k = -1;
10134 while (1) {
10135 if (i == np->squeueput)
10136 break;
10137 if (k == -1) {
10138 if (cp == ncr_ccb_from_dsa(np,
10139 scr_to_cpu(np->squeue[i])))
10140 k = i;
10141 }
10142 else {
10143
10144
10145
10146
10147 np->squeue[k] = np->squeue[i];
10148 k += 2;
10149 if (k >= MAX_START*2)
10150 k = 0;
10151 }
10152
10153 i += 2;
10154 if (i >= MAX_START*2)
10155 i = 0;
10156 }
10157
10158
10159
10160 if (k != -1) {
10161 np->squeue[k] = np->squeue[i];
10162 np->squeueput = k;
10163 }
10164 cp->host_status = HS_ABORTED;
10165 cp->scsi_status = S_ILLEGAL;
10166 ncr_complete(np, cp);
10167 }
10168 break;
10169
10170
10171
10172
10173 case SIR_TARGET_SELECTED:
10174 target = (INB (nc_sdid) & 0xf);
10175 tp = &np->target[target];
10176
10177 np->abrt_tbl.addr = cpu_to_scr(vtobus(np->abrt_msg));
10178
10179
10180
10181
10182
10183
10184 if (tp->to_reset) {
10185 np->abrt_msg[0] = M_RESET;
10186 np->abrt_tbl.size = 1;
10187 tp->to_reset = 0;
10188 break;
10189 }
10190
10191
10192
10193
10194 if (tp->l0p && tp->l0p->to_clear)
10195 lun = 0;
10196 else if (tp->lmp) {
10197 for (k = 1 ; k < MAX_LUN ; k++) {
10198 if (tp->lmp[k] && tp->lmp[k]->to_clear) {
10199 lun = k;
10200 break;
10201 }
10202 }
10203 }
10204
10205
10206
10207
10208
10209 if (lun != -1) {
10210 lcb_p lp = ncr_lp(np, tp, lun);
10211 lp->to_clear = 0;
10212 np->abrt_msg[0] = M_IDENTIFY | lun;
10213 np->abrt_msg[1] = M_ABORT;
10214 np->abrt_tbl.size = 2;
10215 break;
10216 }
10217
10218
10219
10220
10221
10222 for (cp = np->ccbc; cp; cp = cp->link_ccb) {
10223 if (cp->host_status != HS_DISCONNECT)
10224 continue;
10225 if (cp->target != target)
10226 continue;
10227 if (cp->to_abort)
10228 break;
10229 }
10230
10231
10232
10233
10234
10235
10236
10237
10238 if (!cp) {
10239 np->abrt_msg[0] = M_ABORT;
10240 np->abrt_tbl.size = 1;
10241 break;
10242 }
10243
10244
10245
10246
10247
10248 np->abrt_msg[0] = M_IDENTIFY | cp->lun;
10249
10250
10251
10252
10253
10254
10255
10256 if (cp->tag == NO_TAG) {
10257 np->abrt_msg[1] = M_ABORT;
10258 np->abrt_tbl.size = 2;
10259 }
10260 else {
10261 np->abrt_msg[1] = cp->scsi_smsg[1];
10262 np->abrt_msg[2] = cp->scsi_smsg[2];
10263 np->abrt_msg[3] = M_ABORT_TAG;
10264 np->abrt_tbl.size = 4;
10265 }
10266 cp->to_abort = 0;
10267 break;
10268
10269
10270
10271
10272
10273 case SIR_ABORT_SENT:
10274 target = (INB (nc_sdid) & 0xf);
10275 tp = &np->target[target];
10276
10277
10278
10279
10280 if (np->abrt_msg[0] == M_ABORT)
10281 break;
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291 lun = -1;
10292 task = -1;
10293 if (np->abrt_msg[0] == M_RESET) {
10294 tp->sval = 0;
10295 tp->wval = np->rv_scntl3;
10296 tp->uval = np->rv_scntl4;
10297 ncr_set_sync_wide_status(np, target);
10298 ncr_negotiate(np, tp);
10299 }
10300
10301
10302
10303
10304
10305
10306
10307 else {
10308 lun = np->abrt_msg[0] & 0x3f;
10309 if (np->abrt_msg[1] == M_ABORT_TAG)
10310 task = np->abrt_msg[2];
10311 }
10312
10313
10314
10315
10316
10317 (void) ncr_clear_tasks(np, HS_ABORTED, target, lun, task);
10318 break;
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330 case SIR_AUTO_SENSE_DONE:
10331 cp = ncr_ccb_from_dsa(np, INL (nc_dsa));
10332 if (!cp)
10333 break;
10334 memcpy(cp->cmd->sense_buffer, cp->sense_buf,
10335 sizeof(cp->cmd->sense_buffer));
10336 p = &cp->cmd->sense_buffer[0];
10337
10338 if (p[0] != 0x70 || p[2] != 0x6 || p[12] != 0x29)
10339 break;
10340#if 0
10341 (void) ncr_clear_tasks(np, HS_RESET, cp->target, cp->lun, -1);
10342#endif
10343 break;
10344 }
10345
10346
10347
10348
10349 if (num == SIR_TARGET_SELECTED) {
10350 PRINT_TARGET(np, target);
10351 ncr_printl_hex("control msgout:", np->abrt_msg,
10352 np->abrt_tbl.size);
10353 np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
10354 }
10355
10356
10357
10358
10359 OUTONB_STD ();
10360}
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395static int ncr_evaluate_dp(ncb_p np, ccb_p cp, u_int32 scr, int *ofs)
10396{
10397 u_int32 dp_scr;
10398 int dp_ofs, dp_sg, dp_sgmin;
10399 int tmp;
10400 struct pm_ctx *pm;
10401
10402
10403
10404
10405
10406 dp_scr = scr;
10407 dp_ofs = *ofs;
10408 if (dp_scr == NCB_SCRIPT_PHYS (np, pm0_data))
10409 pm = &cp->phys.pm0;
10410 else if (dp_scr == NCB_SCRIPT_PHYS (np, pm1_data))
10411 pm = &cp->phys.pm1;
10412 else
10413 pm = 0;
10414
10415 if (pm) {
10416 dp_scr = scr_to_cpu(pm->ret);
10417 dp_ofs -= scr_to_cpu(pm->sg.size);
10418 }
10419
10420
10421
10422
10423
10424
10425
10426 tmp = scr_to_cpu(cp->phys.header.goalp);
10427 dp_sg = MAX_SCATTER;
10428 if (dp_scr != tmp)
10429 dp_sg -= (tmp - 8 - (int)dp_scr) / (SCR_SG_SIZE*4);
10430 dp_sgmin = MAX_SCATTER - cp->segments;
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444 if (dp_ofs < 0) {
10445 int n;
10446 while (dp_sg > dp_sgmin) {
10447 --dp_sg;
10448 tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
10449 n = dp_ofs + (tmp & 0xffffff);
10450 if (n > 0) {
10451 ++dp_sg;
10452 break;
10453 }
10454 dp_ofs = n;
10455 }
10456 }
10457 else if (dp_ofs > 0) {
10458 while (dp_sg < MAX_SCATTER) {
10459 tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
10460 dp_ofs -= (tmp & 0xffffff);
10461 ++dp_sg;
10462 if (dp_ofs <= 0)
10463 break;
10464 }
10465 }
10466
10467
10468
10469
10470
10471 if (dp_sg < dp_sgmin || (dp_sg == dp_sgmin && dp_ofs < 0))
10472 goto out_err;
10473 else if (dp_sg > MAX_SCATTER || (dp_sg == MAX_SCATTER && dp_ofs > 0))
10474 goto out_err;
10475
10476
10477
10478
10479 if (dp_sg > cp->ext_sg ||
10480 (dp_sg == cp->ext_sg && dp_ofs > cp->ext_ofs)) {
10481 cp->ext_sg = dp_sg;
10482 cp->ext_ofs = dp_ofs;
10483 }
10484
10485
10486
10487
10488 *ofs = dp_ofs;
10489 return dp_sg;
10490
10491out_err:
10492 return -1;
10493}
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509static void ncr_modify_dp(ncb_p np, tcb_p tp, ccb_p cp, int ofs)
10510{
10511 int dp_ofs = ofs;
10512 u_int32 dp_scr = INL (nc_temp);
10513 u_int32 dp_ret;
10514 u_int32 tmp;
10515 u_char hflags;
10516 int dp_sg;
10517 struct pm_ctx *pm;
10518
10519
10520
10521
10522 if (cp->host_flags & HF_AUTO_SENSE)
10523 goto out_reject;
10524
10525
10526
10527
10528
10529 dp_sg = ncr_evaluate_dp(np, cp, dp_scr, &dp_ofs);
10530 if (dp_sg < 0)
10531 goto out_reject;
10532
10533
10534
10535
10536
10537 dp_ret = cpu_to_scr(cp->phys.header.goalp);
10538 dp_ret = dp_ret - 8 - (MAX_SCATTER - dp_sg) * (SCR_SG_SIZE*4);
10539
10540
10541
10542
10543
10544 if (dp_ofs == 0) {
10545 dp_scr = dp_ret;
10546 goto out_ok;
10547 }
10548
10549
10550
10551
10552 hflags = INB (HF_PRT);
10553
10554 if (hflags & HF_DP_SAVED)
10555 hflags ^= HF_ACT_PM;
10556
10557 if (!(hflags & HF_ACT_PM)) {
10558 pm = &cp->phys.pm0;
10559 dp_scr = NCB_SCRIPT_PHYS (np, pm0_data);
10560 }
10561 else {
10562 pm = &cp->phys.pm1;
10563 dp_scr = NCB_SCRIPT_PHYS (np, pm1_data);
10564 }
10565
10566 hflags &= ~(HF_DP_SAVED);
10567
10568 OUTB (HF_PRT, hflags);
10569
10570
10571
10572
10573
10574
10575
10576
10577 pm->ret = cpu_to_scr(dp_ret);
10578 tmp = scr_to_cpu(cp->phys.data[dp_sg-1].addr);
10579 tmp += scr_to_cpu(cp->phys.data[dp_sg-1].size) + dp_ofs;
10580 pm->sg.addr = cpu_to_scr(tmp);
10581 pm->sg.size = cpu_to_scr(-dp_ofs);
10582
10583out_ok:
10584 OUTL (nc_temp, dp_scr);
10585 OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
10586 return;
10587
10588out_reject:
10589 OUTL_DSP (NCB_SCRIPTH_PHYS (np, msg_bad));
10590}
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613static int ncr_compute_residual(ncb_p np, ccb_p cp)
10614{
10615 int dp_sg, dp_sgmin, tmp;
10616 int resid=0;
10617 int dp_ofs = 0;
10618
10619
10620
10621
10622
10623
10624
10625
10626 if (cp->xerr_status & (XE_EXTRA_DATA|XE_SODL_UNRUN|XE_SWIDE_OVRUN)) {
10627 if (cp->xerr_status & XE_EXTRA_DATA)
10628 resid -= cp->extra_bytes;
10629 if (cp->xerr_status & XE_SODL_UNRUN)
10630 ++resid;
10631 if (cp->xerr_status & XE_SWIDE_OVRUN)
10632 --resid;
10633 }
10634
10635
10636
10637
10638
10639
10640 if (cp->phys.header.lastp == cp->phys.header.goalp)
10641 return resid;
10642
10643
10644
10645
10646
10647
10648 if (cp->phys.header.lastp == NCB_SCRIPTH_PHYS (np, data_io))
10649 return cp->data_len;
10650
10651
10652
10653
10654
10655 if (cp->startp == cp->phys.header.lastp ||
10656 ncr_evaluate_dp(np, cp, scr_to_cpu(cp->phys.header.lastp),
10657 &dp_ofs) < 0) {
10658 return cp->data_len;
10659 }
10660
10661
10662
10663
10664
10665 dp_sgmin = MAX_SCATTER - cp->segments;
10666 resid = -cp->ext_ofs;
10667 for (dp_sg = cp->ext_sg; dp_sg < MAX_SCATTER; ++dp_sg) {
10668 tmp = scr_to_cpu(cp->phys.data[dp_sg].size);
10669 resid += (tmp & 0xffffff);
10670 }
10671
10672
10673
10674
10675 return resid;
10676}
10677
10678
10679
10680
10681
10682
10683
10684
10685static int ncr_show_msg (u_char * msg)
10686{
10687 u_char i;
10688 printk ("%x",*msg);
10689 if (*msg==M_EXTENDED) {
10690 for (i=1;i<8;i++) {
10691 if (i-1>msg[1]) break;
10692 printk ("-%x",msg[i]);
10693 };
10694 return (i+1);
10695 } else if ((*msg & 0xf0) == 0x20) {
10696 printk ("-%x",msg[1]);
10697 return (2);
10698 };
10699 return (1);
10700}
10701
10702static void ncr_print_msg (ccb_p cp, char *label, u_char *msg)
10703{
10704 if (cp)
10705 PRINT_ADDR(cp->cmd);
10706 if (label)
10707 printk ("%s: ", label);
10708
10709 (void) ncr_show_msg (msg);
10710 printk (".\n");
10711}
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769static void ncr_sync_nego(ncb_p np, tcb_p tp, ccb_p cp)
10770{
10771 u_char scntl3, scntl4;
10772 u_char chg, ofs, per, fak;
10773
10774
10775
10776
10777
10778 if (DEBUG_FLAGS & DEBUG_NEGO) {
10779 ncr_print_msg(cp, "sync msg in", np->msgin);
10780 };
10781
10782
10783
10784
10785
10786 chg = 0;
10787 per = np->msgin[3];
10788 ofs = np->msgin[4];
10789 if (ofs==0) per=255;
10790
10791
10792
10793
10794
10795
10796 if (ofs)
10797 tp->inq_byte7 |= INQ7_SYNC;
10798
10799
10800
10801
10802
10803 if (per < np->minsync)
10804 {chg = 1; per = np->minsync;}
10805 if (per < tp->minsync)
10806 {chg = 1; per = tp->minsync;}
10807 if (ofs > np->maxoffs_st)
10808 {chg = 1; ofs = np->maxoffs_st;}
10809 if (ofs > tp->maxoffs)
10810 {chg = 1; ofs = tp->maxoffs;}
10811
10812
10813
10814
10815 fak = 7;
10816 scntl3 = 0;
10817 scntl4 = 0;
10818 if (ofs != 0) {
10819 ncr_getsync(np, per, &fak, &scntl3);
10820 if (fak > 7) {
10821 chg = 1;
10822 ofs = 0;
10823 }
10824 }
10825 if (ofs == 0) {
10826 fak = 7;
10827 per = 0;
10828 scntl3 = 0;
10829 scntl4 = 0;
10830 tp->minsync = 0;
10831 }
10832
10833 if (DEBUG_FLAGS & DEBUG_NEGO) {
10834 PRINT_ADDR(cp->cmd);
10835 printk ("sync: per=%d scntl3=0x%x scntl4=0x%x ofs=%d fak=%d chg=%d.\n",
10836 per, scntl3, scntl4, ofs, fak, chg);
10837 }
10838
10839 if (INB (HS_PRT) == HS_NEGOTIATE) {
10840 OUTB (HS_PRT, HS_BUSY);
10841 switch (cp->nego_status) {
10842 case NS_SYNC:
10843
10844
10845
10846 if (chg) {
10847
10848
10849
10850 ncr_setsync (np, cp, 0, 0xe0, 0);
10851 OUTL_DSP (NCB_SCRIPTH_PHYS (np, msg_bad));
10852 } else {
10853
10854
10855
10856 if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
10857 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
10858 ncr_setsync (np, cp, scntl3, (fak<<5)|ofs,0);
10859 else
10860 ncr_setsync (np, cp, scntl3, ofs, scntl4);
10861
10862 OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
10863 };
10864 return;
10865
10866 case NS_WIDE:
10867 ncr_setwide (np, cp, 0, 0);
10868 break;
10869 };
10870 };
10871
10872
10873
10874
10875
10876
10877 if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
10878 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
10879 ncr_setsync (np, cp, scntl3, (fak<<5)|ofs,0);
10880 else
10881 ncr_setsync (np, cp, scntl3, ofs, scntl4);
10882
10883 np->msgout[0] = M_EXTENDED;
10884 np->msgout[1] = 3;
10885 np->msgout[2] = M_X_SYNC_REQ;
10886 np->msgout[3] = per;
10887 np->msgout[4] = ofs;
10888
10889 cp->nego_status = NS_SYNC;
10890
10891 if (DEBUG_FLAGS & DEBUG_NEGO) {
10892 ncr_print_msg(cp, "sync msgout", np->msgout);
10893 }
10894
10895 np->msgin [0] = M_NOOP;
10896
10897 if (!ofs)
10898 OUTL_DSP (NCB_SCRIPTH_PHYS (np, msg_bad));
10899 else
10900 OUTL_DSP (NCB_SCRIPTH_PHYS (np, sdtr_resp));
10901}
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914static void ncr_wide_nego(ncb_p np, tcb_p tp, ccb_p cp)
10915{
10916 u_char chg, wide;
10917
10918
10919
10920
10921 if (DEBUG_FLAGS & DEBUG_NEGO) {
10922 ncr_print_msg(cp, "wide msgin", np->msgin);
10923 };
10924
10925
10926
10927
10928
10929 chg = 0;
10930 wide = np->msgin[3];
10931
10932
10933
10934
10935
10936
10937 if (wide)
10938 tp->inq_byte7 |= INQ7_WIDE16;
10939
10940
10941
10942
10943
10944 if (wide > tp->usrwide)
10945 {chg = 1; wide = tp->usrwide;}
10946
10947 if (DEBUG_FLAGS & DEBUG_NEGO) {
10948 PRINT_ADDR(cp->cmd);
10949 printk ("wide: wide=%d chg=%d.\n", wide, chg);
10950 }
10951
10952 if (INB (HS_PRT) == HS_NEGOTIATE) {
10953 OUTB (HS_PRT, HS_BUSY);
10954 switch (cp->nego_status) {
10955 case NS_WIDE:
10956
10957
10958
10959 if (chg) {
10960
10961
10962
10963 ncr_setwide (np, cp, 0, 1);
10964 OUTL_DSP (NCB_SCRIPTH_PHYS (np, msg_bad));
10965 } else {
10966
10967
10968
10969 ncr_setwide (np, cp, wide, 1);
10970 OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
10971 };
10972 return;
10973
10974 case NS_SYNC:
10975 ncr_setsync (np, cp, 0, 0xe0, 0);
10976 break;
10977 };
10978 };
10979
10980
10981
10982
10983
10984
10985 ncr_setwide (np, cp, wide, 1);
10986
10987 np->msgout[0] = M_EXTENDED;
10988 np->msgout[1] = 2;
10989 np->msgout[2] = M_X_WIDE_REQ;
10990 np->msgout[3] = wide;
10991
10992 np->msgin [0] = M_NOOP;
10993
10994 cp->nego_status = NS_WIDE;
10995
10996 if (DEBUG_FLAGS & DEBUG_NEGO) {
10997 ncr_print_msg(cp, "wide msgout", np->msgout);
10998 }
10999
11000 OUTL_DSP (NCB_SCRIPTH_PHYS (np, wdtr_resp));
11001}
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013static void ncr_ppr_nego(ncb_p np, tcb_p tp, ccb_p cp)
11014{
11015 u_char scntl3, scntl4;
11016 u_char chg, ofs, per, fak, wth, dt;
11017
11018
11019
11020
11021
11022 if (DEBUG_FLAGS & DEBUG_NEGO) {
11023 ncr_print_msg(cp, "ppr msg in", np->msgin);
11024 };
11025
11026
11027
11028
11029
11030 chg = 0;
11031 per = np->msgin[3];
11032 ofs = np->msgin[5];
11033 wth = np->msgin[6];
11034 dt = np->msgin[7];
11035 if (ofs==0) per=255;
11036
11037
11038
11039
11040
11041
11042 if (ofs)
11043 tp->inq_byte7 |= INQ7_SYNC;
11044
11045 if (wth)
11046 tp->inq_byte7 |= INQ7_WIDE16;
11047
11048
11049
11050
11051
11052 if (wth > tp->usrwide)
11053 {chg = 1; wth = tp->usrwide;}
11054 if (per < np->minsync)
11055 {chg = 1; per = np->minsync;}
11056 if (per < tp->minsync)
11057 {chg = 1; per = tp->minsync;}
11058 if (ofs > tp->maxoffs)
11059 {chg = 1; ofs = tp->maxoffs;}
11060
11061
11062
11063
11064 fak = 7;
11065 scntl3 = 0;
11066 scntl4 = 0;
11067 if (ofs != 0) {
11068 scntl4 = dt ? 0x80 : 0;
11069 ncr_getsync(np, per, &fak, &scntl3);
11070 if (fak > 7) {
11071 chg = 1;
11072 ofs = 0;
11073 }
11074 }
11075 if (ofs == 0) {
11076 fak = 7;
11077 per = 0;
11078 scntl3 = 0;
11079 scntl4 = 0;
11080 tp->minsync = 0;
11081 }
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092 if ((per == 0x09) && ofs && (!wth || !dt))
11093 chg = 1;
11094 else if (( (per > 0x09) && dt) )
11095 chg = 2;
11096
11097
11098 if (!dt && ofs > np->maxoffs_st)
11099 {chg = 2; ofs = np->maxoffs_st;}
11100
11101 if (DEBUG_FLAGS & DEBUG_NEGO) {
11102 PRINT_ADDR(cp->cmd);
11103 printk ("ppr: wth=%d per=%d scntl3=0x%x scntl4=0x%x ofs=%d fak=%d chg=%d.\n",
11104 wth, per, scntl3, scntl4, ofs, fak, chg);
11105 }
11106
11107 if (INB (HS_PRT) == HS_NEGOTIATE) {
11108 OUTB (HS_PRT, HS_BUSY);
11109 switch (cp->nego_status) {
11110 case NS_PPR:
11111
11112
11113
11114 if (chg) {
11115
11116
11117
11118 if (chg == 2) {
11119
11120
11121
11122 tp->minsync = 0x0A;
11123 tp->period = 0;
11124 tp->widedone = 0;
11125 }
11126 ncr_setsyncwide (np, cp, 0, 0xe0, 0, 0);
11127 OUTL_DSP (NCB_SCRIPTH_PHYS (np, msg_bad));
11128 } else {
11129
11130
11131
11132
11133 if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
11134 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
11135 ncr_setsyncwide (np, cp, scntl3, (fak<<5)|ofs,0, wth);
11136 else
11137 ncr_setsyncwide (np, cp, scntl3, ofs, scntl4, wth);
11138
11139 OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
11140
11141 };
11142 return;
11143
11144 case NS_SYNC:
11145 ncr_setsync (np, cp, 0, 0xe0, 0);
11146 break;
11147
11148 case NS_WIDE:
11149 ncr_setwide (np, cp, 0, 0);
11150 break;
11151 };
11152 };
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164 if ((per == 0x09) && ofs && (!wth || !dt)) {
11165 per = 0x0A;
11166 dt = 0;
11167 }
11168 else if ( (per > 0x09) && dt) {
11169 dt = 0;
11170 }
11171 if (!dt && ofs > np->maxoffs_st)
11172 ofs = np->maxoffs_st;
11173
11174 if ((np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
11175 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66))
11176 ncr_setsyncwide (np, cp, scntl3, (fak<<5)|ofs,0, wth);
11177 else
11178 ncr_setsyncwide (np, cp, scntl3, ofs, scntl4, wth);
11179
11180 np->msgout[0] = M_EXTENDED;
11181 np->msgout[1] = 6;
11182 np->msgout[2] = M_X_PPR_REQ;
11183 np->msgout[3] = per;
11184 np->msgout[4] = 0;
11185 np->msgout[5] = ofs;
11186 np->msgout[6] = wth;
11187 np->msgout[7] = dt;
11188
11189 cp->nego_status = NS_PPR;
11190
11191 if (DEBUG_FLAGS & DEBUG_NEGO) {
11192 ncr_print_msg(cp, "ppr msgout", np->msgout);
11193 }
11194
11195 np->msgin [0] = M_NOOP;
11196
11197 if (!ofs)
11198 OUTL_DSP (NCB_SCRIPTH_PHYS (np, msg_bad));
11199 else
11200 OUTL_DSP (NCB_SCRIPTH_PHYS (np, ppr_resp));
11201}
11202
11203
11204
11205
11206
11207
11208
11209
11210static void ncr_nego_default(ncb_p np, tcb_p tp, ccb_p cp)
11211{
11212
11213
11214
11215
11216 switch (cp->nego_status) {
11217
11218 case NS_SYNC:
11219 ncr_setsync (np, cp, 0, 0xe0, 0);
11220 break;
11221
11222 case NS_WIDE:
11223 ncr_setwide (np, cp, 0, 0);
11224 break;
11225
11226 case NS_PPR:
11227
11228
11229
11230
11231
11232 if (DEBUG_FLAGS & DEBUG_NEGO) {
11233 tcb_p tp=&np->target[cp->target];
11234 u_char factor, offset, width;
11235
11236 ncr_get_xfer_info ( np, tp, &factor, &offset, &width);
11237
11238 printk("Current factor %d offset %d width %d\n",
11239 factor, offset, width);
11240 }
11241 if (tp->ppr_negotiation == 2)
11242 ncr_setsyncwide (np, cp, 0, 0xe0, 0, 0);
11243 else if (tp->ppr_negotiation == 1) {
11244
11245
11246
11247
11248
11249
11250 tp->ppr_negotiation = 0;
11251 }
11252 else
11253 {
11254 tp->ppr_negotiation = 0;
11255 ncr_setwide (np, cp, 0, 0);
11256 }
11257 break;
11258 };
11259 np->msgin [0] = M_NOOP;
11260 np->msgout[0] = M_NOOP;
11261 cp->nego_status = 0;
11262}
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278static void ncr_nego_rejected(ncb_p np, tcb_p tp, ccb_p cp)
11279{
11280 ncr_nego_default(np, tp, cp);
11281 OUTB (HS_PRT, HS_BUSY);
11282}
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294void ncr_int_sir (ncb_p np)
11295{
11296 u_char num = INB (nc_dsps);
11297 u_long dsa = INL (nc_dsa);
11298 ccb_p cp = ncr_ccb_from_dsa(np, dsa);
11299 u_char target = INB (nc_sdid) & 0x0f;
11300 tcb_p tp = &np->target[target];
11301 int tmp;
11302
11303 if (DEBUG_FLAGS & DEBUG_TINY) printk ("I#%d", num);
11304
11305 switch (num) {
11306
11307
11308
11309#ifdef SCSI_NCR_PCIQ_SYNC_ON_INTR
11310 case SIR_DUMMY_INTERRUPT:
11311 goto out;
11312#endif
11313
11314
11315
11316
11317
11318 case SIR_SCRIPT_STOPPED:
11319 case SIR_TARGET_SELECTED:
11320 case SIR_ABORT_SENT:
11321 case SIR_AUTO_SENSE_DONE:
11322 ncr_sir_task_recovery(np, num);
11323 return;
11324
11325
11326
11327
11328
11329 case SIR_SEL_ATN_NO_MSG_OUT:
11330 printk ("%s:%d: No MSG OUT phase after selection with ATN.\n",
11331 ncr_name (np), target);
11332 goto out_stuck;
11333
11334
11335
11336
11337 case SIR_RESEL_NO_MSG_IN:
11338
11339
11340
11341
11342 case SIR_RESEL_NO_IDENTIFY:
11343
11344
11345
11346
11347
11348 if (tp->l0p) {
11349 OUTL (nc_dsa, scr_to_cpu(tp->l0p->tasktbl[0]));
11350 OUTL_DSP (NCB_SCRIPT_PHYS (np, resel_go));
11351 return;
11352 }
11353
11354
11355
11356 case SIR_RESEL_BAD_LUN:
11357 np->msgout[0] = M_RESET;
11358 goto out;
11359
11360
11361
11362
11363 case SIR_RESEL_BAD_I_T_L:
11364 np->msgout[0] = M_ABORT;
11365 goto out;
11366
11367
11368
11369
11370 case SIR_RESEL_BAD_I_T_L_Q:
11371 np->msgout[0] = M_ABORT_TAG;
11372 goto out;
11373
11374
11375
11376
11377 case SIR_RESEL_ABORTED:
11378 np->lastmsg = np->msgout[0];
11379 np->msgout[0] = M_NOOP;
11380 printk ("%s:%d: message %x sent on bad reselection.\n",
11381 ncr_name (np), target, np->lastmsg);
11382 goto out;
11383
11384
11385
11386
11387 case SIR_MSG_OUT_DONE:
11388 np->lastmsg = np->msgout[0];
11389 np->msgout[0] = M_NOOP;
11390
11391 if (np->lastmsg == M_PARITY || np->lastmsg == M_ID_ERROR) {
11392 if (cp) {
11393 cp->xerr_status &= ~XE_PARITY_ERR;
11394 if (!cp->xerr_status)
11395 OUTOFFB (HF_PRT, HF_EXT_ERR);
11396 }
11397 }
11398 goto out;
11399
11400
11401
11402
11403
11404 case SIR_BAD_STATUS:
11405 if (!cp)
11406 goto out;
11407 ncr_sir_to_redo(np, num, cp);
11408 return;
11409
11410
11411
11412
11413 case SIR_REJECT_TO_SEND:
11414 ncr_print_msg(cp, "M_REJECT to send for ", np->msgin);
11415 np->msgout[0] = M_REJECT;
11416 goto out;
11417
11418
11419
11420
11421
11422
11423 case SIR_SWIDE_OVERRUN:
11424 if (cp) {
11425 OUTONB (HF_PRT, HF_EXT_ERR);
11426 cp->xerr_status |= XE_SWIDE_OVRUN;
11427 }
11428 goto out;
11429
11430
11431
11432
11433
11434 case SIR_SODL_UNDERRUN:
11435 if (cp) {
11436 OUTONB (HF_PRT, HF_EXT_ERR);
11437 cp->xerr_status |= XE_SODL_UNRUN;
11438 }
11439 goto out;
11440
11441
11442
11443
11444
11445
11446 case SIR_DATA_OVERRUN:
11447 if (cp) {
11448 OUTONB (HF_PRT, HF_EXT_ERR);
11449 cp->xerr_status |= XE_EXTRA_DATA;
11450 cp->extra_bytes += INL (nc_scratcha);
11451 }
11452 goto out;
11453
11454
11455
11456 case SIR_BAD_PHASE:
11457 if (cp) {
11458 OUTONB (HF_PRT, HF_EXT_ERR);
11459 cp->xerr_status |= XE_BAD_PHASE;
11460 }
11461 goto out;
11462
11463
11464
11465 case SIR_MSG_RECEIVED:
11466 if (!cp)
11467 goto out_stuck;
11468 switch (np->msgin [0]) {
11469
11470
11471
11472
11473
11474 case M_EXTENDED:
11475 switch (np->msgin [2]) {
11476 case M_X_MODIFY_DP:
11477 if (DEBUG_FLAGS & DEBUG_POINTER)
11478 ncr_print_msg(cp,"modify DP",np->msgin);
11479 tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) +
11480 (np->msgin[5]<<8) + (np->msgin[6]);
11481 ncr_modify_dp(np, tp, cp, tmp);
11482 return;
11483 case M_X_SYNC_REQ:
11484 ncr_sync_nego(np, tp, cp);
11485 return;
11486 case M_X_WIDE_REQ:
11487 ncr_wide_nego(np, tp, cp);
11488 return;
11489 case M_X_PPR_REQ:
11490 ncr_ppr_nego(np, tp, cp);
11491 return;
11492 default:
11493 goto out_reject;
11494 }
11495 break;
11496
11497
11498
11499
11500
11501
11502
11503 case M_IGN_RESIDUE:
11504 if (DEBUG_FLAGS & DEBUG_POINTER)
11505 ncr_print_msg(cp,"ign wide residue", np->msgin);
11506 ncr_modify_dp(np, tp, cp, -1);
11507 return;
11508 case M_REJECT:
11509 if (INB (HS_PRT) == HS_NEGOTIATE)
11510 ncr_nego_rejected(np, tp, cp);
11511 else {
11512 PRINT_ADDR(cp->cmd);
11513 printk ("M_REJECT received (%x:%x).\n",
11514 scr_to_cpu(np->lastmsg), np->msgout[0]);
11515 }
11516 goto out_clrack;
11517 break;
11518 default:
11519 goto out_reject;
11520 }
11521 break;
11522
11523
11524
11525
11526 case SIR_MSG_WEIRD:
11527 ncr_print_msg(cp, "WEIRD message received", np->msgin);
11528 OUTL_DSP (NCB_SCRIPTH_PHYS (np, msg_weird));
11529 return;
11530
11531
11532
11533
11534
11535 case SIR_NEGO_FAILED:
11536 OUTB (HS_PRT, HS_BUSY);
11537
11538
11539
11540
11541 case SIR_NEGO_PROTO:
11542 ncr_nego_default(np, tp, cp);
11543 goto out;
11544 };
11545
11546out:
11547 OUTONB_STD ();
11548 return;
11549out_reject:
11550 OUTL_DSP (NCB_SCRIPTH_PHYS (np, msg_bad));
11551 return;
11552out_clrack:
11553 OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
11554 return;
11555out_stuck:
11556 return;
11557}
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569static ccb_p ncr_get_ccb (ncb_p np, u_char tn, u_char ln)
11570{
11571 tcb_p tp = &np->target[tn];
11572 lcb_p lp = ncr_lp(np, tp, ln);
11573 u_short tag = NO_TAG;
11574 XPT_QUEHEAD *qp;
11575 ccb_p cp = (ccb_p) 0;
11576
11577
11578
11579
11580 if (xpt_que_empty(&np->free_ccbq))
11581 (void) ncr_alloc_ccb(np);
11582
11583
11584
11585
11586 qp = xpt_remque_head(&np->free_ccbq);
11587 if (!qp)
11588 goto out;
11589 cp = xpt_que_entry(qp, struct ccb, link_ccbq);
11590
11591
11592
11593
11594
11595
11596 if (!lp) {
11597 if (xpt_que_empty(&np->b0_ccbq))
11598 xpt_insque_head(&cp->link_ccbq, &np->b0_ccbq);
11599 else
11600 goto out_free;
11601 } else {
11602
11603
11604
11605 if (lp->queuedepth != lp->numtags) {
11606 ncr_setup_tags(np, tn, ln);
11607 }
11608
11609
11610
11611
11612
11613 if (lp->usetags) {
11614 if (lp->busyccbs < lp->maxnxs) {
11615 tag = lp->cb_tags[lp->ia_tag];
11616 ++lp->ia_tag;
11617 if (lp->ia_tag == MAX_TAGS)
11618 lp->ia_tag = 0;
11619 cp->tags_si = lp->tags_si;
11620 ++lp->tags_sum[cp->tags_si];
11621 }
11622 else
11623 goto out_free;
11624 }
11625
11626
11627
11628
11629
11630 xpt_insque_tail(&cp->link_ccbq, &lp->wait_ccbq);
11631 ++lp->busyccbs;
11632 }
11633
11634
11635
11636
11637 cp->to_abort = 0;
11638 cp->tag = tag;
11639 cp->target = tn;
11640 cp->lun = ln;
11641
11642 if (DEBUG_FLAGS & DEBUG_TAGS) {
11643 PRINT_LUN(np, tn, ln);
11644 printk ("ccb @%p using tag %d.\n", cp, tag);
11645 }
11646
11647out:
11648 return cp;
11649out_free:
11650 xpt_insque_head(&cp->link_ccbq, &np->free_ccbq);
11651 return (ccb_p) 0;
11652}
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663static void ncr_free_ccb (ncb_p np, ccb_p cp)
11664{
11665 tcb_p tp = &np->target[cp->target];
11666 lcb_p lp = ncr_lp(np, tp, cp->lun);
11667
11668 if (DEBUG_FLAGS & DEBUG_TAGS) {
11669 PRINT_LUN(np, cp->target, cp->lun);
11670 printk ("ccb @%p freeing tag %d.\n", cp, cp->tag);
11671 }
11672
11673
11674
11675
11676
11677
11678 if (lp) {
11679 if (cp->tag != NO_TAG) {
11680 lp->cb_tags[lp->if_tag++] = cp->tag;
11681 if (lp->if_tag == MAX_TAGS)
11682 lp->if_tag = 0;
11683 --lp->tags_sum[cp->tags_si];
11684 lp->tasktbl[cp->tag] = cpu_to_scr(np->p_bad_i_t_l_q);
11685 } else {
11686 lp->tasktbl[0] = cpu_to_scr(np->p_bad_i_t_l);
11687 }
11688 --lp->busyccbs;
11689 if (cp->queued) {
11690 --lp->queuedccbs;
11691 }
11692 }
11693
11694
11695
11696
11697 xpt_remque(&cp->link_ccbq);
11698 xpt_insque_head(&cp->link_ccbq, &np->free_ccbq);
11699 cp -> host_status = HS_IDLE;
11700 cp -> queued = 0;
11701}
11702
11703
11704
11705
11706
11707
11708static ccb_p ncr_alloc_ccb(ncb_p np)
11709{
11710 ccb_p cp = 0;
11711 int hcode;
11712
11713
11714
11715
11716 cp = m_calloc_dma(sizeof(struct ccb), "CCB");
11717 if (!cp)
11718 return 0;
11719
11720
11721
11722
11723 np->actccbs++;
11724
11725
11726
11727
11728 cp->p_ccb = vtobus(cp);
11729
11730
11731
11732
11733 hcode = CCB_HASH_CODE(cp->p_ccb);
11734 cp->link_ccbh = np->ccbh[hcode];
11735 np->ccbh[hcode] = cp;
11736
11737
11738
11739
11740 cp->phys.header.go.start = cpu_to_scr(NCB_SCRIPT_PHYS (np, idle));
11741 cp->phys.header.go.restart = cpu_to_scr(NCB_SCRIPTH_PHYS(np,bad_i_t_l));
11742
11743
11744
11745
11746 cp->phys.smsg_ext.addr = cpu_to_scr(NCB_PHYS(np, msgin[2]));
11747
11748
11749
11750
11751 cp->link_ccb = np->ccbc;
11752 np->ccbc = cp;
11753
11754 xpt_insque_head(&cp->link_ccbq, &np->free_ccbq);
11755
11756 return cp;
11757}
11758
11759
11760
11761
11762
11763
11764static ccb_p ncr_ccb_from_dsa(ncb_p np, u_long dsa)
11765{
11766 int hcode;
11767 ccb_p cp;
11768
11769 hcode = CCB_HASH_CODE(dsa);
11770 cp = np->ccbh[hcode];
11771 while (cp) {
11772 if (cp->p_ccb == dsa)
11773 break;
11774 cp = cp->link_ccbh;
11775 }
11776
11777 return cp;
11778}
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797static void ncr_init_tcb (ncb_p np, u_char tn)
11798{
11799
11800
11801
11802 assert (( (offsetof(struct ncr_reg, nc_sxfer) ^
11803 offsetof(struct tcb , sval )) &3) == 0);
11804 assert (( (offsetof(struct ncr_reg, nc_scntl3) ^
11805 offsetof(struct tcb , wval )) &3) == 0);
11806 if ((np->device_id == PCI_DEVICE_ID_LSI_53C1010) ||
11807 (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)){
11808 assert (( (offsetof(struct ncr_reg, nc_scntl4) ^
11809 offsetof(struct tcb , uval )) &3) == 0);
11810 }
11811}
11812
11813
11814
11815
11816
11817
11818
11819
11820static lcb_p ncr_alloc_lcb (ncb_p np, u_char tn, u_char ln)
11821{
11822 tcb_p tp = &np->target[tn];
11823 lcb_p lp = ncr_lp(np, tp, ln);
11824
11825
11826
11827
11828 if (lp)
11829 return lp;
11830
11831
11832
11833
11834 ncr_init_tcb(np, tn);
11835
11836
11837
11838
11839
11840 if (ln && !tp->luntbl) {
11841 int i;
11842
11843 tp->luntbl = m_calloc_dma(256, "LUNTBL");
11844 if (!tp->luntbl)
11845 goto fail;
11846 for (i = 0 ; i < 64 ; i++)
11847 tp->luntbl[i] = cpu_to_scr(NCB_PHYS(np, resel_badlun));
11848 tp->b_luntbl = cpu_to_scr(vtobus(tp->luntbl));
11849 }
11850
11851
11852
11853
11854 if (ln && !tp->lmp) {
11855 tp->lmp = m_calloc(MAX_LUN * sizeof(lcb_p), "LMP");
11856 if (!tp->lmp)
11857 goto fail;
11858 }
11859
11860
11861
11862
11863
11864 lp = m_calloc_dma(sizeof(struct lcb), "LCB");
11865 if (!lp)
11866 goto fail;
11867 if (ln) {
11868 tp->lmp[ln] = lp;
11869 tp->luntbl[ln] = cpu_to_scr(vtobus(lp));
11870 }
11871 else {
11872 tp->l0p = lp;
11873 tp->b_lun0 = cpu_to_scr(vtobus(lp));
11874 }
11875
11876
11877
11878
11879 xpt_que_init(&lp->busy_ccbq);
11880 xpt_que_init(&lp->wait_ccbq);
11881
11882
11883
11884
11885
11886 lp->maxnxs = 1;
11887 lp->tasktbl = &lp->tasktbl_0;
11888 lp->b_tasktbl = cpu_to_scr(vtobus(lp->tasktbl));
11889 lp->tasktbl[0] = cpu_to_scr(np->p_notask);
11890 lp->resel_task = cpu_to_scr(NCB_SCRIPT_PHYS(np, resel_notag));
11891
11892
11893
11894
11895 lp->busyccbs = 1;
11896 lp->queuedccbs = 1;
11897 lp->queuedepth = 1;
11898fail:
11899 return lp;
11900}
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911static lcb_p ncr_setup_lcb (ncb_p np, u_char tn, u_char ln, u_char *inq_data)
11912{
11913 tcb_p tp = &np->target[tn];
11914 lcb_p lp = ncr_lp(np, tp, ln);
11915 u_char inq_byte7;
11916 int i;
11917
11918
11919
11920
11921 if (!lp && !(lp = ncr_alloc_lcb(np, tn, ln)))
11922 goto fail;
11923
11924#if 0
11925
11926
11927
11928 tp->quirks = 0;
11929 if (tp->quirks && bootverbose) {
11930 PRINT_LUN(np, tn, ln);
11931 printk ("quirks=%x.\n", tp->quirks);
11932 }
11933#endif
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943 inq_byte7 = 0;
11944 if ((inq_data[2] & 0x7) >= 2 && (inq_data[3] & 0xf) == 2)
11945 inq_byte7 = inq_data[7];
11946 else if ((inq_data[2] & 0x7) == 1 && (inq_data[3] & 0xf) == 1)
11947 inq_byte7 = INQ7_SYNC;
11948
11949
11950
11951
11952
11953 if ((inq_data[0] & 0xe0) > 0x20 || (inq_data[0] & 0x1f) == 0x1f)
11954 inq_byte7 &= (INQ7_SYNC | INQ7_WIDE16);
11955
11956
11957
11958
11959 if (driver_setup.force_sync_nego)
11960 inq_byte7 |= INQ7_SYNC;
11961
11962
11963
11964
11965 tp->inq_done = 1;
11966 if ((inq_byte7 ^ tp->inq_byte7) & (INQ7_SYNC | INQ7_WIDE16)) {
11967 tp->inq_byte7 = inq_byte7;
11968 ncr_negotiate(np, tp);
11969 }
11970
11971
11972
11973
11974
11975 if ((inq_byte7 & INQ7_QUEUE) && lp->tasktbl == &lp->tasktbl_0) {
11976 lp->tasktbl = m_calloc_dma(MAX_TASKS*4, "TASKTBL");
11977 if (!lp->tasktbl) {
11978 lp->tasktbl = &lp->tasktbl_0;
11979 goto fail;
11980 }
11981 lp->b_tasktbl = cpu_to_scr(vtobus(lp->tasktbl));
11982 for (i = 0 ; i < MAX_TASKS ; i++)
11983 lp->tasktbl[i] = cpu_to_scr(np->p_notask);
11984
11985 lp->cb_tags = m_calloc(MAX_TAGS, "CB_TAGS");
11986 if (!lp->cb_tags)
11987 goto fail;
11988 for (i = 0 ; i < MAX_TAGS ; i++)
11989 lp->cb_tags[i] = i;
11990
11991 lp->maxnxs = MAX_TAGS;
11992 lp->tags_stime = ktime_get(3*HZ);
11993 }
11994
11995
11996
11997
11998 if ((inq_byte7 ^ lp->inq_byte7) & INQ7_QUEUE) {
11999 lp->inq_byte7 = inq_byte7;
12000 lp->numtags = lp->maxtags;
12001 ncr_setup_tags (np, tn, ln);
12002 }
12003
12004fail:
12005 return lp;
12006}
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053#define SCATTER_ONE(data, badd, len) \
12054 (data)->addr = cpu_to_scr(badd); \
12055 (data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len);
12056
12057#define CROSS_16MB(p, n) (((((u_long) p) + n - 1) ^ ((u_long) p)) & ~0xffffff)
12058
12059static int ncr_scatter_no_sglist(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd)
12060{
12061 struct scr_tblmove *data = &cp->phys.data[MAX_SCATTER-1];
12062 int segment;
12063
12064 cp->data_len = cmd->request_bufflen;
12065
12066 if (cmd->request_bufflen) {
12067 dma_addr_t baddr = map_scsi_single_data(np, cmd);
12068
12069 SCATTER_ONE(data, baddr, cmd->request_bufflen);
12070 if (CROSS_16MB(baddr, cmd->request_bufflen)) {
12071 cp->host_flags |= HF_PM_TO_C;
12072#ifdef DEBUG_896R1
12073printk("He! we are crossing a 16 MB boundary (0x%lx, 0x%x)\n",
12074 baddr, cmd->request_bufflen);
12075#endif
12076 }
12077 segment = 1;
12078 }
12079 else
12080 segment = 0;
12081
12082 return segment;
12083}
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099static int ncr_scatter_896R1(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd)
12100{
12101 int segn;
12102 int use_sg = (int) cmd->use_sg;
12103
12104 cp->data_len = 0;
12105
12106 if (!use_sg)
12107 segn = ncr_scatter_no_sglist(np, cp, cmd);
12108 else {
12109 struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
12110 struct scr_tblmove *data;
12111
12112 use_sg = map_scsi_sg_data(np, cmd);
12113 if (use_sg > MAX_SCATTER) {
12114 unmap_scsi_data(np, cmd);
12115 return -1;
12116 }
12117
12118 data = &cp->phys.data[MAX_SCATTER - use_sg];
12119
12120 for (segn = 0; segn < use_sg; segn++) {
12121 dma_addr_t baddr = scsi_sg_dma_address(&scatter[segn]);
12122 unsigned int len = scsi_sg_dma_len(&scatter[segn]);
12123
12124 SCATTER_ONE(&data[segn],
12125 baddr,
12126 len);
12127 if (CROSS_16MB(baddr, scatter[segn].length)) {
12128 cp->host_flags |= HF_PM_TO_C;
12129#ifdef DEBUG_896R1
12130printk("He! we are crossing a 16 MB boundary (0x%lx, 0x%x)\n",
12131 baddr, scatter[segn].length);
12132#endif
12133 }
12134 cp->data_len += len;
12135 }
12136 }
12137
12138 return segn;
12139}
12140
12141static int ncr_scatter(ncb_p np, ccb_p cp, Scsi_Cmnd *cmd)
12142{
12143 int segment;
12144 int use_sg = (int) cmd->use_sg;
12145
12146 cp->data_len = 0;
12147
12148 if (!use_sg)
12149 segment = ncr_scatter_no_sglist(np, cp, cmd);
12150 else {
12151 struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
12152 struct scr_tblmove *data;
12153
12154 use_sg = map_scsi_sg_data(np, cmd);
12155 if (use_sg > MAX_SCATTER) {
12156 unmap_scsi_data(np, cmd);
12157 return -1;
12158 }
12159 data = &cp->phys.data[MAX_SCATTER - use_sg];
12160
12161 for (segment = 0; segment < use_sg; segment++) {
12162 dma_addr_t baddr = scsi_sg_dma_address(&scatter[segment]);
12163 unsigned int len = scsi_sg_dma_len(&scatter[segment]);
12164
12165 SCATTER_ONE(&data[segment],
12166 baddr,
12167 len);
12168 cp->data_len += len;
12169 }
12170 }
12171
12172 return segment;
12173}
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186#ifndef SCSI_NCR_IOMAPPED
12187static int __init ncr_regtest (struct ncb* np)
12188{
12189 register volatile u_int32 data;
12190
12191
12192
12193
12194
12195 data = 0xffffffff;
12196 OUTL_OFF(offsetof(struct ncr_reg, nc_dstat), data);
12197 data = INL_OFF(offsetof(struct ncr_reg, nc_dstat));
12198#if 1
12199 if (data == 0xffffffff) {
12200#else
12201 if ((data & 0xe2f0fffd) != 0x02000080) {
12202#endif
12203 printk ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
12204 (unsigned) data);
12205 return (0x10);
12206 };
12207 return (0);
12208}
12209#endif
12210
12211static int __init ncr_snooptest (struct ncb* np)
12212{
12213 u_int32 ncr_rd, ncr_wr, ncr_bk, host_rd, host_wr, pc;
12214 u_char dstat;
12215 int i, err=0;
12216#ifndef SCSI_NCR_IOMAPPED
12217 if (np->reg) {
12218 err |= ncr_regtest (np);
12219 if (err) return (err);
12220 }
12221#endif
12222restart_test:
12223
12224
12225
12226
12227 OUTB (nc_ctest4, (np->rv_ctest4 & MPEE));
12228
12229
12230
12231 pc = NCB_SCRIPTH0_PHYS (np, snooptest);
12232 host_wr = 1;
12233 ncr_wr = 2;
12234
12235
12236
12237 np->ncr_cache = cpu_to_scr(host_wr);
12238 OUTL (nc_temp, ncr_wr);
12239
12240
12241
12242 OUTL (nc_dsa, np->p_ncb);
12243 OUTL_DSP (pc);
12244
12245
12246
12247 for (i=0; i<NCR_SNOOP_TIMEOUT; i++)
12248 if (INB(nc_istat) & (INTF|SIP|DIP))
12249 break;
12250 if (i>=NCR_SNOOP_TIMEOUT) {
12251 printk ("CACHE TEST FAILED: timeout.\n");
12252 return (0x20);
12253 };
12254
12255
12256
12257 dstat = INB (nc_dstat);
12258#if 1
12259 if ((dstat & MDPE) && (np->rv_ctest4 & MPEE)) {
12260 printk ("%s: PCI DATA PARITY ERROR DETECTED - "
12261 "DISABLING MASTER DATA PARITY CHECKING.\n",
12262 ncr_name(np));
12263 np->rv_ctest4 &= ~MPEE;
12264 goto restart_test;
12265 }
12266#endif
12267 if (dstat & (MDPE|BF|IID)) {
12268 printk ("CACHE TEST FAILED: DMA error (dstat=0x%02x).", dstat);
12269 return (0x80);
12270 }
12271
12272
12273
12274 pc = INL (nc_dsp);
12275
12276
12277
12278 host_rd = scr_to_cpu(np->ncr_cache);
12279 ncr_rd = INL (nc_scratcha);
12280 ncr_bk = INL (nc_temp);
12281
12282
12283
12284 if (pc != NCB_SCRIPTH0_PHYS (np, snoopend)+8) {
12285 printk ("CACHE TEST FAILED: script execution failed.\n");
12286 printk ("start=%08lx, pc=%08lx, end=%08lx\n",
12287 (u_long) NCB_SCRIPTH0_PHYS (np, snooptest), (u_long) pc,
12288 (u_long) NCB_SCRIPTH0_PHYS (np, snoopend) +8);
12289 return (0x40);
12290 };
12291
12292
12293
12294 if (host_wr != ncr_rd) {
12295 printk ("CACHE TEST FAILED: host wrote %d, ncr read %d.\n",
12296 (int) host_wr, (int) ncr_rd);
12297 err |= 1;
12298 };
12299 if (host_rd != ncr_wr) {
12300 printk ("CACHE TEST FAILED: ncr wrote %d, host read %d.\n",
12301 (int) ncr_wr, (int) host_rd);
12302 err |= 2;
12303 };
12304 if (ncr_bk != ncr_wr) {
12305 printk ("CACHE TEST FAILED: ncr wrote %d, read back %d.\n",
12306 (int) ncr_wr, (int) ncr_bk);
12307 err |= 4;
12308 };
12309 return (err);
12310}
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339static void ncr_selectclock(ncb_p np, u_char scntl3)
12340{
12341 if (np->multiplier < 2) {
12342 OUTB(nc_scntl3, scntl3);
12343 return;
12344 }
12345
12346 if (bootverbose >= 2)
12347 printk ("%s: enabling clock multiplier\n", ncr_name(np));
12348
12349 OUTB(nc_stest1, DBLEN);
12350
12351 if ( (np->device_id != PCI_DEVICE_ID_LSI_53C1010) &&
12352 (np->device_id != PCI_DEVICE_ID_LSI_53C1010_66) &&
12353 (np->multiplier > 2)) {
12354 int i = 20;
12355 while (!(INB(nc_stest4) & LCKFRQ) && --i > 0)
12356 UDELAY (20);
12357 if (!i)
12358 printk("%s: the chip cannot lock the frequency\n",
12359 ncr_name(np));
12360
12361 } else
12362 UDELAY (120);
12363
12364 OUTB(nc_stest3, HSC);
12365 OUTB(nc_scntl3, scntl3);
12366 OUTB(nc_stest1, (DBLEN|DBLSEL));
12367 OUTB(nc_stest3, 0x00);
12368}
12369
12370
12371
12372
12373
12374static unsigned __init ncrgetfreq (ncb_p np, int gen)
12375{
12376 unsigned int ms = 0;
12377 unsigned int f;
12378 int count;
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395 OUTW (nc_sien , 0x0);
12396
12397 (void) INW (nc_sist);
12398 OUTB (nc_dien , 0);
12399 (void) INW (nc_sist);
12400 OUTB (nc_scntl3, 4);
12401 OUTB (nc_stime1, 0);
12402 OUTB (nc_stime1, gen);
12403
12404
12405 while (!(INW(nc_sist) & GEN) && ms++ < 100000) {
12406
12407 for (count = 0; count < 10; count++)
12408 UDELAY (100);
12409 }
12410 OUTB (nc_stime1, 0);
12411
12412
12413
12414
12415
12416 OUTB (nc_scntl3, 0);
12417
12418
12419
12420
12421
12422 f = ms ? ((1 << gen) * 4340) / ms : 0;
12423
12424 if (bootverbose >= 2)
12425 printk ("%s: Delay (GEN=%d): %u msec, %u KHz\n",
12426 ncr_name(np), gen, ms, f);
12427
12428 return f;
12429}
12430
12431static unsigned __init ncr_getfreq (ncb_p np)
12432{
12433 u_int f1, f2;
12434 int gen = 11;
12435
12436 (void) ncrgetfreq (np, gen);
12437 f1 = ncrgetfreq (np, gen);
12438 f2 = ncrgetfreq (np, gen);
12439 if (f1 > f2) f1 = f2;
12440 return f1;
12441}
12442
12443
12444
12445
12446static void __init ncr_getclock (ncb_p np, int mult)
12447{
12448 unsigned char scntl3 = np->sv_scntl3;
12449 unsigned char stest1 = np->sv_stest1;
12450 unsigned f1;
12451
12452 np->multiplier = 1;
12453 f1 = 40000;
12454
12455
12456
12457
12458 if (mult > 1 && (stest1 & (DBLEN+DBLSEL)) == DBLEN+DBLSEL) {
12459 if (bootverbose >= 2)
12460 printk ("%s: clock multiplier found\n", ncr_name(np));
12461 np->multiplier = mult;
12462 }
12463
12464
12465
12466
12467
12468
12469 if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
12470 OUTB (nc_stest1, 0);
12471 f1 = ncr_getfreq (np);
12472
12473 if (bootverbose)
12474 printk ("%s: NCR clock is %uKHz\n", ncr_name(np), f1);
12475
12476 if (f1 < 55000) f1 = 40000;
12477 else f1 = 80000;
12478
12479
12480
12481
12482
12483
12484 if (np->features & FE_66MHZ) {
12485 np->pciclock_min = (66000*55+80-1)/80;
12486 np->pciclock_max = (66000*55)/40;
12487 }
12488 else {
12489 np->pciclock_min = (33000*55+80-1)/80;
12490 np->pciclock_max = (33000*55)/40;
12491 }
12492
12493 if (f1 == 40000 && mult > 1) {
12494 if (bootverbose >= 2)
12495 printk ("%s: clock multiplier assumed\n", ncr_name(np));
12496 np->multiplier = mult;
12497 }
12498 } else {
12499 if ((scntl3 & 7) == 3) f1 = 40000;
12500 else if ((scntl3 & 7) == 5) f1 = 80000;
12501 else f1 = 160000;
12502
12503 f1 /= np->multiplier;
12504 }
12505
12506
12507
12508
12509 f1 *= np->multiplier;
12510 np->clock_khz = f1;
12511}
12512
12513
12514
12515
12516static u_int __init ncr_getpciclock (ncb_p np)
12517{
12518 static u_int f;
12519
12520 OUTB (nc_stest1, SCLK);
12521 f = ncr_getfreq (np);
12522 OUTB (nc_stest1, 0);
12523
12524 return f;
12525}
12526
12527
12528
12529#ifndef uchar
12530#define uchar unsigned char
12531#endif
12532
12533#ifndef ushort
12534#define ushort unsigned short
12535#endif
12536
12537#ifndef ulong
12538#define ulong unsigned long
12539#endif
12540
12541
12542
12543
12544
12545
12546
12547
12548#ifdef MODULE
12549#define ARG_SEP ' '
12550#else
12551#define ARG_SEP ','
12552#endif
12553
12554#define OPT_TAGS 1
12555#define OPT_MASTER_PARITY 2
12556#define OPT_SCSI_PARITY 3
12557#define OPT_DISCONNECTION 4
12558#define OPT_SPECIAL_FEATURES 5
12559#define OPT_RESERVED_1 6
12560#define OPT_FORCE_SYNC_NEGO 7
12561#define OPT_REVERSE_PROBE 8
12562#define OPT_DEFAULT_SYNC 9
12563#define OPT_VERBOSE 10
12564#define OPT_DEBUG 11
12565#define OPT_BURST_MAX 12
12566#define OPT_LED_PIN 13
12567#define OPT_MAX_WIDE 14
12568#define OPT_SETTLE_DELAY 15
12569#define OPT_DIFF_SUPPORT 16
12570#define OPT_IRQM 17
12571#define OPT_PCI_FIX_UP 18
12572#define OPT_BUS_CHECK 19
12573#define OPT_OPTIMIZE 20
12574#define OPT_RECOVERY 21
12575#define OPT_SAFE_SETUP 22
12576#define OPT_USE_NVRAM 23
12577#define OPT_EXCLUDE 24
12578#define OPT_HOST_ID 25
12579
12580#ifdef SCSI_NCR_IARB_SUPPORT
12581#define OPT_IARB 26
12582#endif
12583
12584static char setup_token[] __initdata =
12585 "tags:" "mpar:"
12586 "spar:" "disc:"
12587 "specf:" "_rsvd1:"
12588 "fsn:" "revprob:"
12589 "sync:" "verb:"
12590 "debug:" "burst:"
12591 "led:" "wide:"
12592 "settle:" "diff:"
12593 "irqm:" "pcifix:"
12594 "buschk:" "optim:"
12595 "recovery:"
12596 "safe:" "nvram:"
12597 "excl:" "hostid:"
12598#ifdef SCSI_NCR_IARB_SUPPORT
12599 "iarb:"
12600#endif
12601 ;
12602
12603#ifdef MODULE
12604#define ARG_SEP ' '
12605#else
12606#define ARG_SEP ','
12607#endif
12608
12609static int __init get_setup_token(char *p)
12610{
12611 char *cur = setup_token;
12612 char *pc;
12613 int i = 0;
12614
12615 while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
12616 ++pc;
12617 ++i;
12618 if (!strncmp(p, cur, pc - cur))
12619 return i;
12620 cur = pc;
12621 }
12622 return 0;
12623}
12624
12625
12626int __init sym53c8xx_setup(char *str)
12627{
12628#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
12629 char *cur = str;
12630 char *pc, *pv;
12631 unsigned long val;
12632 int i, c;
12633 int xi = 0;
12634
12635 while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
12636 char *pe;
12637
12638 val = 0;
12639 pv = pc;
12640 c = *++pv;
12641
12642 if (c == 'n')
12643 val = 0;
12644 else if (c == 'y')
12645 val = 1;
12646 else
12647 val = (int) simple_strtoul(pv, &pe, 0);
12648
12649 switch (get_setup_token(cur)) {
12650 case OPT_TAGS:
12651 driver_setup.default_tags = val;
12652 if (pe && *pe == '/') {
12653 i = 0;
12654 while (*pe && *pe != ARG_SEP &&
12655 i < sizeof(driver_setup.tag_ctrl)-1) {
12656 driver_setup.tag_ctrl[i++] = *pe++;
12657 }
12658 driver_setup.tag_ctrl[i] = '\0';
12659 }
12660 break;
12661 case OPT_MASTER_PARITY:
12662 driver_setup.master_parity = val;
12663 break;
12664 case OPT_SCSI_PARITY:
12665 driver_setup.scsi_parity = val;
12666 break;
12667 case OPT_DISCONNECTION:
12668 driver_setup.disconnection = val;
12669 break;
12670 case OPT_SPECIAL_FEATURES:
12671 driver_setup.special_features = val;
12672 break;
12673 case OPT_FORCE_SYNC_NEGO:
12674 driver_setup.force_sync_nego = val;
12675 break;
12676 case OPT_REVERSE_PROBE:
12677 driver_setup.reverse_probe = val;
12678 break;
12679 case OPT_DEFAULT_SYNC:
12680 driver_setup.default_sync = val;
12681 break;
12682 case OPT_VERBOSE:
12683 driver_setup.verbose = val;
12684 break;
12685 case OPT_DEBUG:
12686 driver_setup.debug = val;
12687 break;
12688 case OPT_BURST_MAX:
12689 driver_setup.burst_max = val;
12690 break;
12691 case OPT_LED_PIN:
12692 driver_setup.led_pin = val;
12693 break;
12694 case OPT_MAX_WIDE:
12695 driver_setup.max_wide = val? 1:0;
12696 break;
12697 case OPT_SETTLE_DELAY:
12698 driver_setup.settle_delay = val;
12699 break;
12700 case OPT_DIFF_SUPPORT:
12701 driver_setup.diff_support = val;
12702 break;
12703 case OPT_IRQM:
12704 driver_setup.irqm = val;
12705 break;
12706 case OPT_PCI_FIX_UP:
12707 driver_setup.pci_fix_up = val;
12708 break;
12709 case OPT_BUS_CHECK:
12710 driver_setup.bus_check = val;
12711 break;
12712 case OPT_OPTIMIZE:
12713 driver_setup.optimize = val;
12714 break;
12715 case OPT_RECOVERY:
12716 driver_setup.recovery = val;
12717 break;
12718 case OPT_USE_NVRAM:
12719 driver_setup.use_nvram = val;
12720 break;
12721 case OPT_SAFE_SETUP:
12722 memcpy(&driver_setup, &driver_safe_setup,
12723 sizeof(driver_setup));
12724 break;
12725 case OPT_EXCLUDE:
12726 if (xi < SCSI_NCR_MAX_EXCLUDES)
12727 driver_setup.excludes[xi++] = val;
12728 break;
12729 case OPT_HOST_ID:
12730 driver_setup.host_id = val;
12731 break;
12732#ifdef SCSI_NCR_IARB_SUPPORT
12733 case OPT_IARB:
12734 driver_setup.iarb = val;
12735 break;
12736#endif
12737 default:
12738 printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
12739 break;
12740 }
12741
12742 if ((cur = strchr(cur, ARG_SEP)) != NULL)
12743 ++cur;
12744 }
12745#endif
12746 return 1;
12747}
12748
12749#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
12750#ifndef MODULE
12751__setup("sym53c8xx=", sym53c8xx_setup);
12752#endif
12753#endif
12754
12755static int
12756sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device);
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773static void __init ncr_print_driver_setup(void)
12774{
12775#define YesNo(y) y ? 'y' : 'n'
12776 printk (NAME53C8XX ": setup=disc:%c,specf:%d,tags:%d,sync:%d,"
12777 "burst:%d,wide:%c,diff:%d,revprob:%c,buschk:0x%x\n",
12778 YesNo(driver_setup.disconnection),
12779 driver_setup.special_features,
12780 driver_setup.default_tags,
12781 driver_setup.default_sync,
12782 driver_setup.burst_max,
12783 YesNo(driver_setup.max_wide),
12784 driver_setup.diff_support,
12785 YesNo(driver_setup.reverse_probe),
12786 driver_setup.bus_check);
12787
12788 printk (NAME53C8XX ": setup=mpar:%c,spar:%c,fsn=%c,verb:%d,debug:0x%x,"
12789 "led:%c,settle:%d,irqm:0x%x,nvram:0x%x,pcifix:0x%x\n",
12790 YesNo(driver_setup.master_parity),
12791 YesNo(driver_setup.scsi_parity),
12792 YesNo(driver_setup.force_sync_nego),
12793 driver_setup.verbose,
12794 driver_setup.debug,
12795 YesNo(driver_setup.led_pin),
12796 driver_setup.settle_delay,
12797 driver_setup.irqm,
12798 driver_setup.use_nvram,
12799 driver_setup.pci_fix_up);
12800#undef YesNo
12801}
12802
12803
12804
12805
12806
12807
12808static ncr_chip ncr_chip_table[] __initdata = SCSI_NCR_CHIP_TABLE;
12809static ushort ncr_chip_ids[] __initdata = SCSI_NCR_CHIP_IDS;
12810
12811#ifdef SCSI_NCR_PQS_PDS_SUPPORT
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828#define SCSI_NCR_MAX_PQS_BUS 16
12829static int pqs_bus[SCSI_NCR_MAX_PQS_BUS] __initdata = { 0 };
12830
12831static void __init ncr_detect_pqs_pds(void)
12832{
12833 short index;
12834 pcidev_t dev = PCIDEV_NULL;
12835
12836 for(index=0; index < SCSI_NCR_MAX_PQS_BUS; index++) {
12837 u_char tmp;
12838
12839 dev = pci_find_device(0x101a, 0x0009, dev);
12840 if (dev == PCIDEV_NULL) {
12841 pqs_bus[index] = -1;
12842 break;
12843 }
12844 printk(KERN_INFO NAME53C8XX ": NCR PQS/PDS memory controller detected on bus %d\n", PciBusNumber(dev));
12845 pci_read_config_byte(dev, 0x44, &tmp);
12846
12847 tmp |= 0x2;
12848 pci_write_config_byte(dev, 0x44, tmp);
12849 pci_read_config_byte(dev, 0x45, &tmp);
12850
12851 tmp |= 0x4;
12852 pci_write_config_byte(dev, 0x45, tmp);
12853
12854 pqs_bus[index] = PciBusNumber(dev);
12855 }
12856}
12857#endif
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870int __init sym53c8xx_detect(Scsi_Host_Template *tpnt)
12871{
12872 pcidev_t pcidev;
12873 int i, j, chips, hosts, count;
12874 int attach_count = 0;
12875 ncr_device *devtbl, *devp;
12876#ifdef SCSI_NCR_NVRAM_SUPPORT
12877 ncr_nvram nvram0, nvram, *nvp;
12878#endif
12879
12880
12881
12882
12883 if (!pci_present())
12884 return 0;
12885
12886
12887
12888
12889#ifdef SCSI_NCR_PROC_INFO_SUPPORT
12890#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
12891 tpnt->proc_dir = &proc_scsi_sym53c8xx;
12892#else
12893 tpnt->proc_name = NAME53C8XX;
12894#endif
12895 tpnt->proc_info = sym53c8xx_proc_info;
12896#endif
12897
12898#if defined(SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT) && defined(MODULE)
12899if (sym53c8xx)
12900 sym53c8xx_setup(sym53c8xx);
12901#endif
12902#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
12903 ncr_debug = driver_setup.debug;
12904#endif
12905
12906 if (initverbose >= 2)
12907 ncr_print_driver_setup();
12908
12909
12910
12911
12912
12913
12914 devtbl = m_calloc(PAGE_SIZE, "devtbl");
12915 if (!devtbl)
12916 return 0;
12917
12918
12919
12920
12921#ifdef SCSI_NCR_PQS_PDS_SUPPORT
12922 ncr_detect_pqs_pds();
12923#endif
12924
12925
12926
12927
12928
12929
12930 chips = sizeof(ncr_chip_ids) / sizeof(ncr_chip_ids[0]);
12931 hosts = PAGE_SIZE / sizeof(*devtbl);
12932#ifdef SCSI_NCR_NVRAM_SUPPORT
12933 nvp = (driver_setup.use_nvram & 0x1) ? &nvram0 : 0;
12934#endif
12935 j = 0;
12936 count = 0;
12937 pcidev = PCIDEV_NULL;
12938 while (1) {
12939 char *msg = "";
12940 if (count >= hosts)
12941 break;
12942 if (j >= chips)
12943 break;
12944 i = driver_setup.reverse_probe ? chips - 1 - j : j;
12945 pcidev = pci_find_device(PCI_VENDOR_ID_NCR, ncr_chip_ids[i],
12946 pcidev);
12947 if (pcidev == PCIDEV_NULL) {
12948 ++j;
12949 continue;
12950 }
12951 if (pci_enable_device(pcidev))
12952 continue;
12953
12954 for (i = 0; i < count ; i++) {
12955 if (devtbl[i].slot.bus == PciBusNumber(pcidev) &&
12956 devtbl[i].slot.device_fn == PciDeviceFn(pcidev))
12957 break;
12958 }
12959 if (i != count)
12960 continue;
12961 devp = &devtbl[count];
12962 devp->host_id = driver_setup.host_id;
12963 devp->attach_done = 0;
12964 if (sym53c8xx_pci_init(tpnt, pcidev, devp)) {
12965 continue;
12966 }
12967 ++count;
12968#ifdef SCSI_NCR_NVRAM_SUPPORT
12969 if (nvp) {
12970 ncr_get_nvram(devp, nvp);
12971 switch(nvp->type) {
12972 case SCSI_NCR_SYMBIOS_NVRAM:
12973
12974
12975
12976
12977
12978 nvp = &nvram;
12979 msg = "with Symbios NVRAM";
12980 break;
12981 case SCSI_NCR_TEKRAM_NVRAM:
12982 msg = "with Tekram NVRAM";
12983 break;
12984 }
12985 }
12986#endif
12987#ifdef SCSI_NCR_PQS_PDS_SUPPORT
12988 if (devp->pqs_pds)
12989 msg = "(NCR PQS/PDS)";
12990#endif
12991 printk(KERN_INFO NAME53C8XX ": 53c%s detected %s\n",
12992 devp->chip.name, msg);
12993 }
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005#ifdef SCSI_NCR_NVRAM_SUPPORT
13006 if (!nvp || nvram0.type != SCSI_NCR_SYMBIOS_NVRAM)
13007 goto next;
13008 for (i = 0; i < 4; i++) {
13009 Symbios_host *h = &nvram0.data.Symbios.host[i];
13010 for (j = 0 ; j < count ; j++) {
13011 devp = &devtbl[j];
13012 if (h->device_fn != devp->slot.device_fn ||
13013 h->bus_nr != devp->slot.bus ||
13014 h->device_id != devp->chip.device_id)
13015 continue;
13016 if (devp->attach_done)
13017 continue;
13018 if (h->flags & SYMBIOS_INIT_SCAN_AT_BOOT) {
13019 ncr_get_nvram(devp, nvp);
13020 if (!ncr_attach (tpnt, attach_count, devp))
13021 attach_count++;
13022 }
13023 else if (!(driver_setup.use_nvram & 0x80))
13024 printk(KERN_INFO NAME53C8XX
13025 ": 53c%s state OFF thus not attached\n",
13026 devp->chip.name);
13027 else
13028 continue;
13029
13030 devp->attach_done = 1;
13031 break;
13032 }
13033 }
13034next:
13035#endif
13036
13037
13038
13039
13040
13041
13042 for (i= 0; i < count; i++) {
13043 devp = &devtbl[i];
13044 if (!devp->attach_done) {
13045#ifdef SCSI_NCR_NVRAM_SUPPORT
13046 ncr_get_nvram(devp, nvp);
13047#endif
13048 if (!ncr_attach (tpnt, attach_count, devp))
13049 attach_count++;
13050 }
13051 }
13052
13053 m_free(devtbl, PAGE_SIZE, "devtbl");
13054
13055 return attach_count;
13056}
13057
13058
13059
13060
13061
13062
13063
13064static int __init
13065sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device)
13066{
13067 u_short vendor_id, device_id, command, status_reg;
13068 u_char cache_line_size, latency_timer;
13069 u_char suggested_cache_line_size = 0;
13070 u_char pci_fix_up = driver_setup.pci_fix_up;
13071 u_char revision;
13072 u_int irq;
13073 u_long base, base_c, base_2, base_2_c, io_port;
13074 int i;
13075 ncr_chip *chip;
13076
13077 printk(KERN_INFO NAME53C8XX ": at PCI bus %d, device %d, function %d\n",
13078 PciBusNumber(pdev),
13079 (int) (PciDeviceFn(pdev) & 0xf8) >> 3,
13080 (int) (PciDeviceFn(pdev) & 7));
13081
13082
13083
13084
13085
13086
13087 vendor_id = PciVendorId(pdev);
13088 device_id = PciDeviceId(pdev);
13089 irq = PciIrqLine(pdev);
13090
13091 i = pci_get_base_address(pdev, 0, &io_port);
13092 io_port = pci_get_base_cookie(pdev, 0);
13093
13094 base_c = pci_get_base_cookie(pdev, i);
13095 i = pci_get_base_address(pdev, i, &base);
13096
13097 base_2_c = pci_get_base_cookie(pdev, i);
13098 (void) pci_get_base_address(pdev, i, &base_2);
13099
13100 pci_read_config_word(pdev, PCI_COMMAND, &command);
13101 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
13102 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size);
13103 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer);
13104 pci_read_config_word(pdev, PCI_STATUS, &status_reg);
13105
13106#ifdef SCSI_NCR_PQS_PDS_SUPPORT
13107
13108
13109
13110
13111
13112
13113 for(i = 0; i < SCSI_NCR_MAX_PQS_BUS && pqs_bus[i] != -1; i++) {
13114 u_char tmp;
13115 if (pqs_bus[i] == PciBusNumber(pdev)) {
13116 pci_read_config_byte(pdev, 0x84, &tmp);
13117 device->pqs_pds = 1;
13118 device->host_id = tmp;
13119 break;
13120 }
13121 }
13122#endif
13123
13124
13125
13126
13127 for (i = 0 ; i < SCSI_NCR_MAX_EXCLUDES ; i++) {
13128 if (driver_setup.excludes[i] ==
13129 (io_port & PCI_BASE_ADDRESS_IO_MASK))
13130 return -1;
13131 }
13132
13133
13134
13135 chip = 0;
13136 for (i = 0; i < sizeof(ncr_chip_table)/sizeof(ncr_chip_table[0]); i++) {
13137 if (device_id != ncr_chip_table[i].device_id)
13138 continue;
13139 if (revision > ncr_chip_table[i].revision_id)
13140 continue;
13141 if (!(ncr_chip_table[i].features & FE_LDSTR))
13142 break;
13143 chip = &device->chip;
13144 memcpy(chip, &ncr_chip_table[i], sizeof(*chip));
13145 chip->revision_id = revision;
13146 break;
13147 }
13148
13149#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
13150
13151
13152
13153
13154
13155 if (chip && (chip->features & FE_DAC)) {
13156 if (pci_set_dma_mask(pdev, (u64) 0xffffffffff))
13157 chip->features &= ~FE_DAC_IN_USE;
13158 else
13159 chip->features |= FE_DAC_IN_USE;
13160 }
13161
13162 if (chip && !(chip->features & FE_DAC_IN_USE)) {
13163 if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
13164 printk(KERN_WARNING NAME53C8XX
13165 "32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
13166 return -1;
13167 }
13168 }
13169#endif
13170
13171
13172
13173
13174
13175#if defined(__i386__) && !defined(SCSI_NCR_PCI_MEM_NOT_SUPPORTED)
13176 if (chip && (base_2_c & PCI_BASE_ADDRESS_MEM_MASK)) {
13177 unsigned int ram_size, ram_val;
13178 u_long ram_ptr;
13179
13180 if (chip->features & FE_RAM8K)
13181 ram_size = 8192;
13182 else
13183 ram_size = 4096;
13184
13185 ram_ptr = remap_pci_mem(base_2_c & PCI_BASE_ADDRESS_MEM_MASK,
13186 ram_size);
13187 if (ram_ptr) {
13188 ram_val = readl_raw(ram_ptr + ram_size - 16);
13189 unmap_pci_mem(ram_ptr, ram_size);
13190 if (ram_val == 0x52414944) {
13191 printk(NAME53C8XX": not initializing, "
13192 "driven by SISL RAID controller.\n");
13193 return -1;
13194 }
13195 }
13196 }
13197#endif
13198
13199 if (!chip) {
13200 printk(NAME53C8XX ": not initializing, device not supported\n");
13201 return -1;
13202 }
13203
13204#ifdef __powerpc__
13205
13206
13207
13208
13209 if ((command & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))
13210 != (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
13211 printk(NAME53C8XX ": setting%s%s...\n",
13212 (command & PCI_COMMAND_IO) ? "" : " PCI_COMMAND_IO",
13213 (command & PCI_COMMAND_MEMORY) ? "" : " PCI_COMMAND_MEMORY");
13214 command |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
13215 pci_write_config_word(pdev, PCI_COMMAND, command);
13216 }
13217
13218#if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)
13219 if ( is_prep ) {
13220 if (io_port >= 0x10000000) {
13221 printk(NAME53C8XX ": reallocating io_port (Wacky IBM)");
13222 io_port = (io_port & 0x00FFFFFF) | 0x01000000;
13223 pci_write_config_dword(pdev,
13224 PCI_BASE_ADDRESS_0, io_port);
13225 }
13226 if (base >= 0x10000000) {
13227 printk(NAME53C8XX ": reallocating base (Wacky IBM)");
13228 base = (base & 0x00FFFFFF) | 0x01000000;
13229 pci_write_config_dword(pdev,
13230 PCI_BASE_ADDRESS_1, base);
13231 }
13232 if (base_2 >= 0x10000000) {
13233 printk(NAME53C8XX ": reallocating base2 (Wacky IBM)");
13234 base_2 = (base_2 & 0x00FFFFFF) | 0x01000000;
13235 pci_write_config_dword(pdev,
13236 PCI_BASE_ADDRESS_2, base_2);
13237 }
13238 }
13239#endif
13240#endif
13241
13242#if defined(__i386__) && !defined(MODULE)
13243 if (!cache_line_size) {
13244#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,75)
13245 extern char x86;
13246 switch(x86) {
13247#else
13248 switch(boot_cpu_data.x86) {
13249#endif
13250 case 4: suggested_cache_line_size = 4; break;
13251 case 6:
13252 case 5: suggested_cache_line_size = 8; break;
13253 }
13254 }
13255#endif
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268#if 1
13269 if (!(command & PCI_COMMAND_IO)) {
13270 printk(NAME53C8XX ": I/O base address (0x%lx) disabled.\n",
13271 (long) io_port);
13272 io_port = 0;
13273 }
13274#endif
13275 if (!(command & PCI_COMMAND_MEMORY)) {
13276 printk(NAME53C8XX ": PCI_COMMAND_MEMORY not set.\n");
13277 base = 0;
13278 base_2 = 0;
13279 }
13280 io_port &= PCI_BASE_ADDRESS_IO_MASK;
13281 base &= PCI_BASE_ADDRESS_MEM_MASK;
13282 base_2 &= PCI_BASE_ADDRESS_MEM_MASK;
13283
13284
13285#if 1
13286 if (io_port && check_region (io_port, 128)) {
13287 printk(NAME53C8XX ": IO region 0x%lx[0..127] is in use\n",
13288 (long) io_port);
13289 io_port = 0;
13290 }
13291 if (!io_port)
13292 return -1;
13293#endif
13294#ifndef SCSI_NCR_IOMAPPED
13295 if (!base) {
13296 printk(NAME53C8XX ": MMIO base address disabled.\n");
13297 return -1;
13298 }
13299#endif
13300
13301
13302
13303
13304 if ((command & (PCI_COMMAND_MASTER | PCI_COMMAND_PARITY))
13305 != (PCI_COMMAND_MASTER | PCI_COMMAND_PARITY)) {
13306 printk(NAME53C8XX ": setting%s%s...(fix-up)\n",
13307 (command & PCI_COMMAND_MASTER) ? "" : " PCI_COMMAND_MASTER",
13308 (command & PCI_COMMAND_PARITY) ? "" : " PCI_COMMAND_PARITY");
13309 command |= (PCI_COMMAND_MASTER | PCI_COMMAND_PARITY);
13310 pci_write_config_word(pdev, PCI_COMMAND, command);
13311 }
13312
13313
13314
13315
13316 if (!(driver_setup.special_features & 1))
13317 chip->features &= ~FE_SPECIAL_SET;
13318 else {
13319 if (driver_setup.special_features & 2)
13320 chip->features &= ~FE_WRIE;
13321 if (driver_setup.special_features & 4)
13322 chip->features &= ~FE_NOPM;
13323 }
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336 if (chip->features & FE_66MHZ) {
13337 if (!(status_reg & PCI_STATUS_66MHZ))
13338 chip->features &= ~FE_66MHZ;
13339 }
13340 else {
13341 if (status_reg & PCI_STATUS_66MHZ) {
13342 status_reg = PCI_STATUS_66MHZ;
13343 pci_write_config_word(pdev, PCI_STATUS, status_reg);
13344 pci_read_config_word(pdev, PCI_STATUS, &status_reg);
13345 }
13346 }
13347
13348
13349
13350
13351
13352
13353
13354
13355 if (device_id == PCI_DEVICE_ID_NCR_53C896 && revision <= 0x10) {
13356 chip->features |= (FE_WRIE | FE_CLSE);
13357 pci_fix_up |= 3;
13358 }
13359
13360#ifdef SCSI_NCR_PCI_FIX_UP_SUPPORT
13361
13362
13363
13364 if ((pci_fix_up & 1) && (chip->features & FE_CLSE) &&
13365 !cache_line_size && suggested_cache_line_size) {
13366 cache_line_size = suggested_cache_line_size;
13367 pci_write_config_byte(pdev,
13368 PCI_CACHE_LINE_SIZE, cache_line_size);
13369 printk(NAME53C8XX ": PCI_CACHE_LINE_SIZE set to %d (fix-up).\n",
13370 cache_line_size);
13371 }
13372
13373 if ((pci_fix_up & 2) && cache_line_size &&
13374 (chip->features & FE_WRIE) && !(command & PCI_COMMAND_INVALIDATE)) {
13375 printk(NAME53C8XX": setting PCI_COMMAND_INVALIDATE (fix-up)\n");
13376 command |= PCI_COMMAND_INVALIDATE;
13377 pci_write_config_word(pdev, PCI_COMMAND, command);
13378 }
13379
13380
13381
13382
13383
13384
13385 if (chip->burst_max && (latency_timer == 0 || (pci_fix_up & 4))) {
13386 uchar lt = (1 << chip->burst_max) + 6 + 10;
13387 if (latency_timer < lt) {
13388 printk(NAME53C8XX
13389 ": changing PCI_LATENCY_TIMER from %d to %d.\n",
13390 (int) latency_timer, (int) lt);
13391 latency_timer = lt;
13392 pci_write_config_byte(pdev,
13393 PCI_LATENCY_TIMER, latency_timer);
13394 }
13395 }
13396
13397#endif
13398
13399
13400
13401
13402 device->pdev = pdev;
13403 device->slot.bus = PciBusNumber(pdev);
13404 device->slot.device_fn = PciDeviceFn(pdev);
13405 device->slot.base = base;
13406 device->slot.base_2 = base_2;
13407 device->slot.base_c = base_c;
13408 device->slot.base_2_c = base_2_c;
13409 device->slot.io_port = io_port;
13410 device->slot.irq = irq;
13411 device->attach_done = 0;
13412
13413 return 0;
13414}
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424
13425
13426
13427
13428
13429#ifdef SCSI_NCR_NVRAM_SUPPORT
13430static void __init ncr_get_nvram(ncr_device *devp, ncr_nvram *nvp)
13431{
13432 devp->nvram = nvp;
13433 if (!nvp)
13434 return;
13435
13436
13437
13438#ifdef SCSI_NCR_IOMAPPED
13439 request_region(devp->slot.io_port, 128, NAME53C8XX);
13440 devp->slot.base_io = devp->slot.io_port;
13441#else
13442 devp->slot.reg =
13443 (struct ncr_reg *) remap_pci_mem(devp->slot.base_c, 128);
13444 if (!devp->slot.reg)
13445 return;
13446#endif
13447
13448
13449
13450
13451
13452 if (!sym_read_Symbios_nvram(&devp->slot, &nvp->data.Symbios))
13453 nvp->type = SCSI_NCR_SYMBIOS_NVRAM;
13454 else if (!sym_read_Tekram_nvram(&devp->slot, devp->chip.device_id,
13455 &nvp->data.Tekram))
13456 nvp->type = SCSI_NCR_TEKRAM_NVRAM;
13457 else {
13458 nvp->type = 0;
13459 devp->nvram = 0;
13460 }
13461
13462
13463
13464
13465#ifdef SCSI_NCR_IOMAPPED
13466 release_region(devp->slot.base_io, 128);
13467#else
13468 unmap_pci_mem((u_long) devp->slot.reg, 128ul);
13469#endif
13470
13471}
13472#endif
13473
13474
13475
13476
13477
13478#define DEF_DEPTH (driver_setup.default_tags)
13479#define ALL_TARGETS -2
13480#define NO_TARGET -1
13481#define ALL_LUNS -2
13482#define NO_LUN -1
13483
13484static int device_queue_depth(ncb_p np, int target, int lun)
13485{
13486 int c, h, t, u, v;
13487 char *p = driver_setup.tag_ctrl;
13488 char *ep;
13489
13490 h = -1;
13491 t = NO_TARGET;
13492 u = NO_LUN;
13493 while ((c = *p++) != 0) {
13494 v = simple_strtoul(p, &ep, 0);
13495 switch(c) {
13496 case '/':
13497 ++h;
13498 t = ALL_TARGETS;
13499 u = ALL_LUNS;
13500 break;
13501 case 't':
13502 if (t != target)
13503 t = (target == v) ? v : NO_TARGET;
13504 u = ALL_LUNS;
13505 break;
13506 case 'u':
13507 if (u != lun)
13508 u = (lun == v) ? v : NO_LUN;
13509 break;
13510 case 'q':
13511 if (h == np->unit &&
13512 (t == ALL_TARGETS || t == target) &&
13513 (u == ALL_LUNS || u == lun))
13514 return v;
13515 break;
13516 case '-':
13517 t = ALL_TARGETS;
13518 u = ALL_LUNS;
13519 break;
13520 default:
13521 break;
13522 }
13523 p = ep;
13524 }
13525 return DEF_DEPTH;
13526}
13527
13528int sym53c8xx_slave_configure(Scsi_Device *device)
13529{
13530 struct Scsi_Host *host = device->host;
13531 ncb_p np;
13532 tcb_p tp;
13533 lcb_p lp;
13534 int numtags, depth_to_use;
13535
13536 np = ((struct host_data *) host->hostdata)->ncb;
13537 tp = &np->target[device->id];
13538 lp = ncr_lp(np, tp, device->lun);
13539
13540
13541
13542
13543
13544
13545
13546 numtags = device_queue_depth(np, device->id, device->lun);
13547 if (numtags > tp->usrtags)
13548 numtags = tp->usrtags;
13549 if (!device->tagged_supported)
13550 numtags = 1;
13551 depth_to_use = numtags;
13552 if (depth_to_use < 2)
13553 depth_to_use = 2;
13554 if (depth_to_use > MAX_TAGS)
13555 depth_to_use = MAX_TAGS;
13556
13557 scsi_adjust_queue_depth(device,
13558 (device->tagged_supported ?
13559 MSG_SIMPLE_TAG : 0),
13560 depth_to_use);
13561
13562
13563
13564
13565
13566
13567 if (lp) {
13568 lp->numtags = lp->maxtags = numtags;
13569 lp->scdev_depth = depth_to_use;
13570 }
13571 ncr_setup_tags (np, device->id, device->lun);
13572
13573#ifdef DEBUG_SYM53C8XX
13574 printk("sym53c8xx_select_queue_depth: host=%d, id=%d, lun=%d, depth=%d\n",
13575 np->unit, device->id, device->lun, depth_to_use);
13576#endif
13577
13578 return 0;
13579}
13580
13581
13582
13583
13584const char *sym53c8xx_info (struct Scsi_Host *host)
13585{
13586 return SCSI_NCR_DRIVER_NAME;
13587}
13588
13589
13590
13591
13592
13593int sym53c8xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
13594{
13595 ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
13596 unsigned long flags;
13597 int sts;
13598
13599#ifdef DEBUG_SYM53C8XX
13600printk("sym53c8xx_queue_command\n");
13601#endif
13602
13603 cmd->scsi_done = done;
13604 cmd->host_scribble = NULL;
13605 cmd->SCp.ptr = NULL;
13606 cmd->SCp.buffer = NULL;
13607#ifdef SCSI_NCR_DYNAMIC_DMA_MAPPING
13608 __data_mapped(cmd) = 0;
13609 __data_mapping(cmd) = 0;
13610#endif
13611
13612 NCR_LOCK_NCB(np, flags);
13613
13614 if ((sts = ncr_queue_command(np, cmd)) != DID_OK) {
13615 SetScsiResult(cmd, sts, 0);
13616#ifdef DEBUG_SYM53C8XX
13617printk("sym53c8xx : command not queued - result=%d\n", sts);
13618#endif
13619 }
13620#ifdef DEBUG_SYM53C8XX
13621 else
13622printk("sym53c8xx : command successfully queued\n");
13623#endif
13624
13625 NCR_UNLOCK_NCB(np, flags);
13626
13627 if (sts != DID_OK) {
13628 unmap_scsi_data(np, cmd);
13629 done(cmd);
13630 }
13631
13632 return sts;
13633}
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643static void sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
13644{
13645 unsigned long flags;
13646 ncb_p np = (ncb_p) dev_id;
13647 Scsi_Cmnd *done_list;
13648
13649#ifdef DEBUG_SYM53C8XX
13650 printk("sym53c8xx : interrupt received\n");
13651#endif
13652
13653 if (DEBUG_FLAGS & DEBUG_TINY) printk ("[");
13654
13655 NCR_LOCK_NCB(np, flags);
13656 ncr_exception(np);
13657 done_list = np->done_list;
13658 np->done_list = 0;
13659 NCR_UNLOCK_NCB(np, flags);
13660
13661 if (DEBUG_FLAGS & DEBUG_TINY) printk ("]\n");
13662
13663 if (done_list) {
13664 NCR_LOCK_SCSI_DONE(done_list->host, flags);
13665 ncr_flush_done_cmds(done_list);
13666 NCR_UNLOCK_SCSI_DONE(done_list->host, flags);
13667 }
13668}
13669
13670
13671
13672
13673
13674static void sym53c8xx_timeout(unsigned long npref)
13675{
13676 ncb_p np = (ncb_p) npref;
13677 unsigned long flags;
13678 Scsi_Cmnd *done_list;
13679
13680 NCR_LOCK_NCB(np, flags);
13681 ncr_timeout((ncb_p) np);
13682 done_list = np->done_list;
13683 np->done_list = 0;
13684 NCR_UNLOCK_NCB(np, flags);
13685
13686 if (done_list) {
13687 NCR_LOCK_SCSI_DONE(done_list->host, flags);
13688 ncr_flush_done_cmds(done_list);
13689 NCR_UNLOCK_SCSI_DONE(done_list->host, flags);
13690 }
13691}
13692
13693
13694
13695
13696
13697#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
13698int sym53c8xx_reset(Scsi_Cmnd *cmd, unsigned int reset_flags)
13699#else
13700int sym53c8xx_reset(Scsi_Cmnd *cmd)
13701#endif
13702{
13703 ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
13704 int sts;
13705 unsigned long flags;
13706 Scsi_Cmnd *done_list;
13707
13708#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
13709 printk("sym53c8xx_reset: pid=%lu reset_flags=%x serial_number=%ld serial_number_at_timeout=%ld\n",
13710 cmd->pid, reset_flags, cmd->serial_number, cmd->serial_number_at_timeout);
13711#else
13712 printk("sym53c8xx_reset: command pid %lu\n", cmd->pid);
13713#endif
13714
13715 NCR_LOCK_NCB(np, flags);
13716
13717
13718
13719
13720#if defined SCSI_RESET_NOT_RUNNING
13721 if (cmd->serial_number != cmd->serial_number_at_timeout) {
13722 sts = SCSI_RESET_NOT_RUNNING;
13723 goto out;
13724 }
13725#endif
13726
13727
13728
13729
13730
13731
13732
13733#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
13734 sts = ncr_reset_bus(np, cmd,
13735 (reset_flags & (SCSI_RESET_SYNCHRONOUS | SCSI_RESET_ASYNCHRONOUS)) == SCSI_RESET_SYNCHRONOUS);
13736#else
13737 sts = ncr_reset_bus(np, cmd, 0);
13738#endif
13739
13740
13741
13742
13743
13744#if defined SCSI_RESET_HOST_RESET
13745 if (sts == SCSI_RESET_SUCCESS)
13746 sts |= SCSI_RESET_HOST_RESET;
13747#endif
13748
13749out:
13750 done_list = np->done_list;
13751 np->done_list = 0;
13752 NCR_UNLOCK_NCB(np, flags);
13753
13754 ncr_flush_done_cmds(done_list);
13755
13756 return sts;
13757}
13758
13759
13760
13761
13762
13763int sym53c8xx_abort(Scsi_Cmnd *cmd)
13764{
13765 ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb;
13766 int sts;
13767 unsigned long flags;
13768 Scsi_Cmnd *done_list;
13769
13770#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
13771 printk("sym53c8xx_abort: pid=%lu serial_number=%ld serial_number_at_timeout=%ld\n",
13772 cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout);
13773#else
13774 printk("sym53c8xx_abort: command pid %lu\n", cmd->pid);
13775#endif
13776
13777 NCR_LOCK_NCB(np, flags);
13778
13779#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
13780
13781
13782
13783 if (cmd->serial_number != cmd->serial_number_at_timeout) {
13784 sts = SCSI_ABORT_NOT_RUNNING;
13785 goto out;
13786 }
13787#endif
13788
13789 sts = ncr_abort_command(np, cmd);
13790out:
13791 done_list = np->done_list;
13792 np->done_list = 0;
13793 NCR_UNLOCK_NCB(np, flags);
13794
13795 ncr_flush_done_cmds(done_list);
13796
13797 return sts;
13798}
13799
13800
13801#ifdef MODULE
13802int sym53c8xx_release(struct Scsi_Host *host)
13803{
13804#ifdef DEBUG_SYM53C8XX
13805printk("sym53c8xx : release\n");
13806#endif
13807 ncr_detach(((struct host_data *) host->hostdata)->ncb);
13808
13809 return 1;
13810}
13811#endif
13812
13813
13814
13815
13816
13817
13818
13819
13820
13821
13822
13823
13824
13825
13826
13827#define next_wcmd host_scribble
13828
13829static void insert_into_waiting_list(ncb_p np, Scsi_Cmnd *cmd)
13830{
13831 Scsi_Cmnd *wcmd;
13832
13833#ifdef DEBUG_WAITING_LIST
13834 printk("%s: cmd %lx inserted into waiting list\n", ncr_name(np), (u_long) cmd);
13835#endif
13836 cmd->next_wcmd = 0;
13837 if (!(wcmd = np->waiting_list)) np->waiting_list = cmd;
13838 else {
13839 while ((wcmd->next_wcmd) != 0)
13840 wcmd = (Scsi_Cmnd *) wcmd->next_wcmd;
13841 wcmd->next_wcmd = (char *) cmd;
13842 }
13843}
13844
13845static Scsi_Cmnd *retrieve_from_waiting_list(int to_remove, ncb_p np, Scsi_Cmnd *cmd)
13846{
13847 Scsi_Cmnd **pcmd = &np->waiting_list;
13848
13849 while (*pcmd) {
13850 if (cmd == *pcmd) {
13851 if (to_remove) {
13852 *pcmd = (Scsi_Cmnd *) cmd->next_wcmd;
13853 cmd->next_wcmd = 0;
13854 }
13855#ifdef DEBUG_WAITING_LIST
13856 printk("%s: cmd %lx retrieved from waiting list\n", ncr_name(np), (u_long) cmd);
13857#endif
13858 return cmd;
13859 }
13860 pcmd = (Scsi_Cmnd **) &(*pcmd)->next_wcmd;
13861 }
13862 return 0;
13863}
13864
13865static void process_waiting_list(ncb_p np, int sts)
13866{
13867 Scsi_Cmnd *waiting_list, *wcmd;
13868
13869 waiting_list = np->waiting_list;
13870 np->waiting_list = 0;
13871
13872#ifdef DEBUG_WAITING_LIST
13873 if (waiting_list) printk("%s: waiting_list=%lx processing sts=%d\n", ncr_name(np), (u_long) waiting_list, sts);
13874#endif
13875 while ((wcmd = waiting_list) != 0) {
13876 waiting_list = (Scsi_Cmnd *) wcmd->next_wcmd;
13877 wcmd->next_wcmd = 0;
13878 if (sts == DID_OK) {
13879#ifdef DEBUG_WAITING_LIST
13880 printk("%s: cmd %lx trying to requeue\n", ncr_name(np), (u_long) wcmd);
13881#endif
13882 sts = ncr_queue_command(np, wcmd);
13883 }
13884 if (sts != DID_OK) {
13885#ifdef DEBUG_WAITING_LIST
13886 printk("%s: cmd %lx done forced sts=%d\n", ncr_name(np), (u_long) wcmd, sts);
13887#endif
13888 SetScsiResult(wcmd, sts, 0);
13889 ncr_queue_done_cmd(np, wcmd);
13890 }
13891 }
13892}
13893
13894#undef next_wcmd
13895
13896#ifdef SCSI_NCR_PROC_INFO_SUPPORT
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908#ifdef SCSI_NCR_USER_COMMAND_SUPPORT
13909
13910#define is_digit(c) ((c) >= '0' && (c) <= '9')
13911#define digit_to_bin(c) ((c) - '0')
13912#define is_space(c) ((c) == ' ' || (c) == '\t')
13913
13914static int skip_spaces(char *ptr, int len)
13915{
13916 int cnt, c;
13917
13918 for (cnt = len; cnt > 0 && (c = *ptr++) && is_space(c); cnt--);
13919
13920 return (len - cnt);
13921}
13922
13923static int get_int_arg(char *ptr, int len, u_long *pv)
13924{
13925 int cnt, c;
13926 u_long v;
13927
13928 for (v = 0, cnt = len; cnt > 0 && (c = *ptr++) && is_digit(c); cnt--) {
13929 v = (v * 10) + digit_to_bin(c);
13930 }
13931
13932 if (pv)
13933 *pv = v;
13934
13935 return (len - cnt);
13936}
13937
13938static int is_keyword(char *ptr, int len, char *verb)
13939{
13940 int verb_len = strlen(verb);
13941
13942 if (len >= strlen(verb) && !memcmp(verb, ptr, verb_len))
13943 return verb_len;
13944 else
13945 return 0;
13946
13947}
13948
13949#define SKIP_SPACES(min_spaces) \
13950 if ((arg_len = skip_spaces(ptr, len)) < (min_spaces)) \
13951 return -EINVAL; \
13952 ptr += arg_len; len -= arg_len;
13953
13954#define GET_INT_ARG(v) \
13955 if (!(arg_len = get_int_arg(ptr, len, &(v)))) \
13956 return -EINVAL; \
13957 ptr += arg_len; len -= arg_len;
13958
13959
13960
13961
13962
13963
13964static int ncr_user_command(ncb_p np, char *buffer, int length)
13965{
13966 char *ptr = buffer;
13967 int len = length;
13968 struct usrcmd *uc = &np->user;
13969 int arg_len;
13970 u_long target;
13971
13972 bzero(uc, sizeof(*uc));
13973
13974 if (len > 0 && ptr[len-1] == '\n')
13975 --len;
13976
13977 if ((arg_len = is_keyword(ptr, len, "setsync")) != 0)
13978 uc->cmd = UC_SETSYNC;
13979 else if ((arg_len = is_keyword(ptr, len, "settags")) != 0)
13980 uc->cmd = UC_SETTAGS;
13981 else if ((arg_len = is_keyword(ptr, len, "setorder")) != 0)
13982 uc->cmd = UC_SETORDER;
13983 else if ((arg_len = is_keyword(ptr, len, "setverbose")) != 0)
13984 uc->cmd = UC_SETVERBOSE;
13985 else if ((arg_len = is_keyword(ptr, len, "setwide")) != 0)
13986 uc->cmd = UC_SETWIDE;
13987 else if ((arg_len = is_keyword(ptr, len, "setdebug")) != 0)
13988 uc->cmd = UC_SETDEBUG;
13989 else if ((arg_len = is_keyword(ptr, len, "setflag")) != 0)
13990 uc->cmd = UC_SETFLAG;
13991 else if ((arg_len = is_keyword(ptr, len, "resetdev")) != 0)
13992 uc->cmd = UC_RESETDEV;
13993 else if ((arg_len = is_keyword(ptr, len, "cleardev")) != 0)
13994 uc->cmd = UC_CLEARDEV;
13995 else
13996 arg_len = 0;
13997
13998#ifdef DEBUG_PROC_INFO
13999printk("ncr_user_command: arg_len=%d, cmd=%ld\n", arg_len, uc->cmd);
14000#endif
14001
14002 if (!arg_len)
14003 return -EINVAL;
14004 ptr += arg_len; len -= arg_len;
14005
14006 switch(uc->cmd) {
14007 case UC_SETSYNC:
14008 case UC_SETTAGS:
14009 case UC_SETWIDE:
14010 case UC_SETFLAG:
14011 case UC_RESETDEV:
14012 case UC_CLEARDEV:
14013 SKIP_SPACES(1);
14014 if ((arg_len = is_keyword(ptr, len, "all")) != 0) {
14015 ptr += arg_len; len -= arg_len;
14016 uc->target = ~0;
14017 } else {
14018 GET_INT_ARG(target);
14019 uc->target = (1<<target);
14020#ifdef DEBUG_PROC_INFO
14021printk("ncr_user_command: target=%ld\n", target);
14022#endif
14023 }
14024 break;
14025 }
14026
14027 switch(uc->cmd) {
14028 case UC_SETVERBOSE:
14029 case UC_SETSYNC:
14030 case UC_SETTAGS:
14031 case UC_SETWIDE:
14032 SKIP_SPACES(1);
14033 GET_INT_ARG(uc->data);
14034#ifdef DEBUG_PROC_INFO
14035printk("ncr_user_command: data=%ld\n", uc->data);
14036#endif
14037 break;
14038 case UC_SETORDER:
14039 SKIP_SPACES(1);
14040 if ((arg_len = is_keyword(ptr, len, "simple")))
14041 uc->data = M_SIMPLE_TAG;
14042 else if ((arg_len = is_keyword(ptr, len, "ordered")))
14043 uc->data = M_ORDERED_TAG;
14044 else if ((arg_len = is_keyword(ptr, len, "default")))
14045 uc->data = 0;
14046 else
14047 return -EINVAL;
14048 break;
14049 case UC_SETDEBUG:
14050 while (len > 0) {
14051 SKIP_SPACES(1);
14052 if ((arg_len = is_keyword(ptr, len, "alloc")))
14053 uc->data |= DEBUG_ALLOC;
14054 else if ((arg_len = is_keyword(ptr, len, "phase")))
14055 uc->data |= DEBUG_PHASE;
14056 else if ((arg_len = is_keyword(ptr, len, "queue")))
14057 uc->data |= DEBUG_QUEUE;
14058 else if ((arg_len = is_keyword(ptr, len, "result")))
14059 uc->data |= DEBUG_RESULT;
14060 else if ((arg_len = is_keyword(ptr, len, "pointer")))
14061 uc->data |= DEBUG_POINTER;
14062 else if ((arg_len = is_keyword(ptr, len, "script")))
14063 uc->data |= DEBUG_SCRIPT;
14064 else if ((arg_len = is_keyword(ptr, len, "tiny")))
14065 uc->data |= DEBUG_TINY;
14066 else if ((arg_len = is_keyword(ptr, len, "timing")))
14067 uc->data |= DEBUG_TIMING;
14068 else if ((arg_len = is_keyword(ptr, len, "nego")))
14069 uc->data |= DEBUG_NEGO;
14070 else if ((arg_len = is_keyword(ptr, len, "tags")))
14071 uc->data |= DEBUG_TAGS;
14072 else
14073 return -EINVAL;
14074 ptr += arg_len; len -= arg_len;
14075 }
14076#ifdef DEBUG_PROC_INFO
14077printk("ncr_user_command: data=%ld\n", uc->data);
14078#endif
14079 break;
14080 case UC_SETFLAG:
14081 while (len > 0) {
14082 SKIP_SPACES(1);
14083 if ((arg_len = is_keyword(ptr, len, "trace")))
14084 uc->data |= UF_TRACE;
14085 else if ((arg_len = is_keyword(ptr, len, "no_disc")))
14086 uc->data |= UF_NODISC;
14087 else
14088 return -EINVAL;
14089 ptr += arg_len; len -= arg_len;
14090 }
14091 break;
14092 default:
14093 break;
14094 }
14095
14096 if (len)
14097 return -EINVAL;
14098 else {
14099 unsigned long flags;
14100
14101 NCR_LOCK_NCB(np, flags);
14102 ncr_usercmd (np);
14103 NCR_UNLOCK_NCB(np, flags);
14104 }
14105 return length;
14106}
14107
14108#endif
14109
14110#ifdef SCSI_NCR_USER_INFO_SUPPORT
14111
14112struct info_str
14113{
14114 char *buffer;
14115 int length;
14116 int offset;
14117 int pos;
14118};
14119
14120static void copy_mem_info(struct info_str *info, char *data, int len)
14121{
14122 if (info->pos + len > info->length)
14123 len = info->length - info->pos;
14124
14125 if (info->pos + len < info->offset) {
14126 info->pos += len;
14127 return;
14128 }
14129 if (info->pos < info->offset) {
14130 data += (info->offset - info->pos);
14131 len -= (info->offset - info->pos);
14132 }
14133
14134 if (len > 0) {
14135 memcpy(info->buffer + info->pos, data, len);
14136 info->pos += len;
14137 }
14138}
14139
14140static int copy_info(struct info_str *info, char *fmt, ...)
14141{
14142 va_list args;
14143 char buf[81];
14144 int len;
14145
14146 va_start(args, fmt);
14147 len = vsprintf(buf, fmt, args);
14148 va_end(args);
14149
14150 copy_mem_info(info, buf, len);
14151 return len;
14152}
14153
14154
14155
14156
14157
14158static int ncr_host_info(ncb_p np, char *ptr, off_t offset, int len)
14159{
14160 struct info_str info;
14161
14162 info.buffer = ptr;
14163 info.length = len;
14164 info.offset = offset;
14165 info.pos = 0;
14166
14167 copy_info(&info, "General information:\n");
14168 copy_info(&info, " Chip " NAME53C "%s, device id 0x%x, "
14169 "revision id 0x%x\n",
14170 np->chip_name, np->device_id, np->revision_id);
14171 copy_info(&info, " On PCI bus %d, device %d, function %d, "
14172#ifdef __sparc__
14173 "IRQ %s\n",
14174#else
14175 "IRQ %d\n",
14176#endif
14177 np->bus, (np->device_fn & 0xf8) >> 3, np->device_fn & 7,
14178#ifdef __sparc__
14179 __irq_itoa(np->irq));
14180#else
14181 (int) np->irq);
14182#endif
14183 copy_info(&info, " Synchronous period factor %d, "
14184 "max commands per lun %d\n",
14185 (int) np->minsync, MAX_TAGS);
14186
14187 if (driver_setup.debug || driver_setup.verbose > 1) {
14188 copy_info(&info, " Debug flags 0x%x, verbosity level %d\n",
14189 driver_setup.debug, driver_setup.verbose);
14190 }
14191
14192 return info.pos > info.offset? info.pos - info.offset : 0;
14193}
14194
14195#endif
14196
14197
14198
14199
14200
14201
14202
14203static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset,
14204 int length, int hostno, int func)
14205{
14206 struct Scsi_Host *host;
14207 struct host_data *host_data;
14208 ncb_p ncb = 0;
14209 int retv;
14210
14211#ifdef DEBUG_PROC_INFO
14212printk("sym53c8xx_proc_info: hostno=%d, func=%d\n", hostno, func);
14213#endif
14214
14215 host = scsi_host_hn_get(hostno);
14216 if (!host)
14217 return -EINVAL;
14218
14219 host_data = (struct host_data *) host->hostdata;
14220 ncb = host_data->ncb;
14221 retv = -EINVAL;
14222 if (!ncb)
14223 goto out;
14224
14225 if (func) {
14226#ifdef SCSI_NCR_USER_COMMAND_SUPPORT
14227 retv = ncr_user_command(ncb, buffer, length);
14228#endif
14229 } else {
14230 if (start)
14231 *start = buffer;
14232#ifdef SCSI_NCR_USER_INFO_SUPPORT
14233 retv = ncr_host_info(ncb, buffer, offset, length);
14234#endif
14235 }
14236
14237out:
14238 scsi_host_put(host);
14239 return retv;
14240}
14241
14242
14243
14244
14245
14246
14247#endif
14248
14249
14250#ifdef SCSI_NCR_NVRAM_SUPPORT
14251
14252
14253
14254
14255
14256
14257
14258
14259
14260#define SET_BIT 0
14261#define CLR_BIT 1
14262#define SET_CLK 2
14263#define CLR_CLK 3
14264
14265
14266
14267
14268static void __init
14269S24C16_set_bit(ncr_slot *np, u_char write_bit, u_char *gpreg, int bit_mode)
14270{
14271 UDELAY (5);
14272 switch (bit_mode){
14273 case SET_BIT:
14274 *gpreg |= write_bit;
14275 break;
14276 case CLR_BIT:
14277 *gpreg &= 0xfe;
14278 break;
14279 case SET_CLK:
14280 *gpreg |= 0x02;
14281 break;
14282 case CLR_CLK:
14283 *gpreg &= 0xfd;
14284 break;
14285
14286 }
14287 OUTB (nc_gpreg, *gpreg);
14288 UDELAY (5);
14289}
14290
14291
14292
14293
14294static void __init S24C16_start(ncr_slot *np, u_char *gpreg)
14295{
14296 S24C16_set_bit(np, 1, gpreg, SET_BIT);
14297 S24C16_set_bit(np, 0, gpreg, SET_CLK);
14298 S24C16_set_bit(np, 0, gpreg, CLR_BIT);
14299 S24C16_set_bit(np, 0, gpreg, CLR_CLK);
14300}
14301
14302
14303
14304
14305static void __init S24C16_stop(ncr_slot *np, u_char *gpreg)
14306{
14307 S24C16_set_bit(np, 0, gpreg, SET_CLK);
14308 S24C16_set_bit(np, 1, gpreg, SET_BIT);
14309}
14310
14311
14312
14313
14314
14315static void __init
14316S24C16_do_bit(ncr_slot *np, u_char *read_bit, u_char write_bit, u_char *gpreg)
14317{
14318 S24C16_set_bit(np, write_bit, gpreg, SET_BIT);
14319 S24C16_set_bit(np, 0, gpreg, SET_CLK);
14320 if (read_bit)
14321 *read_bit = INB (nc_gpreg);
14322 S24C16_set_bit(np, 0, gpreg, CLR_CLK);
14323 S24C16_set_bit(np, 0, gpreg, CLR_BIT);
14324}
14325
14326
14327
14328
14329
14330static void __init
14331S24C16_write_ack(ncr_slot *np, u_char write_bit, u_char *gpreg, u_char *gpcntl)
14332{
14333 OUTB (nc_gpcntl, *gpcntl & 0xfe);
14334 S24C16_do_bit(np, 0, write_bit, gpreg);
14335 OUTB (nc_gpcntl, *gpcntl);
14336}
14337
14338
14339
14340
14341
14342static void __init
14343S24C16_read_ack(ncr_slot *np, u_char *read_bit, u_char *gpreg, u_char *gpcntl)
14344{
14345 OUTB (nc_gpcntl, *gpcntl | 0x01);
14346 S24C16_do_bit(np, read_bit, 1, gpreg);
14347 OUTB (nc_gpcntl, *gpcntl);
14348}
14349
14350
14351
14352
14353
14354static void __init
14355S24C16_write_byte(ncr_slot *np, u_char *ack_data, u_char write_data,
14356 u_char *gpreg, u_char *gpcntl)
14357{
14358 int x;
14359
14360 for (x = 0; x < 8; x++)
14361 S24C16_do_bit(np, 0, (write_data >> (7 - x)) & 0x01, gpreg);
14362
14363 S24C16_read_ack(np, ack_data, gpreg, gpcntl);
14364}
14365
14366
14367
14368
14369
14370static void __init
14371S24C16_read_byte(ncr_slot *np, u_char *read_data, u_char ack_data,
14372 u_char *gpreg, u_char *gpcntl)
14373{
14374 int x;
14375 u_char read_bit;
14376
14377 *read_data = 0;
14378 for (x = 0; x < 8; x++) {
14379 S24C16_do_bit(np, &read_bit, 1, gpreg);
14380 *read_data |= ((read_bit & 0x01) << (7 - x));
14381 }
14382
14383 S24C16_write_ack(np, ack_data, gpreg, gpcntl);
14384}
14385
14386
14387
14388
14389static int __init
14390sym_read_S24C16_nvram (ncr_slot *np, int offset, u_char *data, int len)
14391{
14392 u_char gpcntl, gpreg;
14393 u_char old_gpcntl, old_gpreg;
14394 u_char ack_data;
14395 int retv = 1;
14396 int x;
14397
14398
14399 old_gpreg = INB (nc_gpreg);
14400 old_gpcntl = INB (nc_gpcntl);
14401 gpcntl = old_gpcntl & 0x1c;
14402
14403
14404 OUTB (nc_gpreg, old_gpreg);
14405 OUTB (nc_gpcntl, gpcntl);
14406
14407
14408 gpreg = old_gpreg;
14409 S24C16_set_bit(np, 0, &gpreg, CLR_CLK);
14410 S24C16_set_bit(np, 0, &gpreg, CLR_BIT);
14411
14412
14413 S24C16_stop(np, &gpreg);
14414
14415
14416 S24C16_start(np, &gpreg);
14417
14418
14419 S24C16_write_byte(np, &ack_data,
14420 0xa0 | ((offset >> 7) & 0x0e), &gpreg, &gpcntl);
14421 if (ack_data & 0x01)
14422 goto out;
14423
14424
14425 S24C16_write_byte(np, &ack_data,
14426 offset & 0xff, &gpreg, &gpcntl);
14427 if (ack_data & 0x01)
14428 goto out;
14429
14430
14431 S24C16_start(np, &gpreg);
14432
14433
14434 S24C16_write_byte(np, &ack_data,
14435 0xa1 | ((offset >> 7) & 0x0e), &gpreg, &gpcntl);
14436 if (ack_data & 0x01)
14437 goto out;
14438
14439
14440 gpcntl |= 0x01;
14441 OUTB (nc_gpcntl, gpcntl);
14442
14443
14444 for (x = 0; x < len; x++)
14445 S24C16_read_byte(np, &data[x], (x == (len-1)), &gpreg, &gpcntl);
14446
14447
14448 gpcntl &= 0xfe;
14449 OUTB (nc_gpcntl, gpcntl);
14450 S24C16_stop(np, &gpreg);
14451 retv = 0;
14452out:
14453
14454 OUTB (nc_gpcntl, old_gpcntl);
14455 OUTB (nc_gpreg, old_gpreg);
14456
14457 return retv;
14458}
14459
14460#undef SET_BIT
14461#undef CLR_BIT
14462#undef SET_CLK
14463#undef CLR_CLK
14464
14465
14466
14467
14468
14469static int __init sym_read_Symbios_nvram (ncr_slot *np, Symbios_nvram *nvram)
14470{
14471 static u_char Symbios_trailer[6] = {0xfe, 0xfe, 0, 0, 0, 0};
14472 u_char *data = (u_char *) nvram;
14473 int len = sizeof(*nvram);
14474 u_short csum;
14475 int x;
14476
14477
14478 if (sym_read_S24C16_nvram (np, SYMBIOS_NVRAM_ADDRESS, data, len))
14479 return 1;
14480
14481
14482 if (nvram->type != 0 ||
14483 memcmp(nvram->trailer, Symbios_trailer, 6) ||
14484 nvram->byte_count != len - 12)
14485 return 1;
14486
14487
14488 for (x = 6, csum = 0; x < len - 6; x++)
14489 csum += data[x];
14490 if (csum != nvram->checksum)
14491 return 1;
14492
14493 return 0;
14494}
14495
14496
14497
14498
14499
14500
14501
14502
14503
14504
14505
14506
14507
14508
14509
14510static void __init T93C46_Clk(ncr_slot *np, u_char *gpreg)
14511{
14512 OUTB (nc_gpreg, *gpreg | 0x04);
14513 UDELAY (2);
14514 OUTB (nc_gpreg, *gpreg);
14515}
14516
14517
14518
14519
14520static void __init T93C46_Read_Bit(ncr_slot *np, u_char *read_bit, u_char *gpreg)
14521{
14522 UDELAY (2);
14523 T93C46_Clk(np, gpreg);
14524 *read_bit = INB (nc_gpreg);
14525}
14526
14527
14528
14529
14530static void __init T93C46_Write_Bit(ncr_slot *np, u_char write_bit, u_char *gpreg)
14531{
14532 if (write_bit & 0x01)
14533 *gpreg |= 0x02;
14534 else
14535 *gpreg &= 0xfd;
14536
14537 *gpreg |= 0x10;
14538
14539 OUTB (nc_gpreg, *gpreg);
14540 UDELAY (2);
14541
14542 T93C46_Clk(np, gpreg);
14543}
14544
14545
14546
14547
14548static void __init T93C46_Stop(ncr_slot *np, u_char *gpreg)
14549{
14550 *gpreg &= 0xef;
14551 OUTB (nc_gpreg, *gpreg);
14552 UDELAY (2);
14553
14554 T93C46_Clk(np, gpreg);
14555}
14556
14557
14558
14559
14560static void __init
14561T93C46_Send_Command(ncr_slot *np, u_short write_data,
14562 u_char *read_bit, u_char *gpreg)
14563{
14564 int x;
14565
14566
14567 for (x = 0; x < 9; x++)
14568 T93C46_Write_Bit(np, (u_char) (write_data >> (8 - x)), gpreg);
14569
14570 *read_bit = INB (nc_gpreg);
14571}
14572
14573
14574
14575
14576static void __init
14577T93C46_Read_Word(ncr_slot *np, u_short *nvram_data, u_char *gpreg)
14578{
14579 int x;
14580 u_char read_bit;
14581
14582 *nvram_data = 0;
14583 for (x = 0; x < 16; x++) {
14584 T93C46_Read_Bit(np, &read_bit, gpreg);
14585
14586 if (read_bit & 0x01)
14587 *nvram_data |= (0x01 << (15 - x));
14588 else
14589 *nvram_data &= ~(0x01 << (15 - x));
14590 }
14591}
14592
14593
14594
14595
14596static int __init
14597T93C46_Read_Data(ncr_slot *np, u_short *data,int len,u_char *gpreg)
14598{
14599 u_char read_bit;
14600 int x;
14601
14602 for (x = 0; x < len; x++) {
14603
14604
14605 T93C46_Send_Command(np, 0x180 | x, &read_bit, gpreg);
14606 if (read_bit & 0x01)
14607 return 1;
14608 T93C46_Read_Word(np, &data[x], gpreg);
14609 T93C46_Stop(np, gpreg);
14610 }
14611
14612 return 0;
14613}
14614
14615
14616
14617
14618static int __init
14619sym_read_T93C46_nvram (ncr_slot *np, Tekram_nvram *nvram)
14620{
14621 u_char gpcntl, gpreg;
14622 u_char old_gpcntl, old_gpreg;
14623 int retv = 1;
14624
14625
14626 old_gpreg = INB (nc_gpreg);
14627 old_gpcntl = INB (nc_gpcntl);
14628
14629
14630
14631 gpreg = old_gpreg & 0xe9;
14632 OUTB (nc_gpreg, gpreg);
14633 gpcntl = (old_gpcntl & 0xe9) | 0x09;
14634 OUTB (nc_gpcntl, gpcntl);
14635
14636
14637 retv = T93C46_Read_Data(np, (u_short *) nvram,
14638 sizeof(*nvram) / sizeof(short), &gpreg);
14639
14640
14641 OUTB (nc_gpcntl, old_gpcntl);
14642 OUTB (nc_gpreg, old_gpreg);
14643
14644 return retv;
14645}
14646
14647
14648
14649
14650
14651static int __init
14652sym_read_Tekram_nvram (ncr_slot *np, u_short device_id, Tekram_nvram *nvram)
14653{
14654 u_char *data = (u_char *) nvram;
14655 int len = sizeof(*nvram);
14656 u_short csum;
14657 int x;
14658
14659 switch (device_id) {
14660 case PCI_DEVICE_ID_NCR_53C885:
14661 case PCI_DEVICE_ID_NCR_53C895:
14662 case PCI_DEVICE_ID_NCR_53C896:
14663 x = sym_read_S24C16_nvram(np, TEKRAM_24C16_NVRAM_ADDRESS,
14664 data, len);
14665 break;
14666 case PCI_DEVICE_ID_NCR_53C875:
14667 x = sym_read_S24C16_nvram(np, TEKRAM_24C16_NVRAM_ADDRESS,
14668 data, len);
14669 if (!x)
14670 break;
14671 default:
14672 x = sym_read_T93C46_nvram(np, nvram);
14673 break;
14674 }
14675 if (x)
14676 return 1;
14677
14678
14679 for (x = 0, csum = 0; x < len - 1; x += 2)
14680 csum += data[x] + (data[x+1] << 8);
14681 if (csum != 0x1234)
14682 return 1;
14683
14684 return 0;
14685}
14686
14687#endif
14688
14689
14690
14691
14692
14693MODULE_LICENSE("GPL");
14694
14695#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
14696static
14697#endif
14698#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0) || defined(MODULE)
14699Scsi_Host_Template driver_template = SYM53C8XX;
14700#include "scsi_module.c"
14701#endif
14702