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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170#define DC390_IRQ SA_SHIRQ
171
172
173
174
175
176
177
178
179
180
181#ifdef DC390_DEBUG0
182# define DEBUG0(x) x;
183#else
184# define DEBUG0(x)
185#endif
186#ifdef DC390_DEBUG1
187# define DEBUG1(x) x;
188#else
189# define DEBUG1(x)
190#endif
191#ifdef DC390_DCBDEBUG
192# define DCBDEBUG(x) x;
193#else
194# define DCBDEBUG(x)
195#endif
196#ifdef DC390_PARSEDEBUG
197# define PARSEDEBUG(x) x;
198#else
199# define PARSEDEBUG(x)
200#endif
201#ifdef DC390_REMOVABLEDEBUG
202# define REMOVABLEDEBUG(x) x;
203#else
204# define REMOVABLEDEBUG(x)
205#endif
206#define DCBDEBUG1(x)
207
208
209#include <linux/module.h>
210#include <asm/dma.h>
211#include <asm/io.h>
212#include <asm/system.h>
213#include <linux/delay.h>
214#include <linux/signal.h>
215#include <linux/sched.h>
216#include <linux/errno.h>
217#include <linux/kernel.h>
218#include <linux/ioport.h>
219#include <linux/pci.h>
220#include <linux/proc_fs.h>
221#include <linux/string.h>
222#include <linux/ctype.h>
223#include <linux/mm.h>
224#include <linux/config.h>
225#include <linux/version.h>
226#include <linux/blk.h>
227#include <linux/timer.h>
228
229#include "scsi.h"
230#include "hosts.h"
231#include "constants.h"
232#include "sd.h"
233#include <linux/stat.h>
234#include <scsi/scsicam.h>
235
236#include "dc390.h"
237
238#define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
260# include <linux/init.h>
261#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
262# include <linux/spinlock.h>
263#else
264# include <asm/spinlock.h>
265#endif
266#endif
267
268
269#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
270# define USE_SPINLOCKS 1
271# define NEW_PCI 1
272#else
273# undef NEW_PCI
274# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
275# define USE_SPINLOCKS 2
276# endif
277#endif
278
279#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,99)
280static struct pci_device_id tmscsim_pci_tbl[] __initdata = {
281 {
282 vendor: PCI_VENDOR_ID_AMD,
283 device: PCI_DEVICE_ID_AMD53C974,
284 subvendor: PCI_ANY_ID,
285 subdevice: PCI_ANY_ID,
286 },
287 { }
288};
289MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
290#endif
291
292#ifdef USE_SPINLOCKS
293
294# if USE_SPINLOCKS == 3
295
296# if defined (CONFIG_SMP) || DEBUG_SPINLOCKS > 0
297# define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
298# else
299# define DC390_LOCKA_INIT
300# endif
301 spinlock_t dc390_drvlock = SPIN_LOCK_UNLOCKED;
302
303# define DC390_AFLAGS unsigned long aflags;
304# define DC390_IFLAGS unsigned long iflags;
305# define DC390_DFLAGS unsigned long dflags;
306
307# define DC390_LOCK_IO spin_lock_irqsave (&io_request_lock, iflags)
308# define DC390_UNLOCK_IO spin_unlock_irqrestore (&io_request_lock, iflags)
309
310# define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
311# define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
312# define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
313# define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
314
315# define DC390_LOCK_ACB spin_lock_irqsave (&(pACB->lock), aflags)
316# define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags)
317# define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock))
318# define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock))
319
320
321# else
322
323# if USE_SPINLOCKS == 2
324
325# if defined (CONFIG_SMP) || DEBUG_SPINLOCKS > 0
326# define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
327# else
328# define DC390_LOCKA_INIT
329# endif
330 spinlock_t dc390_drvlock = SPIN_LOCK_UNLOCKED;
331# define DC390_AFLAGS unsigned long aflags;
332# define DC390_IFLAGS
333# define DC390_DFLAGS unsigned long dflags;
334# define DC390_LOCK_IO
335# define DC390_UNLOCK_IO
336# define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
337# define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
338# define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
339# define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
340# define DC390_LOCK_ACB spin_lock_irqsave (&(pACB->lock), aflags)
341# define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags)
342# define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock))
343# define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock))
344
345
346# else
347
348# define DC390_AFLAGS
349# define DC390_IFLAGS unsigned long iflags;
350# define DC390_DFLAGS unsigned long dflags;
351 spinlock_t dc390_drvlock = SPIN_LOCK_UNLOCKED;
352# define DC390_LOCK_IO spin_lock_irqsave (&io_request_lock, iflags)
353# define DC390_UNLOCK_IO spin_unlock_irqrestore (&io_request_lock, iflags)
354# define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
355# define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
356# define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
357# define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
358# define DC390_LOCK_ACB
359# define DC390_UNLOCK_ACB
360# define DC390_LOCK_ACB_NI
361# define DC390_UNLOCK_ACB_NI
362# define DC390_LOCKA_INIT
363
364# endif
365# endif
366
367#else
368
369# define DC390_AFLAGS unsigned long aflags;
370# define DC390_IFLAGS unsigned long iflags;
371# define DC390_DFLAGS unsigned long dflags;
372# define DC390_LOCK_IO save_flags (iflags); cli ()
373# define DC390_UNLOCK_IO restore_flags (iflags)
374# define DC390_LOCK_DRV save_flags (dflags); cli ()
375# define DC390_UNLOCK_DRV restore_flags (dflags)
376# define DC390_LOCK_DRV_NI
377# define DC390_UNLOCK_DRV_NI
378# define DC390_LOCK_ACB save_flags (aflags); cli ()
379# define DC390_UNLOCK_ACB restore_flags (aflags)
380# define DC390_LOCK_ACB_NI
381# define DC390_UNLOCK_ACB_NI
382# define DC390_LOCKA_INIT
383#endif
384
385
386
387
388#ifdef NEW_PCI
389# define PDEV pdev
390# define PDEVDECL struct pci_dev *pdev
391# define PDEVDECL0 struct pci_dev *pdev = NULL
392# define PDEVDECL1 struct pci_dev *pdev
393# define PDEVSET pACB->pdev=pdev
394# define PDEVSET1 pdev=pACB->pdev
395# define PCI_WRITE_CONFIG_BYTE(pd, rv, bv) pci_write_config_byte (pd, rv, bv)
396# define PCI_READ_CONFIG_BYTE(pd, rv, bv) pci_read_config_byte (pd, rv, bv)
397# define PCI_WRITE_CONFIG_WORD(pd, rv, bv) pci_write_config_word (pd, rv, bv)
398# define PCI_READ_CONFIG_WORD(pd, rv, bv) pci_read_config_word (pd, rv, bv)
399# define PCI_BUS_DEV pdev->bus->number, pdev->devfn
400# define PCI_PRESENT pci_present ()
401# define PCI_SET_MASTER pci_set_master (pdev)
402# define PCI_FIND_DEVICE(vend, id) (pdev = pci_find_device (vend, id, pdev))
403#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,10)
404# define PCI_GET_IO_AND_IRQ io_port = pci_resource_start (pdev, 0); irq = pdev->irq
405#else
406# define PCI_GET_IO_AND_IRQ io_port = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; irq = pdev->irq
407#endif
408#else
409# include <linux/bios32.h>
410# define PDEV pbus, pdevfn
411# define PDEVDECL UCHAR pbus, UCHAR pdevfn
412# define PDEVDECL0 UCHAR pbus = 0; UCHAR pdevfn = 0; USHORT pci_index = 0; int error
413# define PDEVDECL1 UCHAR pbus; UCHAR pdevfn
414# define PDEVSET pACB->pbus=pbus; pACB->pdevfn=pdevfn
415# define PDEVSET1 pbus=pACB->pbus; pdevfn=pACB->pdevfn
416# define PCI_WRITE_CONFIG_BYTE(pd, rv, bv) pcibios_write_config_byte (pd, rv, bv)
417# define PCI_READ_CONFIG_BYTE(pd, rv, bv) pcibios_read_config_byte (pd, rv, bv)
418# define PCI_WRITE_CONFIG_WORD(pd, rv, bv) pcibios_write_config_word (pd, rv, bv)
419# define PCI_READ_CONFIG_WORD(pd, rv, bv) pcibios_read_config_word (pd, rv, bv)
420# define PCI_BUS_DEV pbus, pdevfn
421# define PCI_PRESENT pcibios_present ()
422# define PCI_SET_MASTER dc390_set_master (pbus, pdevfn)
423# define PCI_FIND_DEVICE(vend, id) (!pcibios_find_device (vend, id, pci_index++, &pbus, &pdevfn))
424# define PCI_GET_IO_AND_IRQ error = pcibios_read_config_dword (pbus, pdevfn, PCI_BASE_ADDRESS_0, &io_port); \
425 error |= pcibios_read_config_byte (pbus, pdevfn, PCI_INTERRUPT_LINE, &irq); \
426 io_port &= 0xfffe; \
427 if (error) { printk (KERN_ERR "DC390_detect: Error reading PCI config registers!\n"); continue; }
428#endif
429
430#include "tmscsim.h"
431
432#ifndef __init
433# define __init
434#endif
435
436UCHAR dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB );
437void dc390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
438void dc390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
439static void dc390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
440static void dc390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
441static void dc390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
442void dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
443static void dc390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
444static void dc390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
445void dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
446static void dc390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
447void dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
448static void dc390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
449static void dc390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
450static void dc390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus);
451
452static void dc390_SetXferRate( PACB pACB, PDCB pDCB );
453void dc390_Disconnect( PACB pACB );
454void dc390_Reselect( PACB pACB );
455void dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB );
456void dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd );
457static void dc390_ScsiRstDetect( PACB pACB );
458static void dc390_ResetSCSIBus( PACB pACB );
459static void __inline__ dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB );
460static void __inline__ dc390_InvalidCmd( PACB pACB );
461static void __inline__ dc390_EnableMsgOut_Abort (PACB, PSRB);
462static void dc390_remove_dev (PACB pACB, PDCB pDCB);
463void do_DC390_Interrupt( int, void *, struct pt_regs *);
464
465int dc390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, UCHAR index );
466void dc390_initDCB( PACB pACB, PDCB *ppDCB, UCHAR id, UCHAR lun);
467void dc390_updateDCB (PACB pACB, PDCB pDCB);
468
469#ifdef MODULE
470 static int DC390_release(struct Scsi_Host *host);
471 static int dc390_shutdown (struct Scsi_Host *host);
472#endif
473
474
475
476
477
478static PACB dc390_pACB_start= NULL;
479static PACB dc390_pACB_current = NULL;
480static ULONG dc390_lastabortedpid = 0;
481static UINT dc390_laststatus = 0;
482static UCHAR dc390_adapterCnt = 0;
483
484
485int tmscsim[] = {-2, -2, -2, -2, -2, -2};
486
487# if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
488MODULE_PARM(tmscsim, "1-6i");
489MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");
490# endif
491
492#if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
493MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
494MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
495MODULE_LICENSE("GPL");
496
497MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
498#endif
499
500static PVOID dc390_phase0[]={
501 dc390_DataOut_0,
502 dc390_DataIn_0,
503 dc390_Command_0,
504 dc390_Status_0,
505 dc390_Nop_0,
506 dc390_Nop_0,
507 dc390_MsgOut_0,
508 dc390_MsgIn_0,
509 dc390_Nop_1
510 };
511
512static PVOID dc390_phase1[]={
513 dc390_DataOutPhase,
514 dc390_DataInPhase,
515 dc390_CommandPhase,
516 dc390_StatusPhase,
517 dc390_Nop_0,
518 dc390_Nop_0,
519 dc390_MsgOutPhase,
520 dc390_MsgInPhase,
521 dc390_Nop_1
522 };
523
524#ifdef DC390_DEBUG1
525static char* dc390_p0_str[] = {
526 "dc390_DataOut_0",
527 "dc390_DataIn_0",
528 "dc390_Command_0",
529 "dc390_Status_0",
530 "dc390_Nop_0",
531 "dc390_Nop_0",
532 "dc390_MsgOut_0",
533 "dc390_MsgIn_0",
534 "dc390_Nop_1"
535 };
536
537static char* dc390_p1_str[] = {
538 "dc390_DataOutPhase",
539 "dc390_DataInPhase",
540 "dc390_CommandPhase",
541 "dc390_StatusPhase",
542 "dc390_Nop_0",
543 "dc390_Nop_0",
544 "dc390_MsgOutPhase",
545 "dc390_MsgInPhase",
546 "dc390_Nop_1"
547 };
548#endif
549
550
551UCHAR dc390_baddevname1[2][28] ={
552 "SEAGATE ST3390N 9546",
553 "HP C3323-300 4269"};
554#define BADDEVCNT 2
555
556static char* dc390_adapname = "DC390";
557UCHAR dc390_eepromBuf[MAX_ADAPTER_NUM][EE_LEN];
558UCHAR dc390_clock_period1[] = {4, 5, 6, 7, 8, 10, 13, 20};
559UCHAR dc390_clock_speed[] = {100,80,67,57,50, 40, 31, 20};
560
561#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,30)
562struct proc_dir_entry DC390_proc_scsi_tmscsim ={
563 PROC_SCSI_DC390T, 7 ,"tmscsim",
564 S_IFDIR | S_IRUGO | S_IXUGO, 2
565 };
566#endif
567
568
569
570
571
572
573
574
575static void __init dc390_EnDisableCE( UCHAR mode, PDEVDECL, PUCHAR regval )
576{
577 UCHAR bval;
578
579 bval = 0;
580 if(mode == ENABLE_CE)
581 *regval = 0xc0;
582 else
583 *regval = 0x80;
584 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
585 if(mode == DISABLE_CE)
586 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
587 udelay(160);
588}
589
590
591
592static void __init dc390_EEprom_Override (UCHAR index)
593{
594 PUCHAR ptr;
595 UCHAR id;
596 ptr = (PUCHAR) dc390_eepromBuf[index];
597
598
599 if (tmscsim[0] != -2)
600 ptr[EE_ADAPT_SCSI_ID] = (UCHAR)tmscsim[0];
601 if (tmscsim[3] != -2)
602 ptr[EE_MODE2] = (UCHAR)tmscsim[3];
603 if (tmscsim[5] != -2)
604 ptr[EE_DELAY] = tmscsim[5];
605 if (tmscsim[4] != -2)
606 ptr[EE_TAG_CMD_NUM] = (UCHAR)tmscsim[4];
607
608
609 for (id = 0; id < MAX_SCSI_ID; id++)
610 {
611 if (tmscsim[2] != -2)
612 ptr[id<<2] = (UCHAR)tmscsim[2];
613 if (tmscsim[1] != -2)
614 ptr[(id<<2) + 1] = (UCHAR)tmscsim[1];
615 };
616}
617
618
619static void __init dc390_check_for_safe_settings (void)
620{
621 if (tmscsim[0] == -1 || tmscsim[0] > 15)
622 {
623 tmscsim[0] = 7; tmscsim[1] = 4;
624 tmscsim[2] = 0x09; tmscsim[3] = 0x0f;
625 tmscsim[4] = 2; tmscsim[5] = 10;
626 printk (KERN_INFO "DC390: Using safe settings.\n");
627 }
628}
629
630
631#ifndef CONFIG_SCSI_DC390T_NOGENSUPP
632int __initdata tmscsim_def[] = {7, 0 ,
633 PARITY_CHK_ | SEND_START_ | EN_DISCONNECT_
634 | SYNC_NEGO_ | TAG_QUEUEING_,
635 MORE2_DRV | GREATER_1G | RST_SCSI_BUS | ACTIVE_NEGATION
636
637# ifdef CONFIG_SCSI_MULTI_LUN
638 | LUN_CHECK
639# endif
640 , 3 , 1 };
641
642
643static void __init dc390_fill_with_defaults (void)
644{
645 int i;
646 PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x %08x\n", tmscsim[0],\
647 tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4], tmscsim[5]);)
648 for (i = 0; i < 6; i++)
649 {
650 if (tmscsim[i] < 0 || tmscsim[i] > 255)
651 tmscsim[i] = tmscsim_def[i];
652 }
653
654 if (tmscsim[0] > 7) tmscsim[0] = 7;
655 if (tmscsim[1] > 7) tmscsim[1] = 4;
656 if (tmscsim[4] > 5) tmscsim[4] = 4;
657 if (tmscsim[5] > 180) tmscsim[5] = 180;
658};
659#endif
660
661
662
663
664#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13)
665int __init dc390_setup (char *str)
666{
667 int ints[8];
668 int i, im;
669 (void)get_options (str, ARRAY_SIZE(ints), ints);
670 im = ints[0];
671 if (im > 6)
672 {
673 printk (KERN_NOTICE "DC390: ignore extra params!\n");
674 im = 6;
675 };
676 for (i = 0; i < im; i++)
677 tmscsim[i] = ints[i+1];
678
679 return 1;
680};
681#ifndef MODULE
682__setup("tmscsim=", dc390_setup);
683#endif
684
685#else
686void __init dc390_setup (char *str, int *ints)
687{
688 int i, im;
689 im = ints[0];
690 if (im > 6)
691 {
692 printk (KERN_NOTICE "DC390: ignore extra params!\n");
693 im = 6;
694 };
695 for (i = 0; i < im; i++)
696 tmscsim[i] = ints[i+1];
697
698};
699#endif
700
701
702
703static void __init dc390_EEpromOutDI( PDEVDECL, PUCHAR regval, UCHAR Carry )
704{
705 UCHAR bval;
706
707 bval = 0;
708 if(Carry)
709 {
710 bval = 0x40;
711 *regval = 0x80;
712 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
713 }
714 udelay(160);
715 bval |= 0x80;
716 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
717 udelay(160);
718 bval = 0;
719 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
720 udelay(160);
721}
722
723
724static UCHAR __init dc390_EEpromInDO( PDEVDECL )
725{
726 UCHAR bval;
727
728 PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x80);
729 udelay(160);
730 PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x40);
731 udelay(160);
732 PCI_READ_CONFIG_BYTE(PDEV, 0x00, &bval);
733 if(bval == 0x22)
734 return(1);
735 else
736 return(0);
737}
738
739
740static USHORT __init dc390_EEpromGetData1( PDEVDECL )
741{
742 UCHAR i;
743 UCHAR carryFlag;
744 USHORT wval;
745
746 wval = 0;
747 for(i=0; i<16; i++)
748 {
749 wval <<= 1;
750 carryFlag = dc390_EEpromInDO(PDEV);
751 wval |= carryFlag;
752 }
753 return(wval);
754}
755
756
757static void __init dc390_Prepare( PDEVDECL, PUCHAR regval, UCHAR EEpromCmd )
758{
759 UCHAR i,j;
760 UCHAR carryFlag;
761
762 carryFlag = 1;
763 j = 0x80;
764 for(i=0; i<9; i++)
765 {
766 dc390_EEpromOutDI(PDEV,regval,carryFlag);
767 carryFlag = (EEpromCmd & j) ? 1 : 0;
768 j >>= 1;
769 }
770}
771
772
773static void __init dc390_ReadEEprom( PDEVDECL, PUSHORT ptr)
774{
775 UCHAR regval,cmd;
776 UCHAR i;
777
778 cmd = EEPROM_READ;
779 for(i=0; i<0x40; i++)
780 {
781 dc390_EnDisableCE(ENABLE_CE, PDEV, ®val);
782 dc390_Prepare(PDEV, ®val, cmd++);
783 *ptr++ = dc390_EEpromGetData1(PDEV);
784 dc390_EnDisableCE(DISABLE_CE, PDEV, ®val);
785 }
786}
787
788
789static void __init dc390_interpret_delay (UCHAR index)
790{
791 char interpd [] = {1,3,5,10,16,30,60,120};
792 dc390_eepromBuf[index][EE_DELAY] = interpd [dc390_eepromBuf[index][EE_DELAY]];
793};
794
795static UCHAR __init dc390_CheckEEpromCheckSum( PDEVDECL, UCHAR index )
796{
797 UCHAR i;
798 char EEbuf[128];
799 USHORT wval, *ptr = (PUSHORT)EEbuf;
800
801 dc390_ReadEEprom( PDEV, ptr );
802 memcpy (dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID);
803 memcpy (&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID],
804 &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID);
805 dc390_interpret_delay (index);
806
807 wval = 0;
808 for(i=0; i<0x40; i++, ptr++)
809 wval += *ptr;
810 return (wval == 0x1234 ? 0 : 1);
811}
812
813
814
815
816
817
818
819static PDCB __inline__ dc390_findDCB ( PACB pACB, UCHAR id, UCHAR lun)
820{
821 PDCB pDCB = pACB->pLinkDCB; if (!pDCB) return 0;
822 while (pDCB->TargetID != id || pDCB->TargetLUN != lun)
823 {
824 pDCB = pDCB->pNextDCB;
825 if (pDCB == pACB->pLinkDCB)
826 {
827 DCBDEBUG(printk (KERN_WARNING "DC390: DCB not found (DCB=%p, DCBmap[%2x]=%2x)\n",
828 pDCB, id, pACB->DCBmap[id]);)
829 return 0;
830 }
831 };
832 DCBDEBUG1( printk (KERN_DEBUG "DCB %p (%02x,%02x) found.\n", \
833 pDCB, pDCB->TargetID, pDCB->TargetLUN);)
834 return pDCB;
835};
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852#if 0
853
854static PSRB dc390_find_cmd_in_SRBq (PSCSICMD cmd, PSRB queue)
855{
856 PSRB q = queue;
857 while (q)
858 {
859 if (q->pcmd == cmd) return q;
860 q = q->pNextSRB;
861 if (q == queue) return 0;
862 }
863 return q;
864};
865#endif
866
867
868
869static void dc390_Query_append( PSCSICMD cmd, PACB pACB )
870{
871 DEBUG0(printk ("DC390: Append cmd %li to Query\n", cmd->pid);)
872 if( !pACB->QueryCnt )
873 pACB->pQueryHead = cmd;
874 else
875 pACB->pQueryTail->next = cmd;
876
877 pACB->pQueryTail = cmd;
878 pACB->QueryCnt++;
879 pACB->CmdOutOfSRB++;
880 cmd->next = NULL;
881}
882
883
884
885static PSCSICMD dc390_Query_get ( PACB pACB )
886{
887 PSCSICMD pcmd;
888
889 pcmd = pACB->pQueryHead;
890 if (!pcmd) return pcmd;
891 DEBUG0(printk ("DC390: Get cmd %li from Query\n", pcmd->pid);)
892 pACB->pQueryHead = pcmd->next;
893 pcmd->next = NULL;
894 if (!pACB->pQueryHead) pACB->pQueryTail = NULL;
895 pACB->QueryCnt--;
896 return( pcmd );
897}
898
899
900
901static __inline__ PSRB dc390_Free_get ( PACB pACB )
902{
903 PSRB pSRB;
904
905 pSRB = pACB->pFreeSRB;
906 DEBUG0(printk ("DC390: Get Free SRB %p\n", pSRB);)
907 if( pSRB )
908 {
909 pACB->pFreeSRB = pSRB->pNextSRB;
910 pSRB->pNextSRB = NULL;
911 }
912
913 return( pSRB );
914}
915
916
917static __inline__ void dc390_Free_insert (PACB pACB, PSRB pSRB)
918{
919 DEBUG0(printk ("DC390: Free SRB %p\n", pSRB);)
920 pSRB->pNextSRB = pACB->pFreeSRB;
921 pACB->pFreeSRB = pSRB;
922}
923
924
925
926static __inline__ void dc390_Waiting_insert ( PDCB pDCB, PSRB pSRB )
927{
928 DEBUG0(printk ("DC390: Insert pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid);)
929 pSRB->pNextSRB = pDCB->pWaitingSRB;
930 if (!pDCB->pWaitingSRB)
931 pDCB->pWaitLast = pSRB;
932 pDCB->pWaitingSRB = pSRB;
933 pDCB->WaitSRBCnt++;
934}
935
936
937
938static __inline__ void dc390_Waiting_append ( PDCB pDCB, PSRB pSRB)
939{
940 DEBUG0(printk ("DC390: Append pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid);)
941 if( pDCB->pWaitingSRB )
942 pDCB->pWaitLast->pNextSRB = pSRB;
943 else
944 pDCB->pWaitingSRB = pSRB;
945
946 pDCB->pWaitLast = pSRB;
947 pSRB->pNextSRB = NULL;
948 pDCB->WaitSRBCnt++;
949 pDCB->pDCBACB->CmdInQ++;
950}
951
952static __inline__ void dc390_Going_append (PDCB pDCB, PSRB pSRB)
953{
954 pDCB->GoingSRBCnt++;
955 DEBUG0(printk("DC390: Append SRB %p to Going\n", pSRB);)
956
957 if( pDCB->pGoingSRB )
958 pDCB->pGoingLast->pNextSRB = pSRB;
959 else
960 pDCB->pGoingSRB = pSRB;
961
962 pDCB->pGoingLast = pSRB;
963
964 pSRB->pNextSRB = NULL;
965};
966
967static __inline__ void dc390_Going_remove (PDCB pDCB, PSRB pSRB)
968{
969 DEBUG0(printk("DC390: Remove SRB %p from Going\n", pSRB);)
970 if (pSRB == pDCB->pGoingSRB)
971 pDCB->pGoingSRB = pSRB->pNextSRB;
972 else
973 {
974 PSRB psrb = pDCB->pGoingSRB;
975 while (psrb && psrb->pNextSRB != pSRB)
976 psrb = psrb->pNextSRB;
977 if (!psrb)
978 { printk (KERN_ERR "DC390: Remove non-ex. SRB %p from Going!\n", pSRB); return; }
979 psrb->pNextSRB = pSRB->pNextSRB;
980 if (pSRB == pDCB->pGoingLast)
981 pDCB->pGoingLast = psrb;
982 }
983 pDCB->GoingSRBCnt--;
984};
985
986
987static void dc390_Going_to_Waiting ( PDCB pDCB, PSRB pSRB )
988{
989 DEBUG0(printk(KERN_INFO "DC390: Going_to_Waiting (SRB %p) pid = %li\n", pSRB, pSRB->pcmd->pid);)
990
991 dc390_Going_remove (pDCB, pSRB);
992
993 dc390_Waiting_insert (pDCB, pSRB);
994
995}
996
997
998static __inline__ void dc390_Waiting_to_Going ( PDCB pDCB, PSRB pSRB )
999{
1000
1001 DEBUG0(printk("DC390: Remove SRB %p from head of Waiting\n", pSRB);)
1002 pDCB->pWaitingSRB = pSRB->pNextSRB;
1003 if( !pDCB->pWaitingSRB ) pDCB->pWaitLast = NULL;
1004 pDCB->WaitSRBCnt--;
1005 dc390_Going_append (pDCB, pSRB);
1006}
1007
1008
1009#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,30)
1010 static inline int timer_pending(struct timer_list * timer)
1011 {
1012 return timer->prev != NULL;
1013 }
1014 #define time_after(a,b) ((long)(b) - (long)(a) < 0)
1015 #define time_before(a,b) time_after(b,a)
1016#endif
1017
1018void DC390_waiting_timed_out (unsigned long ptr);
1019
1020static void dc390_waiting_timer (PACB pACB, unsigned long to)
1021{
1022 if (timer_pending (&pACB->Waiting_Timer)) return;
1023 init_timer (&pACB->Waiting_Timer);
1024 pACB->Waiting_Timer.function = DC390_waiting_timed_out;
1025 pACB->Waiting_Timer.data = (unsigned long)pACB;
1026 if (time_before (jiffies + to, pACB->pScsiHost->last_reset))
1027 pACB->Waiting_Timer.expires = pACB->pScsiHost->last_reset + 1;
1028 else
1029 pACB->Waiting_Timer.expires = jiffies + to + 1;
1030 add_timer (&pACB->Waiting_Timer);
1031}
1032
1033
1034
1035static void dc390_Waiting_process ( PACB pACB )
1036{
1037 PDCB ptr, ptr1;
1038 PSRB pSRB;
1039
1040 if( (pACB->pActiveDCB) || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) )
1041 return;
1042 if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);
1043 ptr = pACB->pDCBRunRobin;
1044 if( !ptr )
1045 {
1046 ptr = pACB->pLinkDCB;
1047 pACB->pDCBRunRobin = ptr;
1048 }
1049 ptr1 = ptr;
1050 if (!ptr1) return;
1051 do
1052 {
1053 pACB->pDCBRunRobin = ptr1->pNextDCB;
1054 if( !( pSRB = ptr1->pWaitingSRB ) ||
1055 ( ptr1->MaxCommand <= ptr1->GoingSRBCnt ))
1056 ptr1 = ptr1->pNextDCB;
1057 else
1058 {
1059
1060 if( !dc390_StartSCSI(pACB, ptr1, pSRB) )
1061 dc390_Waiting_to_Going (ptr1, pSRB);
1062 else
1063 dc390_waiting_timer (pACB, HZ/5);
1064 break;
1065 }
1066 } while (ptr1 != ptr);
1067 return;
1068}
1069
1070
1071void DC390_waiting_timed_out (unsigned long ptr)
1072{
1073 PACB pACB = (PACB)ptr;
1074 DC390_IFLAGS
1075 DC390_AFLAGS
1076 DEBUG0(printk ("DC390: Debug: Waiting queue woken up by timer!\n");)
1077 DC390_LOCK_IO;
1078 DC390_LOCK_ACB;
1079 dc390_Waiting_process (pACB);
1080 DC390_UNLOCK_ACB;
1081 DC390_UNLOCK_IO;
1082}
1083
1084
1085
1086
1087
1088
1089
1090
1091static void dc390_SendSRB( PACB pACB, PSRB pSRB )
1092{
1093 PDCB pDCB;
1094
1095 pDCB = pSRB->pSRBDCB;
1096 if( (pDCB->MaxCommand <= pDCB->GoingSRBCnt) || (pACB->pActiveDCB) ||
1097 (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) )
1098 {
1099 dc390_Waiting_append (pDCB, pSRB);
1100 dc390_Waiting_process (pACB);
1101 return;
1102 }
1103
1104#if 0
1105 if( pDCB->pWaitingSRB )
1106 {
1107 dc390_Waiting_append (pDCB, pSRB);
1108
1109 pSRB = pDCB->pWaitingSRB;
1110
1111 pDCB->pWaitingSRB = pSRB->pNextSRB;
1112 pSRB->pNextSRB = NULL;
1113 if (!pDCB->pWaitingSRB) pDCB->pWaitLast = NULL;
1114 }
1115#endif
1116
1117 if (!dc390_StartSCSI(pACB, pDCB, pSRB))
1118 dc390_Going_append (pDCB, pSRB);
1119 else {
1120 dc390_Waiting_insert (pDCB, pSRB);
1121 dc390_waiting_timer (pACB, HZ/5);
1122 };
1123}
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133static void dc390_BuildSRB (Scsi_Cmnd* pcmd, PDCB pDCB, PSRB pSRB)
1134{
1135 pSRB->pSRBDCB = pDCB;
1136 pSRB->pcmd = pcmd;
1137
1138
1139
1140 if( pcmd->use_sg )
1141 {
1142 pSRB->SGcount = (UCHAR) pcmd->use_sg;
1143 pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
1144 }
1145 else if( pcmd->request_buffer )
1146 {
1147 pSRB->SGcount = 1;
1148 pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
1149 pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
1150 pSRB->Segmentx.length = pcmd->request_bufflen;
1151 }
1152 else
1153 pSRB->SGcount = 0;
1154
1155 pSRB->SGIndex = 0;
1156 pSRB->AdaptStatus = 0;
1157 pSRB->TargetStatus = 0;
1158 pSRB->MsgCnt = 0;
1159 if( pDCB->DevType != TYPE_TAPE )
1160 pSRB->RetryCnt = 1;
1161 else
1162 pSRB->RetryCnt = 0;
1163 pSRB->SRBStatus = 0;
1164 pSRB->SRBFlag = 0;
1165 pSRB->SRBState = 0;
1166 pSRB->TotalXferredLen = 0;
1167 pSRB->SGBusAddr = 0;
1168 pSRB->SGToBeXferLen = 0;
1169 pSRB->ScsiPhase = 0;
1170 pSRB->EndMessage = 0;
1171 pSRB->TagNumber = 255;
1172};
1173
1174
1175static void dc390_Query_to_Waiting (PACB pACB)
1176{
1177 Scsi_Cmnd *pcmd;
1178 PSRB pSRB;
1179 PDCB pDCB;
1180
1181 if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) )
1182 return;
1183
1184 while (pACB->QueryCnt)
1185 {
1186 pSRB = dc390_Free_get ( pACB );
1187 if (!pSRB) return;
1188 pcmd = dc390_Query_get ( pACB );
1189 if (!pcmd) { dc390_Free_insert (pACB, pSRB); return; };
1190 pDCB = dc390_findDCB (pACB, pcmd->target, pcmd->lun);
1191 if (!pDCB)
1192 {
1193 dc390_Free_insert (pACB, pSRB);
1194 printk (KERN_ERR "DC390: Command in queue to non-existing device!\n");
1195 pcmd->result = MK_RES(DRIVER_ERROR,DID_ERROR,0,0);
1196 DC390_UNLOCK_ACB_NI;
1197 pcmd->done (pcmd);
1198 DC390_LOCK_ACB_NI;
1199 };
1200 dc390_BuildSRB (pcmd, pDCB, pSRB);
1201 dc390_Waiting_append ( pDCB, pSRB );
1202 }
1203}
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
1225{
1226 PDCB pDCB;
1227 PSRB pSRB;
1228 DC390_AFLAGS
1229 PACB pACB = (PACB) cmd->host->hostdata;
1230
1231
1232 DEBUG0( \
1233 printk(KERN_INFO "DC390: Queue Cmd=%02x,Tgt=%d,LUN=%d (pid=%li)\n",\
1234 cmd->cmnd[0],cmd->target,cmd->lun,cmd->pid);)
1235
1236 DC390_LOCK_ACB;
1237
1238
1239 cmd->result = DID_BAD_TARGET << 16;
1240
1241
1242
1243
1244
1245 if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )
1246 pACB->scan_devices = 0;
1247
1248 else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) )
1249 pACB->scan_devices = 0;
1250
1251 if ( ( cmd->target >= pACB->pScsiHost->max_id ) ||
1252 (cmd->lun >= pACB->pScsiHost->max_lun) )
1253 {
1254
1255
1256 DC390_UNLOCK_ACB;
1257
1258 done (cmd);
1259 return (0);
1260 }
1261
1262 if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) &&
1263 !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
1264 {
1265 pACB->scan_devices = 1;
1266
1267 dc390_initDCB( pACB, &pDCB, cmd->target, cmd->lun );
1268 if (!pDCB)
1269 {
1270 printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n",
1271 cmd->target, cmd->lun);
1272 DC390_UNLOCK_ACB;
1273 printk ("DC390: No DCB in queue_command!\n");
1274#ifdef USE_NEW_EH
1275 return (1);
1276#else
1277 done (cmd);
1278 return (0);
1279#endif
1280 };
1281
1282 }
1283 else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
1284 {
1285 printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n",
1286 cmd->target, cmd->lun);
1287 DC390_UNLOCK_ACB;
1288
1289 done (cmd);
1290 return (0);
1291 }
1292 else
1293 {
1294 pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun);
1295 if (!pDCB)
1296 {
1297 printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n",
1298 cmd->target, cmd->lun);
1299 DC390_UNLOCK_ACB;
1300 printk ("DC390: No DCB in queuecommand (2)!\n");
1301#ifdef USE_NEW_EH
1302 return (1);
1303#else
1304 done (cmd);
1305 return (0);
1306#endif
1307 };
1308 }
1309
1310 pACB->Cmds++;
1311 cmd->scsi_done = done;
1312 cmd->result = 0;
1313
1314 dc390_Query_to_Waiting (pACB);
1315
1316 if( pACB->QueryCnt )
1317 {
1318 DEBUG0(printk ("DC390: QueryCnt != 0\n");)
1319 dc390_Query_append ( cmd, pACB );
1320 dc390_Waiting_process (pACB);
1321 }
1322 else if (pDCB->pWaitingSRB)
1323 {
1324 pSRB = dc390_Free_get ( pACB );
1325 DEBUG0(if (!pSRB) printk ("DC390: No free SRB but Waiting\n"); else printk ("DC390: Free SRB w/ Waiting\n");)
1326 if (!pSRB) dc390_Query_append (cmd, pACB);
1327 else
1328 {
1329 dc390_BuildSRB (cmd, pDCB, pSRB);
1330 dc390_Waiting_append (pDCB, pSRB);
1331 }
1332 dc390_Waiting_process (pACB);
1333 }
1334 else
1335 {
1336 pSRB = dc390_Free_get ( pACB );
1337 DEBUG0(if (!pSRB) printk ("DC390: No free SRB w/o Waiting\n"); else printk ("DC390: Free SRB w/o Waiting\n");)
1338 if (!pSRB)
1339 {
1340 dc390_Query_append (cmd, pACB);
1341 dc390_Waiting_process (pACB);
1342 }
1343 else
1344 {
1345 dc390_BuildSRB (cmd, pDCB, pSRB);
1346 dc390_SendSRB (pACB, pSRB);
1347 };
1348 };
1349
1350 DC390_UNLOCK_ACB;
1351 DEBUG1(printk (KERN_DEBUG " ... command (pid %li) queued successfully.\n", cmd->pid);)
1352 return(0);
1353}
1354
1355
1356
1357
1358#ifdef CONFIG_SCSI_DC390T_TRADMAP
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371#include <asm/unaligned.h>
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384static int partsize(struct buffer_head *bh, unsigned long capacity,
1385 unsigned int *cyls, unsigned int *hds, unsigned int *secs) {
1386 struct partition *p, *largest = NULL;
1387 int i, largest_cyl;
1388 int cyl, ext_cyl, end_head, end_cyl, end_sector;
1389 unsigned int logical_end, physical_end, ext_physical_end;
1390
1391
1392 if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
1393 for (largest_cyl = -1, p = (struct partition *)
1394 (0x1BE + bh->b_data), i = 0; i < 4; ++i, ++p) {
1395 if (!p->sys_ind)
1396 continue;
1397 cyl = p->cyl + ((p->sector & 0xc0) << 2);
1398 if (cyl > largest_cyl) {
1399 largest_cyl = cyl;
1400 largest = p;
1401 }
1402 }
1403 }
1404
1405 if (largest) {
1406 end_cyl = largest->end_cyl + ((largest->end_sector & 0xc0) << 2);
1407 end_head = largest->end_head;
1408 end_sector = largest->end_sector & 0x3f;
1409
1410 physical_end = end_cyl * (end_head + 1) * end_sector +
1411 end_head * end_sector + end_sector;
1412
1413
1414 logical_end = get_unaligned(&largest->start_sect)
1415 + get_unaligned(&largest->nr_sects);
1416
1417
1418 ext_cyl= (logical_end-(end_head * end_sector + end_sector))
1419 /(end_head + 1) / end_sector;
1420 ext_physical_end = ext_cyl * (end_head + 1) * end_sector +
1421 end_head * end_sector + end_sector;
1422
1423 if ((logical_end == physical_end) ||
1424 (end_cyl==1023 && ext_physical_end==logical_end)) {
1425 *secs = end_sector;
1426 *hds = end_head + 1;
1427 *cyls = capacity / ((end_head + 1) * end_sector);
1428 return 0;
1429 }
1430 }
1431 return -1;
1432}
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445int DC390_bios_param (Disk *disk, kdev_t devno, int geom[])
1446{
1447 int heads, sectors, cylinders;
1448 PACB pACB = (PACB) disk->device->host->hostdata;
1449 struct buffer_head *bh;
1450 int ret_code = -1;
1451 int size = disk->capacity;
1452
1453 if ((bh = bread(MKDEV(MAJOR(devno), MINOR(devno)&~0xf), 0, block_size(devno))))
1454 {
1455
1456 ret_code = partsize (bh, (unsigned long) size, (unsigned int *) geom + 2,
1457 (unsigned int *) geom + 0, (unsigned int *) geom + 1);
1458 brelse (bh);
1459 }
1460 if (ret_code == -1)
1461 {
1462 heads = 64;
1463 sectors = 32;
1464 cylinders = size / (heads * sectors);
1465
1466 if ( (pACB->Gmode2 & GREATER_1G) && (cylinders > 1024) )
1467 {
1468 heads = 255;
1469 sectors = 63;
1470 cylinders = size / (heads * sectors);
1471 }
1472
1473 geom[0] = heads;
1474 geom[1] = sectors;
1475 geom[2] = cylinders;
1476 }
1477
1478 return (0);
1479}
1480#else
1481int DC390_bios_param (Disk *disk, kdev_t devno, int geom[])
1482{
1483 return scsicam_bios_param (disk, devno, geom);
1484};
1485#endif
1486
1487
1488void dc390_dumpinfo (PACB pACB, PDCB pDCB, PSRB pSRB)
1489{
1490 USHORT pstat; PDEVDECL1;
1491 if (!pDCB) pDCB = pACB->pActiveDCB;
1492 if (!pSRB && pDCB) pSRB = pDCB->pActiveSRB;
1493
1494 if (pSRB)
1495 {
1496 printk ("DC390: SRB: Xferred %08lx, Remain %08lx, State %08x, Phase %02x\n",
1497 pSRB->TotalXferredLen, pSRB->SGToBeXferLen, pSRB->SRBState,
1498 pSRB->ScsiPhase);
1499 printk ("DC390: AdpaterStatus: %02x, SRB Status %02x\n", pSRB->AdaptStatus, pSRB->SRBStatus);
1500 };
1501 printk ("DC390: Status of last IRQ (DMA/SC/Int/IRQ): %08x\n", dc390_laststatus);
1502 printk ("DC390: Register dump: SCSI block:\n");
1503 printk ("DC390: XferCnt Cmd Stat IntS IRQS FFIS Ctl1 Ctl2 Ctl3 Ctl4\n");
1504 printk ("DC390: %06x %02x %02x %02x",
1505 DC390_read8(CtcReg_Low) + (DC390_read8(CtcReg_Mid) << 8) + (DC390_read8(CtcReg_High) << 16),
1506 DC390_read8(ScsiCmd), DC390_read8(Scsi_Status), DC390_read8(Intern_State));
1507 printk (" %02x %02x %02x %02x %02x %02x\n",
1508 DC390_read8(INT_Status), DC390_read8(Current_Fifo), DC390_read8(CtrlReg1),
1509 DC390_read8(CtrlReg2), DC390_read8(CtrlReg3), DC390_read8(CtrlReg4));
1510 DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
1511 if (DC390_read8(Current_Fifo) & 0x1f)
1512 {
1513 printk ("DC390: FIFO:");
1514 while (DC390_read8(Current_Fifo) & 0x1f) printk (" %02x", DC390_read8(ScsiFifo));
1515 printk ("\n");
1516 };
1517 printk ("DC390: Register dump: DMA engine:\n");
1518 printk ("DC390: Cmd STrCnt SBusA WrkBC WrkAC Stat SBusCtrl\n");
1519 printk ("DC390: %02x %08x %08x %08x %08x %02x %08x\n",
1520 DC390_read8(DMA_Cmd), DC390_read32(DMA_XferCnt), DC390_read32(DMA_XferAddr),
1521 DC390_read32(DMA_Wk_ByteCntr), DC390_read32(DMA_Wk_AddrCntr),
1522 DC390_read8(DMA_Status), DC390_read32(DMA_ScsiBusCtrl));
1523 DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
1524 PDEVSET1; PCI_READ_CONFIG_WORD(PDEV, PCI_STATUS, &pstat);
1525 printk ("DC390: Register dump: PCI Status: %04x\n", pstat);
1526 printk ("DC390: In case of driver trouble read linux/drivers/scsi/README.tmscsim\n");
1527};
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542int DC390_abort (Scsi_Cmnd *cmd)
1543{
1544 PDCB pDCB;
1545 PSRB pSRB, psrb;
1546 UINT count, i;
1547 PSCSICMD pcmd;
1548 int status;
1549
1550 DC390_AFLAGS
1551 PACB pACB = (PACB) cmd->host->hostdata;
1552
1553 DC390_LOCK_ACB;
1554
1555 printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n",
1556 cmd->pid, cmd->target, cmd->lun);
1557
1558
1559 if( pACB->QueryCnt )
1560 {
1561 pcmd = pACB->pQueryHead;
1562 if( pcmd == cmd )
1563 {
1564
1565 pACB->pQueryHead = pcmd->next;
1566 pcmd->next = NULL;
1567 if (cmd == pACB->pQueryTail) pACB->pQueryTail = NULL;
1568 pACB->QueryCnt--;
1569 status = SCSI_ABORT_SUCCESS;
1570 goto ABO_X;
1571 }
1572 for( count = pACB->QueryCnt, i=0; i<count-1; i++)
1573 {
1574 if( pcmd->next == cmd )
1575 {
1576 pcmd->next = cmd->next;
1577 cmd->next = NULL;
1578 if (cmd == pACB->pQueryTail) pACB->pQueryTail = NULL;
1579 pACB->QueryCnt--;
1580 status = SCSI_ABORT_SUCCESS;
1581 goto ABO_X;
1582 }
1583 else
1584 {
1585 pcmd = pcmd->next;
1586 }
1587 }
1588 }
1589
1590 pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun);
1591 if( !pDCB ) goto NOT_RUN;
1592
1593
1594
1595
1596
1597
1598
1599
1600 pSRB = pDCB->pWaitingSRB;
1601 if( !pSRB )
1602 goto ON_GOING;
1603
1604
1605 if( pSRB->pcmd == cmd )
1606 {
1607 pDCB->pWaitingSRB = pSRB->pNextSRB;
1608 goto IN_WAIT;
1609 }
1610 else
1611 {
1612 psrb = pSRB;
1613 if( !(psrb->pNextSRB) )
1614 goto ON_GOING;
1615 while( psrb->pNextSRB->pcmd != cmd )
1616 {
1617 psrb = psrb->pNextSRB;
1618 if( !(psrb->pNextSRB) || psrb == pSRB)
1619 goto ON_GOING;
1620 }
1621 pSRB = psrb->pNextSRB;
1622 psrb->pNextSRB = pSRB->pNextSRB;
1623 if( pSRB == pDCB->pWaitLast )
1624 pDCB->pWaitLast = psrb;
1625IN_WAIT:
1626 dc390_Free_insert (pACB, pSRB);
1627 pDCB->WaitSRBCnt--;
1628 cmd->next = NULL;
1629 status = SCSI_ABORT_SUCCESS;
1630 goto ABO_X;
1631 }
1632
1633
1634ON_GOING:
1635
1636
1637
1638 dc390_dumpinfo (pACB, pDCB, pSRB);
1639 pSRB = pDCB->pGoingSRB;
1640 pDCB->DCBFlag |= ABORT_DEV_;
1641
1642 for( count = pDCB->GoingSRBCnt, i=0; i<count; i++)
1643 {
1644 if( pSRB->pcmd != cmd )
1645 pSRB = pSRB->pNextSRB;
1646 else
1647 {
1648 if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) )
1649 {
1650 status = SCSI_ABORT_BUSY;
1651 printk ("DC390: Abort current command (pid %li, SRB %p)\n",
1652 cmd->pid, pSRB);
1653 goto ABO_X;
1654 }
1655 else
1656 {
1657 status = SCSI_ABORT_SNOOZE;
1658 goto ABO_X;
1659 }
1660 }
1661 }
1662
1663NOT_RUN:
1664 status = SCSI_ABORT_NOT_RUNNING;
1665
1666ABO_X:
1667 cmd->result = DID_ABORT << 16;
1668 printk(KERN_INFO "DC390: Aborted pid %li with status %i\n", cmd->pid, status);
1669#if 0
1670 if (cmd->pid == dc390_lastabortedpid)
1671 {
1672
1673 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1674 DC390_write8 (ScsiCmd, DMA_COMMAND);
1675
1676
1677 DC390_write8 (ScsiCmd, NOP_CMD);
1678
1679
1680
1681 };
1682 sbac = DC390_read32 (DMA_ScsiBusCtrl);
1683 if (sbac & SCSI_BUSY)
1684 {
1685 printk (KERN_WARNING "DC390: Reset SCSI device: ");
1686
1687
1688
1689
1690
1691
1692
1693
1694 DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
1695 udelay (250);
1696 DC390_write8 (ScsiCmd, NOP_CMD);
1697 sbac = DC390_read32 (DMA_ScsiBusCtrl);
1698 printk ("%08lx\n", sbac);
1699 };
1700#endif
1701 dc390_lastabortedpid = cmd->pid;
1702 DC390_UNLOCK_ACB;
1703
1704#ifndef USE_NEW_EH
1705 if (status == SCSI_ABORT_SUCCESS) cmd->scsi_done(cmd);
1706#endif
1707 return( status );
1708}
1709
1710
1711static void dc390_ResetDevParam( PACB pACB )
1712{
1713 PDCB pDCB, pdcb;
1714
1715 pDCB = pACB->pLinkDCB;
1716 if (! pDCB) return;
1717 pdcb = pDCB;
1718 do
1719 {
1720 pDCB->SyncMode &= ~SYNC_NEGO_DONE;
1721 pDCB->SyncPeriod = 0;
1722 pDCB->SyncOffset = 0;
1723 pDCB->TagMask = 0;
1724 pDCB->CtrlR3 = FAST_CLK;
1725 pDCB->CtrlR4 &= NEGATE_REQACKDATA | CTRL4_RESERVED | NEGATE_REQACK;
1726 pDCB->CtrlR4 |= pACB->glitch_cfg;
1727 pDCB = pDCB->pNextDCB;
1728 }
1729 while( pdcb != pDCB );
1730 pACB->ACBFlag &= ~(RESET_DEV | RESET_DONE | RESET_DETECT);
1731
1732}
1733
1734#if 0
1735
1736static void dc390_RecoverSRB( PACB pACB )
1737{
1738 PDCB pDCB, pdcb;
1739 PSRB psrb, psrb2;
1740 UINT cnt, i;
1741
1742 pDCB = pACB->pLinkDCB;
1743 if( !pDCB ) return;
1744 pdcb = pDCB;
1745 do
1746 {
1747 cnt = pdcb->GoingSRBCnt;
1748 psrb = pdcb->pGoingSRB;
1749 for (i=0; i<cnt; i++)
1750 {
1751 psrb2 = psrb;
1752 psrb = psrb->pNextSRB;
1753
1754 if( pdcb->pWaitingSRB )
1755 {
1756 psrb2->pNextSRB = pdcb->pWaitingSRB;
1757 pdcb->pWaitingSRB = psrb2;
1758 }
1759 else
1760 {
1761 pdcb->pWaitingSRB = psrb2;
1762 pdcb->pWaitLast = psrb2;
1763 psrb2->pNextSRB = NULL;
1764 }
1765 }
1766 pdcb->GoingSRBCnt = 0;
1767 pdcb->pGoingSRB = NULL;
1768 pdcb->TagMask = 0;
1769 pdcb = pdcb->pNextDCB;
1770 } while( pdcb != pDCB );
1771}
1772#endif
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785int DC390_reset (Scsi_Cmnd *cmd, unsigned int resetFlags)
1786{
1787 UCHAR bval;
1788 DC390_AFLAGS
1789 PACB pACB = (PACB) cmd->host->hostdata;
1790
1791 printk(KERN_INFO "DC390: RESET ... ");
1792
1793 DC390_LOCK_ACB;
1794 if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);
1795 bval = DC390_read8 (CtrlReg1);
1796 bval |= DIS_INT_ON_SCSI_RST;
1797 DC390_write8 (CtrlReg1, bval);
1798
1799 pACB->ACBFlag |= RESET_DEV;
1800 dc390_ResetSCSIBus( pACB );
1801
1802 dc390_ResetDevParam( pACB );
1803 udelay (1000);
1804 pACB->pScsiHost->last_reset = jiffies + 3*HZ/2
1805 + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
1806
1807 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1808 DC390_read8 (INT_Status);
1809
1810 dc390_DoingSRB_Done( pACB, cmd );
1811
1812 pACB->pActiveDCB = NULL;
1813
1814 pACB->ACBFlag = 0;
1815 bval = DC390_read8 (CtrlReg1);
1816 bval &= ~DIS_INT_ON_SCSI_RST;
1817 DC390_write8 (CtrlReg1, bval);
1818
1819 dc390_Waiting_process( pACB );
1820
1821 printk("done\n");
1822 DC390_UNLOCK_ACB;
1823 return( SCSI_RESET_SUCCESS );
1824}
1825
1826#include "scsiiom.c"
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837void dc390_initDCB( PACB pACB, PDCB *ppDCB, UCHAR id, UCHAR lun )
1838{
1839 PEEprom prom;
1840 UCHAR index;
1841 PDCB pDCB, pDCB2;
1842
1843 pDCB = kmalloc (sizeof(DC390_DCB), GFP_ATOMIC);
1844 DCBDEBUG(printk (KERN_INFO "DC390: alloc mem for DCB (ID %i, LUN %i): %p\n" \
1845 id, lun, pDCB);)
1846
1847 *ppDCB = pDCB; pDCB2 = 0;
1848 if (!pDCB) return;
1849 if( pACB->DCBCnt == 0 )
1850 {
1851 pACB->pLinkDCB = pDCB;
1852 pACB->pDCBRunRobin = pDCB;
1853 }
1854 else
1855 {
1856 pACB->pLastDCB->pNextDCB = pDCB;
1857 };
1858
1859 pACB->DCBCnt++;
1860
1861 pDCB->pNextDCB = pACB->pLinkDCB;
1862 pACB->pLastDCB = pDCB;
1863
1864 pDCB->pDCBACB = pACB;
1865 pDCB->TargetID = id;
1866 pDCB->TargetLUN = lun;
1867 pDCB->pWaitingSRB = NULL;
1868 pDCB->pGoingSRB = NULL;
1869 pDCB->GoingSRBCnt = 0;
1870 pDCB->WaitSRBCnt = 0;
1871 pDCB->pActiveSRB = NULL;
1872 pDCB->TagMask = 0;
1873 pDCB->MaxCommand = 1;
1874 index = pACB->AdapterIndex;
1875 pDCB->DCBFlag = 0;
1876
1877
1878 if (lun != 0)
1879 pDCB2 = dc390_findDCB (pACB, id, 0);
1880 prom = (PEEprom) &dc390_eepromBuf[index][id << 2];
1881
1882
1883 if (pDCB2)
1884 {
1885 pDCB->DevMode = pDCB2->DevMode;
1886 pDCB->SyncMode = pDCB2->SyncMode;
1887 pDCB->SyncPeriod = pDCB2->SyncPeriod;
1888 pDCB->SyncOffset = pDCB2->SyncOffset;
1889 pDCB->NegoPeriod = pDCB2->NegoPeriod;
1890
1891 pDCB->CtrlR3 = pDCB2->CtrlR3;
1892 pDCB->CtrlR4 = pDCB2->CtrlR4;
1893 pDCB->Inquiry7 = pDCB2->Inquiry7;
1894 }
1895 else
1896 {
1897 pDCB->DevMode = prom->EE_MODE1;
1898 pDCB->SyncMode = 0;
1899 pDCB->SyncPeriod = 0;
1900 pDCB->SyncOffset = 0;
1901 pDCB->NegoPeriod = (dc390_clock_period1[prom->EE_SPEED] * 25) >> 2;
1902
1903 pDCB->CtrlR3 = FAST_CLK;
1904
1905 pDCB->CtrlR4 = pACB->glitch_cfg | CTRL4_RESERVED;
1906 if( dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION)
1907 pDCB->CtrlR4 |= NEGATE_REQACKDATA | NEGATE_REQACK;
1908 pDCB->Inquiry7 = 0;
1909 }
1910
1911 pACB->DCBmap[id] |= (1 << lun);
1912 dc390_updateDCB(pACB, pDCB);
1913}
1914
1915
1916
1917
1918
1919
1920
1921void dc390_updateDCB (PACB pACB, PDCB pDCB)
1922{
1923 pDCB->SyncMode &= EN_TAG_QUEUEING | SYNC_NEGO_DONE ;
1924 if (pDCB->DevMode & TAG_QUEUEING_) {
1925
1926 } else {
1927 pDCB->SyncMode &= ~EN_TAG_QUEUEING;
1928 pDCB->MaxCommand = 1;
1929 };
1930
1931 if( pDCB->DevMode & SYNC_NEGO_ )
1932 pDCB->SyncMode |= SYNC_ENABLE;
1933 else {
1934 pDCB->SyncMode &= ~(SYNC_NEGO_DONE | SYNC_ENABLE);
1935 pDCB->SyncOffset &= ~0x0f;
1936 };
1937
1938
1939
1940 pDCB->CtrlR1 = pACB->pScsiHost->this_id;
1941 if( pDCB->DevMode & PARITY_CHK_ )
1942 pDCB->CtrlR1 |= PARITY_ERR_REPO;
1943};
1944
1945
1946
1947
1948
1949
1950
1951
1952static void dc390_updateDCBs (PACB pACB)
1953{
1954 int i;
1955 PDCB pDCB = pACB->pLinkDCB;
1956 for (i = 0; i < pACB->DCBCnt; i++)
1957 {
1958 dc390_updateDCB (pACB, pDCB);
1959 pDCB = pDCB->pNextDCB;
1960 };
1961};
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972static void __inline__ dc390_initSRB( PSRB psrb )
1973{
1974
1975}
1976
1977
1978void dc390_linkSRB( PACB pACB )
1979{
1980 UINT count, i;
1981
1982 count = pACB->SRBCount;
1983 for( i=0; i<count; i++)
1984 {
1985 if( i != count-1 )
1986 pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
1987 else
1988 pACB->SRB_array[i].pNextSRB = NULL;
1989 dc390_initSRB( &pACB->SRB_array[i] );
1990 }
1991}
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
2004{
2005 PACB pACB;
2006 UCHAR i;
2007 DC390_AFLAGS
2008
2009 psh->can_queue = MAX_CMD_QUEUE;
2010 psh->cmd_per_lun = MAX_CMD_PER_LUN;
2011 psh->this_id = (int) dc390_eepromBuf[index][EE_ADAPT_SCSI_ID];
2012 psh->io_port = io_port;
2013 psh->n_io_port = 0x80;
2014 psh->irq = Irq;
2015#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,50)
2016 psh->base = io_port;
2017#else
2018 psh->base = (char*)io_port;
2019#endif
2020 psh->unique_id = io_port;
2021 psh->dma_channel = -1;
2022 psh->last_reset = jiffies;
2023
2024 pACB = (PACB) psh->hostdata;
2025 DC390_LOCKA_INIT;
2026 DC390_LOCK_ACB;
2027
2028 pACB->pScsiHost = psh;
2029 pACB->IOPortBase = (USHORT) io_port;
2030 pACB->IRQLevel = Irq;
2031
2032 DEBUG0(printk (KERN_INFO "DC390: Adapter index %i, ID %i, IO 0x%08x, IRQ 0x%02x\n", \
2033 index, psh->this_id, (int)io_port, Irq);)
2034
2035 psh->max_id = 8;
2036
2037 if( psh->max_id - 1 == dc390_eepromBuf[index][EE_ADAPT_SCSI_ID] )
2038 psh->max_id--;
2039 psh->max_lun = 1;
2040 if( dc390_eepromBuf[index][EE_MODE2] & LUN_CHECK )
2041 psh->max_lun = 8;
2042
2043 pACB->pLinkDCB = NULL;
2044 pACB->pDCBRunRobin = NULL;
2045 pACB->pActiveDCB = NULL;
2046 pACB->pFreeSRB = pACB->SRB_array;
2047 pACB->SRBCount = MAX_SRB_CNT;
2048 pACB->QueryCnt = 0;
2049 pACB->pQueryHead = NULL;
2050 pACB->AdapterIndex = index;
2051 pACB->status = 0;
2052 psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID];
2053 pACB->DeviceCnt = 0;
2054 pACB->DCBCnt = 0;
2055 pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM];
2056 pACB->ACBFlag = 0;
2057 pACB->scan_devices = 1;
2058 pACB->MsgLen = 0;
2059 pACB->Ignore_IRQ = 0;
2060 pACB->Gmode2 = dc390_eepromBuf[index][EE_MODE2];
2061 dc390_linkSRB( pACB );
2062 pACB->pTmpSRB = &pACB->TmpSRB;
2063 dc390_initSRB( pACB->pTmpSRB );
2064 for(i=0; i<MAX_SCSI_ID; i++)
2065 pACB->DCBmap[i] = 0;
2066 pACB->sel_timeout = SEL_TIMEOUT;
2067 pACB->glitch_cfg = EATER_25NS;
2068 pACB->Cmds = pACB->CmdInQ = pACB->CmdOutOfSRB = 0;
2069 pACB->SelLost = pACB->SelConn = 0;
2070 init_timer (&pACB->Waiting_Timer);
2071}
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
2086{
2087 PACB pACB, pACB2;
2088 UCHAR dstate;
2089 int i;
2090
2091 pACB = (PACB) psh->hostdata;
2092
2093 if (check_region (io_port, psh->n_io_port))
2094 {
2095 printk(KERN_ERR "DC390: register IO ports error!\n");
2096 return( -1 );
2097 }
2098 else
2099 request_region (io_port, psh->n_io_port, "tmscsim");
2100
2101 DC390_read8_ (INT_Status, io_port);
2102
2103 if( (i = request_irq(Irq, do_DC390_Interrupt, DC390_IRQ, "tmscsim", pACB) ))
2104 {
2105 printk(KERN_ERR "DC390: register IRQ error!\n");
2106 release_region (io_port, psh->n_io_port);
2107 return( -1 );
2108 }
2109
2110 if( !dc390_pACB_start )
2111 {
2112 pACB2 = NULL;
2113 dc390_pACB_start = pACB;
2114 dc390_pACB_current = pACB;
2115 pACB->pNextACB = NULL;
2116 }
2117 else
2118 {
2119 pACB2 = dc390_pACB_current;
2120 dc390_pACB_current->pNextACB = pACB;
2121 dc390_pACB_current = pACB;
2122 pACB->pNextACB = NULL;
2123 };
2124
2125 DC390_write8 (CtrlReg1, DIS_INT_ON_SCSI_RST | psh->this_id);
2126
2127 if (pACB->Gmode2 & RST_SCSI_BUS)
2128 {
2129 dc390_ResetSCSIBus( pACB );
2130 udelay (1000);
2131 pACB->pScsiHost->last_reset = jiffies + HZ/2
2132 + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
2133
2134
2135
2136
2137 };
2138 pACB->ACBFlag = 0;
2139 DC390_read8 (INT_Status);
2140
2141 DC390_write8 (Scsi_TimeOut, SEL_TIMEOUT);
2142 DC390_write8 (Clk_Factor, CLK_FREQ_40MHZ);
2143 DC390_write8 (ScsiCmd, NOP_CMD);
2144 DC390_write8 (CtrlReg2, EN_FEATURE+EN_SCSI2_CMD);
2145 DC390_write8 (CtrlReg3, FAST_CLK);
2146 DC390_write8 (CtrlReg4, pACB->glitch_cfg |
2147 (dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION) ? NEGATE_REQACKDATA : 0);
2148 DC390_write8 (CtcReg_High, 0);
2149 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
2150 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
2151 DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
2152 dstate = DC390_read8 (DMA_Status);
2153 DC390_write8 (DMA_Status, dstate);
2154
2155 return(0);
2156}
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, PDEVDECL, UCHAR index)
2177{
2178 PSH psh;
2179 PACB pACB;
2180 DC390_AFLAGS
2181
2182 if (dc390_CheckEEpromCheckSum (PDEV, index))
2183 {
2184#ifdef CONFIG_SCSI_DC390T_NOGENSUPP
2185 printk (KERN_ERR "DC390_init: No EEPROM found!\n");
2186 return( -1 );
2187#else
2188 int speed;
2189 dc390_adapname = "AM53C974";
2190 printk (KERN_INFO "DC390_init: No EEPROM found! Trying default settings ...\n");
2191 dc390_check_for_safe_settings ();
2192 dc390_fill_with_defaults ();
2193 dc390_EEprom_Override (index);
2194 speed = dc390_clock_speed[tmscsim[1]];
2195 printk (KERN_INFO "DC390: Used defaults: AdaptID=%i, SpeedIdx=%i (%i.%i MHz),"
2196 " DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i), DelayReset=%is\n",
2197 tmscsim[0], tmscsim[1], speed/10, speed%10,
2198 (UCHAR)tmscsim[2], (UCHAR)tmscsim[3], tmscsim[4], 2 << (tmscsim[4]), tmscsim[5]);
2199#endif
2200 }
2201 else
2202 {
2203 dc390_check_for_safe_settings ();
2204 dc390_EEprom_Override (index);
2205 }
2206
2207 psh = scsi_register( psht, sizeof(DC390_ACB) );
2208 if( !psh ) return( -1 );
2209
2210 scsi_set_pci_device(psh, pdev);
2211 pACB = (PACB) psh->hostdata;
2212 DC390_LOCKA_INIT;
2213 DC390_LOCK_ACB;
2214
2215#if 0
2216 if( !dc390_pSH_start )
2217 {
2218 dc390_pSH_start = psh;
2219 dc390_pSH_current = psh;
2220 }
2221 else
2222 {
2223 dc390_pSH_current->next = psh;
2224 dc390_pSH_current = psh;
2225 }
2226#endif
2227
2228 DEBUG0(printk(KERN_INFO "DC390: pSH = %8x,", (UINT) psh);)
2229 DEBUG0(printk(" Index %02i,", index);)
2230
2231 dc390_initACB( psh, io_port, Irq, index );
2232 pACB = (PACB) psh->hostdata;
2233
2234 PDEVSET;
2235
2236 if( !dc390_initAdapter( psh, io_port, Irq, index ) )
2237 {
2238 DEBUG0(printk("\nDC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
2239 (UINT) pACB, (UINT) pACB->DCBmap, (UINT) pACB->SRB_array);)
2240 DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\
2241 sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) );)
2242
2243 DC390_UNLOCK_ACB;
2244 return (0);
2245 }
2246 else
2247 {
2248
2249 scsi_unregister( psh );
2250 DC390_UNLOCK_ACB;
2251 return( -1 );
2252 }
2253}
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269#ifndef NEW_PCI
2270
2271
2272static void __init dc390_set_master (PDEVDECL)
2273{
2274 USHORT cmd;
2275 UCHAR lat;
2276
2277 PCI_READ_CONFIG_WORD (PDEV, PCI_COMMAND, &cmd);
2278
2279 if (! (cmd & PCI_COMMAND_MASTER)) {
2280 printk("PCI: Enabling bus mastering for device %02x:%02x\n",
2281 PCI_BUS_DEV);
2282 cmd |= PCI_COMMAND_MASTER;
2283 PCI_WRITE_CONFIG_WORD(PDEV, PCI_COMMAND, cmd);
2284 }
2285 PCI_READ_CONFIG_BYTE (PDEV, PCI_LATENCY_TIMER, &lat);
2286 if (lat < 16 ) {
2287 printk("PCI: Setting latency timer of device %02x:%02x from %i to 64\n",
2288 PCI_BUS_DEV, lat);
2289 PCI_WRITE_CONFIG_BYTE(PDEV, PCI_LATENCY_TIMER, 64);
2290 }
2291
2292};
2293#endif
2294
2295static void __init dc390_set_pci_cfg (PDEVDECL)
2296{
2297 USHORT cmd;
2298 PCI_READ_CONFIG_WORD (PDEV, PCI_COMMAND, &cmd);
2299 cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO;
2300 PCI_WRITE_CONFIG_WORD (PDEV, PCI_COMMAND, cmd);
2301 PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
2302};
2303
2304
2305int __init DC390_detect (Scsi_Host_Template *psht)
2306{
2307 PDEVDECL0;
2308 UCHAR irq;
2309 UINT io_port;
2310
2311 DC390_DFLAGS
2312
2313 DC390_LOCK_DRV;
2314
2315 dc390_pACB_start = NULL;
2316
2317 if ( PCI_PRESENT )
2318 while (PCI_FIND_DEVICE (PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974))
2319 {
2320#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,30)
2321 if (pci_enable_device (pdev))
2322 continue;
2323#endif
2324
2325 PCI_GET_IO_AND_IRQ;
2326 DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq);)
2327
2328 if( !DC390_init(psht, io_port, irq, PDEV, dc390_adapterCnt))
2329 {
2330 PCI_SET_MASTER;
2331 dc390_set_pci_cfg (PDEV);
2332 dc390_adapterCnt++;
2333 };
2334
2335 }
2336 else
2337 printk (KERN_ERR "DC390: No PCI BIOS found!\n");
2338
2339 if (dc390_adapterCnt)
2340#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
2341 psht->proc_name = "tmscsim";
2342#else
2343 psht->proc_dir = &DC390_proc_scsi_tmscsim;
2344#endif
2345 printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt);
2346 DC390_UNLOCK_DRV;
2347 return( dc390_adapterCnt );
2348}
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359static void dc390_inquiry_done (Scsi_Cmnd* cmd)
2360{
2361 printk (KERN_INFO "DC390: INQUIRY (ID %02x LUN %02x) returned %08x\n",
2362 cmd->target, cmd->lun, cmd->result);
2363 if (cmd->result)
2364 {
2365 PACB pACB = (PACB)cmd->host->hostdata;
2366 PDCB pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun);
2367 printk ("DC390: Unsetting DsCn, Sync and TagQ!\n");
2368 if (pDCB)
2369 {
2370 pDCB->DevMode &= ~(SYNC_NEGO_ | TAG_QUEUEING_ | EN_DISCONNECT_ );
2371 dc390_updateDCB (pACB, pDCB);
2372 };
2373 };
2374 kfree (cmd);
2375};
2376
2377void dc390_inquiry (PACB pACB, PDCB pDCB)
2378{
2379 char* buffer;
2380 Scsi_Cmnd* cmd;
2381 cmd = kmalloc (sizeof(Scsi_Cmnd) + 256, GFP_ATOMIC);
2382 if (!cmd) { printk ("DC390: kmalloc failed in inquiry!\n"); return; };
2383 buffer = (char*)cmd + sizeof(Scsi_Cmnd);
2384
2385 memset (cmd, 0, sizeof(Scsi_Cmnd) + 256);
2386 cmd->cmnd[0] = INQUIRY;
2387 cmd->cmnd[1] = (pDCB->TargetLUN << 5) & 0xe0;
2388 cmd->cmnd[4] = 0xff;
2389
2390 cmd->cmd_len = 6; cmd->old_cmd_len = 6;
2391 cmd->host = pACB->pScsiHost;
2392 cmd->target = pDCB->TargetID;
2393 cmd->lun = pDCB->TargetLUN;
2394 cmd->serial_number = 1;
2395 cmd->pid = 390;
2396 cmd->bufflen = 128;
2397 cmd->buffer = buffer;
2398 cmd->request_bufflen = 128;
2399 cmd->request_buffer = &buffer[128];
2400 cmd->done = dc390_inquiry_done;
2401 cmd->scsi_done = dc390_inquiry_done;
2402 cmd->timeout_per_command = HZ;
2403
2404 cmd->request.rq_status = RQ_SCSI_BUSY;
2405
2406 pDCB->SyncMode &= ~SYNC_NEGO_DONE;
2407 printk (KERN_INFO "DC390: Queue INQUIRY command to dev ID %02x LUN %02x\n",
2408 pDCB->TargetID, pDCB->TargetLUN);
2409 DC390_queue_command (cmd, dc390_inquiry_done);
2410};
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420static void dc390_sendstart_done (Scsi_Cmnd* cmd)
2421{
2422 printk (KERN_INFO "DC390: SENDSTART (ID %02x LUN %02x) returned %08x\n",
2423 cmd->target, cmd->lun, cmd->result);
2424 kfree (cmd);
2425};
2426
2427void dc390_sendstart (PACB pACB, PDCB pDCB)
2428{
2429 char* buffer;
2430 Scsi_Cmnd* cmd;
2431 cmd = kmalloc (sizeof(Scsi_Cmnd) + 256, GFP_ATOMIC);
2432 if (!cmd) { printk ("DC390: kmalloc failed in sendstart!\n"); return; };
2433 buffer = (char*)cmd + sizeof(Scsi_Cmnd);
2434
2435 memset (cmd, 0, sizeof(Scsi_Cmnd) + 256);
2436 cmd->cmnd[0] = 0x1b;
2437 cmd->cmnd[1] = (pDCB->TargetLUN << 5) & 0xe0;
2438 cmd->cmnd[4] = 0x01;
2439
2440 cmd->cmd_len = 6; cmd->old_cmd_len = 6;
2441 cmd->host = pACB->pScsiHost;
2442 cmd->target = pDCB->TargetID;
2443 cmd->lun = pDCB->TargetLUN;
2444 cmd->serial_number = 1;
2445 cmd->pid = 310;
2446 cmd->bufflen = 128;
2447 cmd->buffer = buffer;
2448 cmd->request_bufflen = 128;
2449 cmd->request_buffer = &buffer[128];
2450 cmd->done = dc390_sendstart_done;
2451 cmd->scsi_done = dc390_sendstart_done;
2452 cmd->timeout_per_command = 5*HZ;
2453
2454 cmd->request.rq_status = RQ_SCSI_BUSY;
2455
2456 pDCB->SyncMode &= ~SYNC_NEGO_DONE;
2457 printk (KERN_INFO "DC390: Queue SEND_START command to dev ID %02x LUN %02x\n",
2458 pDCB->TargetID, pDCB->TargetLUN);
2459 DC390_queue_command (cmd, dc390_sendstart_done);
2460};
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471static int dc390_scanf (char** p1, char** p2, int* var)
2472{
2473 *p2 = *p1;
2474 *var = simple_strtoul (*p2, p1, 10);
2475 if (*p2 == *p1) return -1;
2476 *p1 = strtok (0, " \t\n:=,;.");
2477 return 0;
2478};
2479
2480#define SCANF(p1, p2, var, min, max) \
2481if (dc390_scanf (&p1, &p2, &var)) goto einv; \
2482else if (var<min || var>max) goto einv2
2483
2484static int dc390_yesno (char** p, char* var, char bmask)
2485{
2486 switch (**p)
2487 {
2488 case 'Y': *var |= bmask; break;
2489 case 'N': *var &= ~bmask; break;
2490 case '-': break;
2491 default: return -1;
2492 }
2493 *p = strtok (0, " \t\n:=,;");
2494 return 0;
2495};
2496
2497#define YESNO(p, var, bmask) \
2498if (dc390_yesno (&p, &var, bmask)) goto einv; \
2499else dc390_updateDCB (pACB, pDCB); \
2500if (!p) goto ok
2501
2502static int dc390_search (char **p1, char **p2, char *var, char* txt, int max, int scale, char* ign)
2503{
2504 int dum;
2505 if (! memcmp (*p1, txt, strlen(txt)))
2506 {
2507 *p2 = strtok (0, " \t\n:=,;");
2508 if (!*p2) return -1;
2509 dum = simple_strtoul (*p2, p1, 10);
2510 if (*p2 == *p1) return -1;
2511 if (dum >= 0 && dum <= max)
2512 { *var = (dum * 100) / scale; }
2513 else return -2;
2514 *p1 = strtok (0, " \t\n:=,;");
2515 if (*ign && *p1 && strlen(*p1) >= strlen(ign) &&
2516 !(memcmp (*p1, ign, strlen(ign))))
2517 *p1 = strtok (0, " \t\n:=,;");
2518
2519 }
2520 return 0;
2521};
2522
2523#define SEARCH(p1, p2, var, txt, max) \
2524if (dc390_search (&p1, &p2, (PUCHAR)(&var), txt, max, 100, "")) goto einv2; \
2525else if (!p1) goto ok2
2526
2527#define SEARCH2(p1, p2, var, txt, max, scale) \
2528if (dc390_search (&p1, &p2, &var, txt, max, scale, "")) goto einv2; \
2529else if (!p1) goto ok2
2530
2531#define SEARCH3(p1, p2, var, txt, max, scale, ign) \
2532if (dc390_search (&p1, &p2, &var, txt, max, scale, ign)) goto einv2; \
2533else if (!p1) goto ok2
2534
2535
2536#ifdef DC390_PARSEDEBUG
2537static char _prstr[256];
2538char* prstr (char* p, char* e)
2539{
2540 char* c = _prstr;
2541 while (p < e)
2542 if (*p == 0) { *c++ = ':'; p++; }
2543 else if (*p == 10) { *c++ = '\\'; *c++ = 'n'; p++; }
2544 else *c++ = *p++;
2545 *c = 0;
2546 return _prstr;
2547};
2548#endif
2549
2550int dc390_set_info (char *buffer, int length, PACB pACB)
2551{
2552 char *pos = buffer, *p0 = buffer;
2553 char needs_inquiry = 0;
2554 int dum = 0;
2555 char dev;
2556 PDCB pDCB = pACB->pLinkDCB;
2557 DC390_IFLAGS
2558 DC390_AFLAGS
2559 pos[length] = 0;
2560
2561 DC390_LOCK_IO;
2562 DC390_LOCK_ACB;
2563
2564
2565 while (*pos)
2566 { if (*pos >='a' && *pos <= 'z') *pos = *pos + 'A' - 'a'; pos++; };
2567
2568
2569
2570
2571
2572 pos = strtok (buffer, " \t:\n=,;");
2573 if (!pos) goto ok;
2574
2575 next:
2576 if (!memcmp (pos, "RESET", 5)) goto reset;
2577 else if (!memcmp (pos, "INQUIRY", 7)) goto inquiry;
2578 else if (!memcmp (pos, "REMOVE", 6)) goto remove;
2579 else if (!memcmp (pos, "ADD", 3)) goto add;
2580 else if (!memcmp (pos, "START", 5)) goto start;
2581 else if (!memcmp (pos, "DUMP", 4)) goto dump;
2582
2583 if (isdigit (*pos))
2584 {
2585
2586 int dev, id, lun; char* pdec;
2587 char olddevmode;
2588
2589 SCANF (pos, p0, dev, 0, pACB->DCBCnt-1);
2590 if (pos) { SCANF (pos, p0, id, 0, 7); } else goto einv;
2591 if (pos) { SCANF (pos, p0, lun, 0, 7); } else goto einv;
2592 if (!pos) goto einv;
2593
2594 PARSEDEBUG(printk (KERN_INFO "DC390: config line %i %i %i:\"%s\"\n", dev, id, lun, prstr (pos, &buffer[length]));)
2595 pDCB = pACB->pLinkDCB;
2596 for (dum = 0; dum < dev; dum++) pDCB = pDCB->pNextDCB;
2597
2598 if (pDCB->TargetID != id || pDCB->TargetLUN != lun)
2599 {
2600 printk (KERN_ERR "DC390: no such device: Idx=%02i ID=%02i LUN=%02i\n",
2601 dev, id, lun);
2602 goto einv2;
2603 };
2604
2605 if (pDCB->pWaitingSRB || pDCB->pGoingSRB)
2606 {
2607 printk ("DC390: Cannot change dev (%i-%i) cfg: Pending requests\n",
2608 pDCB->TargetID, pDCB->TargetLUN);
2609 goto einv;
2610 };
2611
2612 olddevmode = pDCB->DevMode;
2613 YESNO (pos, pDCB->DevMode, PARITY_CHK_);
2614 needs_inquiry++;
2615 YESNO (pos, pDCB->DevMode, SYNC_NEGO_);
2616 if ((olddevmode & SYNC_NEGO_) == (pDCB->DevMode & SYNC_NEGO_)) needs_inquiry--;
2617 needs_inquiry++;
2618 YESNO (pos, pDCB->DevMode, EN_DISCONNECT_);
2619 if ((olddevmode & EN_DISCONNECT_) == (pDCB->DevMode & EN_DISCONNECT_)) needs_inquiry--;
2620 YESNO (pos, pDCB->DevMode, SEND_START_);
2621 needs_inquiry++;
2622 YESNO (pos, pDCB->DevMode, TAG_QUEUEING_);
2623 if ((olddevmode & TAG_QUEUEING_) == (pDCB->DevMode & TAG_QUEUEING_)) needs_inquiry--;
2624
2625 dc390_updateDCB (pACB, pDCB);
2626 if (!pos) goto ok;
2627
2628 olddevmode = pDCB->NegoPeriod;
2629
2630 pdec = pos;
2631 while (pdec++ < &buffer[length]) if (*pdec == '.') break;
2632
2633 if (*pos != '-')
2634 {
2635 SCANF (pos, p0, dum, 72, 800);
2636 pDCB->NegoPeriod = dum >> 2;
2637 if (pDCB->NegoPeriod != olddevmode) needs_inquiry++;
2638 if (!pos) goto ok;
2639 if (memcmp (pos, "NS", 2) == 0) pos = strtok (0, " \t\n:=,;.");
2640 }
2641 else pos = strtok (0, " \t\n:=,;.");
2642 if (!pos) goto ok;
2643
2644
2645 if (*pos != '-')
2646 {
2647 SCANF (pos, p0, dum, 1, 13);
2648 pDCB->NegoPeriod = (1000/dum) >> 2;
2649 if (pDCB->NegoPeriod != olddevmode && !pos) needs_inquiry++;
2650 if (!pos) goto ok;
2651
2652 if (pos-1 == pdec)
2653 {
2654 int dumold = dum;
2655 dum = simple_strtoul (pos, &p0, 10) * 10;
2656 for (; p0-pos > 1; p0--) dum /= 10;
2657 pDCB->NegoPeriod = (100000/(100*dumold + dum)) >> 2;
2658 if (pDCB->NegoPeriod < 19) pDCB->NegoPeriod = 19;
2659 pos = strtok (0, " \t\n:=,;");
2660 if (!pos) goto ok;
2661 };
2662 if (*pos == 'M') pos = strtok (0, " \t\n:=,;");
2663 if (pDCB->NegoPeriod != olddevmode) needs_inquiry++;
2664 }
2665 else pos = strtok (0, " \t\n:=,;");
2666
2667 if (!pos) goto ok;
2668
2669 olddevmode = pDCB->SyncOffset;
2670
2671 if (*pos != '-')
2672 {
2673 SCANF (pos, p0, dum, 0, 0x0f);
2674 pDCB->SyncOffset = dum;
2675 if (pDCB->SyncOffset > olddevmode) needs_inquiry++;
2676 }
2677 else pos = strtok (0, " \t\n:=,;");
2678 if (!pos) goto ok;
2679 dc390_updateDCB (pACB, pDCB);
2680
2681
2682
2683 if (*pos != '-')
2684 {
2685 SCANF (pos, p0, dum, 1, 32 );
2686 if (pDCB->SyncMode & EN_TAG_QUEUEING)
2687 pDCB->MaxCommand = dum;
2688 else printk (KERN_INFO "DC390: Can't set MaxCmd larger than one without Tag Queueing!\n");
2689 }
2690 else pos = strtok (0, " \t\n:=,;");
2691
2692 }
2693 else
2694 {
2695 char* p1 = pos; UCHAR dum, newadaptid;
2696 PARSEDEBUG(printk (KERN_INFO "DC390: chg adapt cfg \"%s\"\n", prstr (pos, &buffer[length]));)
2697 dum = GLITCH_TO_NS (pACB->glitch_cfg);
2698
2699 SEARCH (pos, p0, pACB->pScsiHost->max_id, "MAXID", 8);
2700 SEARCH (pos, p0, pACB->pScsiHost->max_lun, "MAXLUN", 8);
2701 SEARCH (pos, p0, newadaptid, "ADAPTERID", 7);
2702 SEARCH (pos, p0, pACB->TagMaxNum, "TAGMAXNUM", 32);
2703 SEARCH (pos, p0, pACB->ACBFlag, "ACBFLAG", 255);
2704 SEARCH3 (pos, p0, dum, "GLITCHEATER", 40, 1000, "NS");
2705 SEARCH3 (pos, p0, pACB->sel_timeout, "SELTIMEOUT", 400, 163, "MS");
2706 SEARCH3 (pos, p0, dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY], "DELAYRESET", 180, 100, "S");
2707 ok2:
2708 pACB->glitch_cfg = NS_TO_GLITCH (dum);
2709 if (pACB->sel_timeout < 60) pACB->sel_timeout = 60;
2710 DC390_write8 (Scsi_TimeOut, pACB->sel_timeout);
2711 if (newadaptid != pACB->pScsiHost->this_id)
2712 {
2713 pACB->pScsiHost->this_id = newadaptid;
2714 dc390_ResetDevParam (pACB);
2715 }
2716
2717
2718 dc390_updateDCBs (pACB);
2719
2720 if (pos == p1) goto einv;
2721 }
2722 if (pos) goto next;
2723
2724 ok:
2725
2726 DC390_UNLOCK_ACB;
2727 if (needs_inquiry)
2728 { dc390_updateDCB (pACB, pDCB); dc390_inquiry (pACB, pDCB); };
2729 DC390_UNLOCK_IO;
2730 return (length);
2731
2732 einv2:
2733 pos = p0;
2734 einv:
2735
2736 DC390_UNLOCK_ACB;
2737 DC390_UNLOCK_IO;
2738 printk (KERN_WARNING "DC390: parse error near \"%s\"\n", (pos? pos: "NULL"));
2739 return (-EINVAL);
2740
2741 reset:
2742 {
2743 Scsi_Cmnd cmd; cmd.host = pACB->pScsiHost;
2744 printk (KERN_WARNING "DC390: Driver reset requested!\n");
2745 DC390_UNLOCK_ACB;
2746 DC390_reset (&cmd, 0);
2747 DC390_UNLOCK_IO;
2748 };
2749 return (length);
2750
2751 dump:
2752 {
2753 dc390_dumpinfo (pACB, 0, 0);
2754 DC390_UNLOCK_ACB;
2755 DC390_UNLOCK_IO;
2756 }
2757 return (length);
2758
2759 inquiry:
2760 {
2761 pos = strtok (0, " \t\n.:;="); if (!pos) goto einv;
2762 dev = simple_strtoul (pos, &p0, 10);
2763 if (dev >= pACB->DCBCnt) goto einv_dev;
2764 for (dum = 0; dum < dev; dum++) pDCB = pDCB->pNextDCB;
2765 printk (KERN_NOTICE " DC390: Issue INQUIRY command to Dev(Idx) %i SCSI ID %i LUN %i\n",
2766 dev, pDCB->TargetID, pDCB->TargetLUN);
2767 DC390_UNLOCK_ACB;
2768 dc390_inquiry (pACB, pDCB);
2769 DC390_UNLOCK_IO;
2770 };
2771 return (length);
2772
2773 remove:
2774 {
2775 pos = strtok (0, " \t\n.:;="); if (!pos) goto einv;
2776 dev = simple_strtoul (pos, &p0, 10);
2777 if (dev >= pACB->DCBCnt) goto einv_dev;
2778 for (dum = 0; dum < dev; dum++) pDCB = pDCB->pNextDCB;
2779 printk (KERN_NOTICE " DC390: Remove DCB for Dev(Idx) %i SCSI ID %i LUN %i\n",
2780 dev, pDCB->TargetID, pDCB->TargetLUN);
2781
2782 dc390_remove_dev (pACB, pDCB);
2783 DC390_UNLOCK_ACB;
2784 DC390_UNLOCK_IO;
2785 };
2786 return (length);
2787
2788 add:
2789 {
2790 int id, lun;
2791 pos = strtok (0, " \t\n.:;=");
2792 if (pos) { SCANF (pos, p0, id, 0, 7); } else goto einv;
2793 if (pos) { SCANF (pos, p0, lun, 0, 7); } else goto einv;
2794 pDCB = dc390_findDCB (pACB, id, lun);
2795 if (pDCB) { printk ("DC390: ADD: Device already existing\n"); goto einv; };
2796 dc390_initDCB (pACB, &pDCB, id, lun);
2797 DC390_UNLOCK_ACB;
2798 dc390_inquiry (pACB, pDCB);
2799 DC390_UNLOCK_IO;
2800 };
2801 return (length);
2802
2803 start:
2804 {
2805 int id, lun;
2806 pos = strtok (0, " \t\n.:;=");
2807 if (pos) { SCANF (pos, p0, id, 0, 7); } else goto einv;
2808 if (pos) { SCANF (pos, p0, lun, 0, 7); } else goto einv;
2809 pDCB = dc390_findDCB (pACB, id, lun);
2810 if (pDCB) printk ("DC390: SendStart: Device already existing ...\n");
2811 else dc390_initDCB (pACB, &pDCB, id, lun);
2812 DC390_UNLOCK_ACB;
2813 dc390_sendstart (pACB, pDCB);
2814 dc390_inquiry (pACB, pDCB);
2815 DC390_UNLOCK_IO;
2816 };
2817 return (length);
2818
2819 einv_dev:
2820 printk (KERN_WARNING "DC390: Ignore cmnd to illegal Dev(Idx) %i. Valid range: 0 - %i.\n",
2821 dev, pACB->DCBCnt - 1);
2822 DC390_UNLOCK_ACB;
2823 DC390_UNLOCK_IO;
2824 return (-EINVAL);
2825
2826
2827}
2828
2829#undef SEARCH
2830#undef YESNO
2831#undef SCANF
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852#undef SPRINTF
2853#define SPRINTF(args...) pos += sprintf(pos, ## args)
2854
2855#define YESNO(YN) \
2856 if (YN) SPRINTF(" Yes "); \
2857 else SPRINTF(" No ")
2858
2859
2860int DC390_proc_info (char *buffer, char **start,
2861 off_t offset, int length, int hostno, int inout)
2862{
2863 int dev, spd, spd1;
2864 char *pos = buffer;
2865 PSH shpnt = 0;
2866 PACB pACB;
2867 PDCB pDCB;
2868 PSCSICMD pcmd;
2869 DC390_AFLAGS
2870
2871 pACB = dc390_pACB_start;
2872
2873 while(pACB != (PACB)-1)
2874 {
2875 shpnt = pACB->pScsiHost;
2876 if (shpnt->host_no == hostno) break;
2877 pACB = pACB->pNextACB;
2878 }
2879
2880 if (pACB == (PACB)-1) return(-ESRCH);
2881 if(!shpnt) return(-ESRCH);
2882
2883 if(inout)
2884 return dc390_set_info(buffer, length, pACB);
2885
2886 SPRINTF("Tekram DC390/AM53C974 PCI SCSI Host Adapter, ");
2887 SPRINTF("Driver Version %s\n", DC390_VERSION);
2888
2889 DC390_LOCK_ACB;
2890
2891 SPRINTF("SCSI Host Nr %i, ", shpnt->host_no);
2892 SPRINTF("%s Adapter Nr %i\n", dc390_adapname, pACB->AdapterIndex);
2893 SPRINTF("IOPortBase 0x%04x, ", pACB->IOPortBase);
2894 SPRINTF("IRQ %02i\n", pACB->IRQLevel);
2895
2896 SPRINTF("MaxID %i, MaxLUN %i, ", shpnt->max_id, shpnt->max_lun);
2897 SPRINTF("AdapterID %i, SelTimeout %i ms, DelayReset %i s\n",
2898 shpnt->this_id, (pACB->sel_timeout*164)/100,
2899 dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]);
2900
2901 SPRINTF("TagMaxNum %i, Status 0x%02x, ACBFlag 0x%02x, GlitchEater %i ns\n",
2902 pACB->TagMaxNum, pACB->status, pACB->ACBFlag, GLITCH_TO_NS(pACB->glitch_cfg)*12);
2903
2904 SPRINTF("Statistics: Cmnds %li, Cmnds not sent directly %i, Out of SRB conds %i\n",
2905 pACB->Cmds, pACB->CmdInQ, pACB->CmdOutOfSRB);
2906 SPRINTF(" Lost arbitrations %i, Sel. connected %i, Connected: %s\n",
2907 pACB->SelLost, pACB->SelConn, pACB->Connected? "Yes": "No");
2908
2909 SPRINTF("Nr of attached devices: %i, Nr of DCBs: %i\n", pACB->DeviceCnt, pACB->DCBCnt);
2910 SPRINTF("Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x\n",
2911 pACB->DCBmap[0], pACB->DCBmap[1], pACB->DCBmap[2], pACB->DCBmap[3],
2912 pACB->DCBmap[4], pACB->DCBmap[5], pACB->DCBmap[6], pACB->DCBmap[7]);
2913
2914 SPRINTF("Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs MaxCmd\n");
2915
2916 pDCB = pACB->pLinkDCB;
2917 for (dev = 0; dev < pACB->DCBCnt; dev++)
2918 {
2919 SPRINTF("%02i %02i %02i ", dev, pDCB->TargetID, pDCB->TargetLUN);
2920 YESNO(pDCB->DevMode & PARITY_CHK_);
2921 YESNO(pDCB->SyncMode & SYNC_NEGO_DONE);
2922 YESNO(pDCB->DevMode & EN_DISCONNECT_);
2923 YESNO(pDCB->DevMode & SEND_START_);
2924 YESNO(pDCB->SyncMode & EN_TAG_QUEUEING);
2925 if (pDCB->SyncOffset & 0x0f)
2926 {
2927 int sp = pDCB->SyncPeriod; if (! (pDCB->CtrlR3 & FAST_SCSI)) sp++;
2928 SPRINTF(" %03i ns ", (pDCB->NegoPeriod) << 2);
2929 spd = 40/(sp); spd1 = 40%(sp);
2930 spd1 = (spd1 * 10 + sp/2) / (sp);
2931 SPRINTF(" %2i.%1i M %02i", spd, spd1, (pDCB->SyncOffset & 0x0f));
2932 }
2933 else SPRINTF(" (%03i ns) ", (pDCB->NegoPeriod) << 2);
2934
2935 SPRINTF (" %02i\n", pDCB->MaxCommand);
2936 pDCB = pDCB->pNextDCB;
2937 }
2938 SPRINTF ("Commands in Queues: Query: %li:", pACB->QueryCnt);
2939 for (pcmd = pACB->pQueryHead; pcmd; pcmd = pcmd->next)
2940 SPRINTF (" %li", pcmd->pid);
2941 if (timer_pending(&pACB->Waiting_Timer)) SPRINTF ("Waiting queue timer running\n");
2942 else SPRINTF ("\n");
2943 pDCB = pACB->pLinkDCB;
2944
2945 for (dev = 0; dev < pACB->DCBCnt; dev++)
2946 {
2947 PSRB pSRB;
2948 if (pDCB->WaitSRBCnt)
2949 SPRINTF ("DCB (%02i-%i): Waiting: %i:", pDCB->TargetID, pDCB->TargetLUN,
2950 pDCB->WaitSRBCnt);
2951 for (pSRB = pDCB->pWaitingSRB; pSRB; pSRB = pSRB->pNextSRB)
2952 SPRINTF(" %li", pSRB->pcmd->pid);
2953 if (pDCB->GoingSRBCnt)
2954 SPRINTF ("\nDCB (%02i-%i): Going : %i:", pDCB->TargetID, pDCB->TargetLUN,
2955 pDCB->GoingSRBCnt);
2956 for (pSRB = pDCB->pGoingSRB; pSRB; pSRB = pSRB->pNextSRB)
2957#if 0
2958 SPRINTF(" %s\n ", pSRB->debugtrace);
2959#else
2960 SPRINTF(" %li", pSRB->pcmd->pid);
2961#endif
2962 if (pDCB->WaitSRBCnt || pDCB->GoingSRBCnt) SPRINTF ("\n");
2963 pDCB = pDCB->pNextDCB;
2964 }
2965
2966#ifdef DC390_DEBUGDCB
2967 SPRINTF ("DCB list for ACB %p:\n", pACB);
2968 pDCB = pACB->pLinkDCB;
2969 SPRINTF ("%p", pDCB);
2970 for (dev = 0; dev < pACB->DCBCnt; dev++, pDCB=pDCB->pNextDCB)
2971 SPRINTF ("->%p", pDCB->pNextDCB);
2972 SPRINTF("\n");
2973#endif
2974
2975
2976 DC390_UNLOCK_ACB;
2977 *start = buffer + offset;
2978
2979 if (pos - buffer < offset)
2980 return 0;
2981 else if (pos - buffer - offset < length)
2982 return pos - buffer - offset;
2983 else
2984 return length;
2985}
2986
2987#undef YESNO
2988#undef SPRINTF
2989
2990#ifdef MODULE
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000static int dc390_shutdown (struct Scsi_Host *host)
3001{
3002 UCHAR bval;
3003 PACB pACB = (PACB)(host->hostdata);
3004
3005
3006
3007 printk(KERN_INFO "DC390: shutdown\n");
3008
3009 pACB->ACBFlag = RESET_DEV;
3010 bval = DC390_read8 (CtrlReg1);
3011 bval |= DIS_INT_ON_SCSI_RST;
3012 DC390_write8 (CtrlReg1, bval);
3013 if (pACB->Gmode2 & RST_SCSI_BUS)
3014 dc390_ResetSCSIBus (pACB);
3015
3016 if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);
3017 return( 0 );
3018}
3019
3020void dc390_freeDCBs (struct Scsi_Host *host)
3021{
3022 PDCB pDCB, nDCB;
3023 PACB pACB = (PACB)(host->hostdata);
3024
3025 pDCB = pACB->pLinkDCB;
3026 if (!pDCB) return;
3027 do
3028 {
3029 nDCB = pDCB->pNextDCB;
3030 DCBDEBUG(printk (KERN_INFO "DC390: Free DCB (ID %i, LUN %i): %p\n",\
3031 pDCB->TargetID, pDCB->TargetLUN, pDCB);)
3032
3033 dc390_remove_dev (pACB, pDCB);
3034 pDCB = nDCB;
3035 } while (pDCB && pACB->pLinkDCB);
3036
3037};
3038
3039int DC390_release (struct Scsi_Host *host)
3040{
3041 DC390_AFLAGS DC390_IFLAGS
3042 PACB pACB = (PACB)(host->hostdata);
3043
3044 DC390_LOCK_IO;
3045 DC390_LOCK_ACB;
3046
3047
3048 dc390_shutdown (host);
3049
3050 if (host->irq != IRQ_NONE)
3051 {
3052 DEBUG0(printk(KERN_INFO "DC390: Free IRQ %i\n",host->irq);)
3053 free_irq (host->irq, pACB);
3054 }
3055
3056 release_region(host->io_port,host->n_io_port);
3057 dc390_freeDCBs (host);
3058 DC390_UNLOCK_ACB;
3059 DC390_UNLOCK_IO;
3060 return( 1 );
3061}
3062#endif
3063
3064#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,99)
3065static Scsi_Host_Template driver_template = DC390_T;
3066#include "scsi_module.c"
3067#endif
3068