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