1 /***********************************************************************
2 * FILE NAME : TMSCSIM.C *
3 * BY : C.L. Huang, ching@tekram.com.tw *
4 * Description: Device Driver for Tekram DC-390(T) PCI SCSI *
5 * Bus Master Host Adapter *
6 * (C)Copyright 1995-1996 Tekram Technology Co., Ltd. *
7 ***********************************************************************/
8 /* (C) Copyright: put under GNU GPL in 10/96 *
9 *************************************************************************/
10 /* $Id: tmscsim.c,v 2.16 1998/12/25 17:54:44 garloff Exp $ */
11 /* Enhancements and bugfixes by *
12 * Kurt Garloff <kurt@garloff.de> *
13 ***********************************************************************/
16 * REV# DATE NAME DESCRIPTION *
17 * 1.00 96/04/24 CLH First release *
18 * 1.01 96/06/12 CLH Fixed bug of Media Change for Removable *
19 * Device, scan all LUN. Support Pre2.0.10 *
20 * 1.02 96/06/18 CLH Fixed bug of Command timeout ... *
21 * 1.03 96/09/25 KG Added tmscsim_proc_info() *
22 * 1.04 96/10/11 CLH Updating for support KV 2.0.x *
23 * 1.05 96/10/18 KG Fixed bug in DC390_abort(null ptr deref)*
24 * 1.06 96/10/25 KG Fixed module support *
25 * 1.07 96/11/09 KG Fixed tmscsim_proc_info() *
26 * 1.08 96/11/18 KG Fixed null ptr in DC390_Disconnect() *
27 * 1.09 96/11/30 KG Added register the allocated IO space *
28 * 1.10 96/12/05 CLH Modified tmscsim_proc_info(), and reset *
29 * pending interrupt in DC390_detect() *
30 * 1.11 97/02/05 KG/CLH Fixeds problem with partitions greater *
32 * 1.12 98/02/15 MJ Rewritten PCI probing *
33 * 1.13 98/04/08 KG Support for non DC390, __initfunc decls,*
34 * changed max devs from 10 to 16 *
35 * 1.14a 98/05/05 KG Dynamic DCB allocation, add-single-dev *
36 * for LUNs if LUN_SCAN (BIOS) not set *
37 * runtime config using /proc interface *
38 * 1.14b 98/05/06 KG eliminated cli (); sti (); spinlocks *
39 * 1.14c 98/05/07 KG 2.0.x compatibility *
40 * 1.20a 98/05/07 KG changed names of funcs to be consistent *
41 * DC390_ (entry points), dc390_ (internal)*
43 * 1.20b 98/05/12 KG bugs: version, kfree, _ctmp *
45 * 1.20c 98/05/12 KG bugs: kfree, parsing, EEpromDefaults *
46 * 1.20d 98/05/14 KG bugs: list linkage, clear flag after *
47 * reset on startup, code cleanup *
48 * 1.20e 98/05/15 KG spinlock comments, name space cleanup *
49 * pLastDCB now part of ACB structure *
50 * added stats, timeout for 2.1, TagQ bug *
51 * RESET and INQUIRY interface commands *
52 * 1.20f 98/05/18 KG spinlocks fixes, max_lun fix, free DCBs *
53 * for missing LUNs, pending int *
54 * 1.20g 98/05/19 KG Clean up: Avoid short *
55 * 1.20h 98/05/21 KG Remove AdaptSCSIID, max_lun ... *
56 * 1.20i 98/05/21 KG Aiiie: Bug with TagQMask *
57 * 1.20j 98/05/24 KG Handle STAT_BUSY, handle pACB->pLinkDCB *
58 * == 0 in remove_dev and DoingSRB_Done *
59 * 1.20k 98/05/25 KG DMA_INT (experimental) *
60 * 1.20l 98/05/27 KG remove DMA_INT; DMA_IDLE cmds added; *
61 * 1.20m 98/06/10 KG glitch configurable; made some global *
62 * vars part of ACB; use DC390_readX *
63 * 1.20n 98/06/11 KG startup params *
64 * 1.20o 98/06/15 KG added TagMaxNum to boot/module params *
65 * Device Nr -> Idx, TagMaxNum power of 2 *
66 * 1.20p 98/06/17 KG Docu updates. Reset depends on settings *
67 * pci_set_master added; 2.0.xx: pcibios_* *
68 * used instead of MechNum things ... *
69 * 1.20q 98/06/23 KG Changed defaults. Added debug code for *
70 * removable media and fixed it. TagMaxNum *
71 * fixed for DC390. Locking: ACB, DRV for *
72 * better IRQ sharing. Spelling: Queueing *
73 * Parsing and glitch_cfg changes. Display *
74 * real SyncSpeed value. Made DisConn *
76 * 1.20r 98/06/30 KG Debug macros, allow disabling DsCn, set *
77 * BIT4 in CtrlR4, EN_PAGE_INT, 2.0 module *
79 * 1.20s 98/08/20 KG Debug info on abort(), try to check PCI,*
80 * phys_to_bus instead of phys_to_virt, *
81 * fixed sel. process, fixed locking, *
82 * added MODULE_XXX infos, changed IRQ *
83 * request flags, disable DMA_INT *
84 * 1.20t 98/09/07 KG TagQ report fixed; Write Erase DMA Stat;*
85 * initfunc -> __init; better abort; *
86 * Timeout for XFER_DONE & BLAST_COMPLETE; *
87 * Allow up to 33 commands being processed *
88 * 2.0a 98/10/14 KG Max Cmnds back to 17. DMA_Stat clearing *
89 * all flags. Clear within while() loops *
90 * in DataIn_0/Out_0. Null ptr in dumpinfo *
91 * for pSRB==0. Better locking during init.*
92 * bios_param() now respects part. table. *
93 * 2.0b 98/10/24 KG Docu fixes. Timeout Msg in DMA Blast. *
94 * Disallow illegal idx in INQUIRY/REMOVE *
95 * 2.0c 98/11/19 KG Cleaned up detect/init for SMP boxes, *
96 * Write Erase DMA (1.20t) caused problems *
97 * 2.0d 98/12/25 KG Christmas release ;-) Message handling *
98 * competely reworked. Handle target ini- *
99 * tiated SDTR correctly. *
100 ***********************************************************************/
102 /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */
103 #define DC390_IRQ SA_SHIRQ /* | SA_INTERRUPT */
106 //#define DC390_DEBUG0
107 //#define DC390_DEBUG1
108 //#define DC390_DCBDEBUG
109 //#define DC390_PARSEDEBUG
110 //#define DC390_REMOVABLEDEBUG
112 /* Debug definitions */
114 # define DEBUG0(x) x;
119 # define DEBUG1(x) x;
123 #ifdef DC390_DCBDEBUG
124 # define DCBDEBUG(x) x;
128 #ifdef DC390_PARSEDEBUG
129 # define PARSEDEBUG(x) x;
131 # define PARSEDEBUG(x)
133 #ifdef DC390_REMOVABLEDEBUG
134 # define REMOVABLEDEBUG(x) x;
136 # define REMOVABLEDEBUG(x)
142 # include <linux/module.h>
147 #include <asm/system.h>
148 #include <linux/delay.h>
149 #include <linux/signal.h>
150 #include <linux/sched.h>
151 #include <linux/errno.h>
152 #include <linux/kernel.h>
153 #include <linux/ioport.h>
154 #include <linux/pci.h>
155 #include <linux/proc_fs.h>
156 #include <linux/string.h>
157 #include <linux/ctype.h>
158 #include <linux/mm.h>
159 #include <linux/config.h>
160 #include <linux/version.h>
161 #include <linux/blk.h>
165 #include "constants.h"
167 #include <linux/stat.h>
171 #define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI
175 /* Note: Starting from 2.1.9x, the mid-level scsi code issues a
176 * spinlock_irqsave (&io_request_lock) before calling the driver's
177 * routines, so we don't need to lock.
178 * TODO: Verify, if we are locked in every case!
179 * The policy 3, let the midlevel scsi code do the io_request_locks
180 * and us locking on a driver specific lock, shouldn't hurt anybody; it
181 * just causes a minor performance degradation for setting the locks.
185 * level 3: lock on both adapter specific locks and (global) io_request_lock
186 * level 2: lock on adapter specific locks only
187 * level 1: rely on the locking of the mid level code (io_request_lock)
188 * undef : traditional save_flags; cli; restore_flags;
191 //#define DEBUG_SPINLOCKS 2 /* Set to 0, 1 or 2 in include/linux/spinlock.h */
193 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
195 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30)
196 # include <linux/init.h>
197 # include <linux/spinlock.h>
201 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
202 # define USE_SPINLOCKS 1
206 # if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30)
207 # define USE_SPINLOCKS 2
213 # if USE_SPINLOCKS == 3 /* both */
215 # if defined (__SMP__) || DEBUG_SPINLOCKS > 0
216 # define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
218 # define DC390_LOCKA_INIT
220 spinlock_t dc390_drvlock
= SPIN_LOCK_UNLOCKED
;
222 # define DC390_AFLAGS unsigned long aflags;
223 # define DC390_IFLAGS unsigned long iflags;
224 # define DC390_DFLAGS unsigned long dflags;
226 # define DC390_LOCK_IO spin_lock_irqsave (&io_request_lock, iflags)
227 # define DC390_UNLOCK_IO spin_unlock_irqrestore (&io_request_lock, iflags)
229 # define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
230 # define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
231 # define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
232 # define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
234 # define DC390_LOCK_ACB spin_lock_irqsave (&(pACB->lock), aflags)
235 # define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags)
236 # define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock))
237 # define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock))
238 //# define DC390_LOCKA_INIT spin_lock_init (&(pACB->lock))
242 # if USE_SPINLOCKS == 2 /* adapter specific locks */
244 # if defined (__SMP__) || DEBUG_SPINLOCKS > 0
245 # define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
247 # define DC390_LOCKA_INIT
249 spinlock_t dc390_drvlock
= SPIN_LOCK_UNLOCKED
;
250 # define DC390_AFLAGS unsigned long aflags;
251 # define DC390_IFLAGS
252 # define DC390_DFLAGS unsigned long dflags;
253 # define DC390_LOCK_IO /* spin_lock_irqsave (&io_request_lock, iflags) */
254 # define DC390_UNLOCK_IO /* spin_unlock_irqrestore (&io_request_lock, iflags) */
255 # define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
256 # define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
257 # define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
258 # define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
259 # define DC390_LOCK_ACB spin_lock_irqsave (&(pACB->lock), aflags)
260 # define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags)
261 # define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock))
262 # define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock))
263 //# define DC390_LOCKA_INIT spin_lock_init (&(pACB->lock))
265 # else /* USE_SPINLOCKS == 1: global lock io_request_lock */
267 # define DC390_AFLAGS
268 # define DC390_IFLAGS unsigned long iflags;
269 # define DC390_DFLAGS unsigned long dflags;
270 spinlock_t dc390_drvlock
= SPIN_LOCK_UNLOCKED
;
271 # define DC390_LOCK_IO spin_lock_irqsave (&io_request_lock, iflags)
272 # define DC390_UNLOCK_IO spin_unlock_irqrestore (&io_request_lock, iflags)
273 # define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
274 # define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
275 # define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
276 # define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
277 # define DC390_LOCK_ACB /* DC390_LOCK_IO */
278 # define DC390_UNLOCK_ACB /* DC390_UNLOCK_IO */
279 # define DC390_LOCK_ACB_NI /* spin_lock (&(pACB->lock)) */
280 # define DC390_UNLOCK_ACB_NI /* spin_unlock (&(pACB->lock)) */
281 # define DC390_LOCKA_INIT /* DC390_LOCKA_INIT */
286 #else /* USE_SPINLOCKS undefined */
288 # define DC390_AFLAGS unsigned long aflags;
289 # define DC390_IFLAGS unsigned long iflags;
290 # define DC390_DFLAGS unsigned long dflags;
291 # define DC390_LOCK_IO save_flags (iflags); cli ()
292 # define DC390_UNLOCK_IO restore_flags (iflags)
293 # define DC390_LOCK_DRV save_flags (dflags); cli ()
294 # define DC390_UNLOCK_DRV restore_flags (dflags)
295 # define DC390_LOCK_DRV_NI
296 # define DC390_UNLOCK_DRV_NI
297 # define DC390_LOCK_ACB save_flags (aflags); cli ()
298 # define DC390_UNLOCK_ACB restore_flags (aflags)
299 # define DC390_LOCK_ACB_NI
300 # define DC390_UNLOCK_ACB_NI
301 # define DC390_LOCKA_INIT
305 /* These macros are used for uniform access to 2.0.x and 2.1.x PCI config space*/
309 # define PDEVDECL struct pci_dev *pdev
310 # define PDEVDECL0 struct pci_dev *pdev = NULL
311 # define PDEVDECL1 struct pci_dev *pdev
312 # define PDEVSET pACB->pdev=pdev
313 # define PDEVSET1 pdev=pACB->pdev
314 # define PCI_WRITE_CONFIG_BYTE(pd, rv, bv) pci_write_config_byte (pd, rv, bv)
315 # define PCI_READ_CONFIG_BYTE(pd, rv, bv) pci_read_config_byte (pd, rv, bv)
316 # define PCI_WRITE_CONFIG_WORD(pd, rv, bv) pci_write_config_word (pd, rv, bv)
317 # define PCI_READ_CONFIG_WORD(pd, rv, bv) pci_read_config_word (pd, rv, bv)
318 # define PCI_BUS_DEV pdev->bus->number, pdev->devfn
319 # define PCI_PRESENT pci_present ()
320 # define PCI_SET_MASTER pci_set_master (pdev)
321 # define PCI_FIND_DEVICE(vend, id) (pdev = pci_find_device (vend, id, pdev))
322 # define PCI_GET_IO_AND_IRQ io_port = pdev->resource[0].start; irq = pdev->irq
324 # include <linux/bios32.h>
325 # define PDEV pbus, pdevfn
326 # define PDEVDECL UCHAR pbus, UCHAR pdevfn
327 # define PDEVDECL0 UCHAR pbus = 0; UCHAR pdevfn = 0; USHORT pci_index = 0; int error
328 # define PDEVDECL1 UCHAR pbus; UCHAR pdevfn /*; USHORT pci_index */
329 # define PDEVSET pACB->pbus=pbus; pACB->pdevfn=pdevfn /*; pACB->pci_index=pci_index */
330 # define PDEVSET1 pbus=pACB->pbus; pdevfn=pACB->pdevfn /*; pci_index=pACB->pci_index */
331 # define PCI_WRITE_CONFIG_BYTE(pd, rv, bv) pcibios_write_config_byte (pd, rv, bv)
332 # define PCI_READ_CONFIG_BYTE(pd, rv, bv) pcibios_read_config_byte (pd, rv, bv)
333 # define PCI_WRITE_CONFIG_WORD(pd, rv, bv) pcibios_write_config_word (pd, rv, bv)
334 # define PCI_READ_CONFIG_WORD(pd, rv, bv) pcibios_read_config_word (pd, rv, bv)
335 # define PCI_BUS_DEV pbus, pdevfn
336 # define PCI_PRESENT pcibios_present ()
337 # define PCI_SET_MASTER dc390_set_master (pbus, pdevfn)
338 # define PCI_FIND_DEVICE(vend, id) (!pcibios_find_device (vend, id, pci_index++, &pbus, &pdevfn))
339 # define PCI_GET_IO_AND_IRQ error = pcibios_read_config_dword (pbus, pdevfn, PCI_BASE_ADDRESS_0, &io_port); \
340 error |= pcibios_read_config_byte (pbus, pdevfn, PCI_INTERRUPT_LINE, &irq); \
342 if (error) { printk (KERN_ERR "DC390_detect: Error reading PCI config registers!\n"); continue; }
351 UCHAR
dc390_StartSCSI( PACB pACB
, PDCB pDCB
, PSRB pSRB
);
352 void dc390_DataOut_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
353 void dc390_DataIn_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
354 static void dc390_Command_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
355 static void dc390_Status_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
356 static void dc390_MsgOut_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
357 void dc390_MsgIn_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
358 static void dc390_DataOutPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
359 static void dc390_DataInPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
360 void dc390_CommandPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
361 static void dc390_StatusPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
362 void dc390_MsgOutPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
363 static void dc390_MsgInPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
364 static void dc390_Nop_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
365 static void dc390_Nop_1( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
367 static void dc390_SetXferRate( PACB pACB
, PDCB pDCB
);
368 void dc390_Disconnect( PACB pACB
);
369 void dc390_Reselect( PACB pACB
);
370 void dc390_SRBdone( PACB pACB
, PDCB pDCB
, PSRB pSRB
);
371 void dc390_DoingSRB_Done( PACB pACB
);
372 static void dc390_ScsiRstDetect( PACB pACB
);
373 static void dc390_ResetSCSIBus( PACB pACB
);
374 static void __inline__
dc390_RequestSense( PACB pACB
, PDCB pDCB
, PSRB pSRB
);
375 static void __inline__
dc390_InvalidCmd( PACB pACB
);
376 static void __inline__
dc390_EnableMsgOut_Abort (PACB
, PSRB
);
377 static void dc390_remove_dev (PACB pACB
, PDCB pDCB
);
378 void do_DC390_Interrupt( int, void *, struct pt_regs
*);
380 int dc390_initAdapter( PSH psh
, ULONG io_port
, UCHAR Irq
, UCHAR index
);
381 void dc390_initDCB( PACB pACB
, PDCB
*ppDCB
, PSCSICMD cmd
);
382 void dc390_updateDCB (PACB pACB
, PDCB pDCB
);
385 static int DC390_release(struct Scsi_Host
*host
);
386 static int dc390_shutdown (struct Scsi_Host
*host
);
390 //static PSHT dc390_pSHT_start = NULL;
391 //static PSH dc390_pSH_start = NULL;
392 //static PSH dc390_pSH_current = NULL;
393 static PACB dc390_pACB_start
= NULL
;
394 static PACB dc390_pACB_current
= NULL
;
395 static UCHAR dc390_adapterCnt
= 0;
396 static UCHAR dc390_CurrSyncOffset
= 0;
397 static ULONG dc390_lastabortedpid
= 0;
398 static ULONG dc390_laststatus
= 0;
400 #ifndef CONFIG_SCSI_DC390T_NOGENSUPP
401 /* Startup values, to be overriden on the commandline */
402 int tmscsim
[] = {7, 1 /* 8MHz */,
403 PARITY_CHK_
| SEND_START_
| EN_DISCONNECT_
404 | SYNC_NEGO_
| TAG_QUEUEING_
,
405 MORE2_DRV
| GREATER_1G
| RST_SCSI_BUS
| ACTIVE_NEGATION
407 # ifdef CONFIG_SCSI_MULTI_LUN
410 , 3 /* 16 Tags per LUN */};
412 # if defined(MODULE) && LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30)
413 MODULE_PARM(tmscsim
, "1-5i");
414 MODULE_PARM_DESC(tmscsim
, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1)");
417 #endif /* CONFIG_SCSI_DC390T_NOGENSUPP */
419 #if defined(MODULE) && LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30)
420 MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
421 MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
422 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
425 static PVOID dc390_phase0
[]={
437 static PVOID dc390_phase1
[]={
450 static char* dc390_p0_str
[] = {
462 static char* dc390_p1_str
[] = {
463 "dc390_DataOutPhase",
465 "dc390_CommandPhase",
475 /* Devices erroneously pretending to be able to do TagQ */
476 UCHAR dc390_baddevname1
[2][28] ={
477 "SEAGATE ST3390N 9546",
478 "HP C3323-300 4269"};
481 static char* dc390_adapname
= "DC390";
482 UCHAR dc390_eepromBuf
[MAX_ADAPTER_NUM
][EE_LEN
];
483 UCHAR dc390_clock_period1
[] = {4, 5, 6, 7, 8, 10, 13, 20};
485 struct proc_dir_entry DC390_proc_scsi_tmscsim
={
486 PROC_SCSI_DC390T
, 7 ,"tmscsim",
487 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2
491 /***********************************************************************
492 * Functions for access to DC390 EEPROM
493 * and some to emulate it
495 **********************************************************************/
498 static void __init
dc390_EnDisableCE( UCHAR mode
, PDEVDECL
, PUCHAR regval
)
503 if(mode
== ENABLE_CE
)
507 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
508 if(mode
== DISABLE_CE
)
509 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
513 #ifndef CONFIG_SCSI_DC390T_NOGENSUPP
514 static void __init
dc390_EEpromDefaults (UCHAR index
)
518 ptr
= (PUCHAR
) dc390_eepromBuf
[index
];
520 /* Adapter Settings */
521 ptr
[EE_ADAPT_SCSI_ID
] = (UCHAR
)tmscsim
[0]; /* Adapter ID */
522 ptr
[EE_MODE2
] = (UCHAR
)tmscsim
[3];
523 ptr
[EE_DELAY
] = 0; /* ?? */
524 ptr
[EE_TAG_CMD_NUM
] = (UCHAR
)tmscsim
[4]; /* Tagged Comds */
526 /* Device Settings */
527 for (id
= 0; id
< MAX_SCSI_ID
; id
++)
529 ptr
[id
<<2] = (UCHAR
)tmscsim
[2]; /* EE_MODE1 */
530 ptr
[(id
<<2) + 1] = (UCHAR
)tmscsim
[1]; /* EE_Speed */
532 dc390_adapname
= "AM53C974";
535 static void __init
dc390_checkparams (void)
537 PARSEDEBUG(printk(KERN_INFO
"DC390: setup %08x %08x %08x %08x %08x\n", tmscsim
[0],\
538 tmscsim
[1], tmscsim
[2], tmscsim
[3], tmscsim
[4]);)
539 if (tmscsim
[0] < 0 || tmscsim
[0] > 7) /* modules-2.0.0 passes -1 as string */
541 tmscsim
[0] = 7; tmscsim
[1] = 4;
542 tmscsim
[2] = 9; tmscsim
[3] = 15;
544 printk (KERN_INFO
"DC390: Using safe settings.\n");
548 /* if (tmscsim[0] < 0 || tmscsim[0] > 7) tmscsim[0] = 7; */
549 if (tmscsim
[1] < 0 || tmscsim
[1] > 7) tmscsim
[1] = 4;
550 if (tmscsim
[4] < 0 || tmscsim
[4] > 5) tmscsim
[4] = 4;
553 /* Override defaults on cmdline:
554 * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped)
556 void __init
dc390_setup (char *str
, int *ints
)
559 for (i
= 0; i
< ints
[0]; i
++)
560 tmscsim
[i
] = ints
[i
+1];
562 printk (KERN_NOTICE
"DC390: ignore extra params!\n");
563 /* dc390_checkparams (); */
565 #endif /* CONFIG_SCSI_DC390T_NOGENSUPP */
568 static void __init
dc390_EEpromOutDI( PDEVDECL
, PUCHAR regval
, UCHAR Carry
)
577 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
581 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
584 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
589 static UCHAR __init
dc390_EEpromInDO( PDEVDECL
)
593 PCI_WRITE_CONFIG_BYTE(PDEV
, 0x80, 0x80);
595 PCI_WRITE_CONFIG_BYTE(PDEV
, 0x80, 0x40);
597 PCI_READ_CONFIG_BYTE(PDEV
, 0x00, &bval
);
605 static USHORT __init
dc390_EEpromGetData1( PDEVDECL
)
615 carryFlag
= dc390_EEpromInDO(PDEV
);
622 static void __init
dc390_Prepare( PDEVDECL
, PUCHAR regval
, UCHAR EEpromCmd
)
631 dc390_EEpromOutDI(PDEV
,regval
,carryFlag
);
632 carryFlag
= (EEpromCmd
& j
) ? 1 : 0;
638 static void __init
dc390_ReadEEprom( PDEVDECL
, PUSHORT ptr
)
644 for(i
=0; i
<0x40; i
++)
646 dc390_EnDisableCE(ENABLE_CE
, PDEV
, ®val
);
647 dc390_Prepare(PDEV
, ®val
, cmd
++);
648 *ptr
++ = dc390_EEpromGetData1(PDEV
);
649 dc390_EnDisableCE(DISABLE_CE
, PDEV
, ®val
);
654 static UCHAR __init
dc390_CheckEEpromCheckSum( PDEVDECL
, UCHAR index
)
658 USHORT wval
, *ptr
= (PUSHORT
)EEbuf
;
660 dc390_ReadEEprom( PDEV
, ptr
);
661 memcpy (dc390_eepromBuf
[index
], EEbuf
, EE_ADAPT_SCSI_ID
);
662 memcpy (&dc390_eepromBuf
[index
][EE_ADAPT_SCSI_ID
],
663 &EEbuf
[REAL_EE_ADAPT_SCSI_ID
], EE_LEN
- EE_ADAPT_SCSI_ID
);
665 for(i
=0; i
<0x40; i
++, ptr
++)
667 return (wval
== 0x1234 ? 0 : 1);
671 /***********************************************************************
672 * Functions for the management of the internal structures
673 * (DCBs, SRBs, Queueing)
675 **********************************************************************/
676 static PDCB __inline__
dc390_findDCB ( PACB pACB
, Scsi_Cmnd
*cmd
)
678 PDCB pDCB
= pACB
->pLinkDCB
; if (!pDCB
) return 0;
679 while (pDCB
->UnitSCSIID
!= cmd
->target
|| pDCB
->UnitSCSILUN
!= cmd
->lun
)
681 pDCB
= pDCB
->pNextDCB
;
682 if (pDCB
== pACB
->pLinkDCB
)
684 printk (KERN_WARNING
"DC390: DCB not found (DCB=%08x, DCBmap[%2x]=%2x)\n",
685 (int)pDCB
, cmd
->target
, pACB
->DCBmap
[cmd
->target
]);
689 DCBDEBUG1( printk (KERN_DEBUG
"DCB %08x (%02x,%02x) found.\n", \
690 (int)pDCB
, pDCB
->UnitSCSIID
, pDCB
->UnitSCSILUN
);)
694 static void dc390_QLinkcmd( PSCSICMD cmd
, PDCB pDCB
)
698 if( !pDCB
->QIORBCnt
)
700 pDCB
->pQIORBhead
= cmd
;
701 pDCB
->pQIORBtail
= cmd
;
707 pcmd
= pDCB
->pQIORBtail
;
709 pDCB
->pQIORBtail
= cmd
;
717 static __inline__ PSCSICMD
dc390_Getcmd( PDCB pDCB
)
721 pcmd
= pDCB
->pQIORBhead
;
722 pDCB
->pQIORBhead
= pcmd
->next
;
730 static __inline__ PSRB
dc390_GetSRB( PACB pACB
)
734 pSRB
= pACB
->pFreeSRB
;
737 pACB
->pFreeSRB
= pSRB
->pNextSRB
;
738 pSRB
->pNextSRB
= NULL
;
745 static __inline__
void dc390_RewaitSRB0( PDCB pDCB
, PSRB pSRB
)
749 if( (psrb1
= pDCB
->pWaitingSRB
) )
751 pSRB
->pNextSRB
= psrb1
;
755 pSRB
->pNextSRB
= NULL
;
756 pDCB
->pWaitLast
= pSRB
;
758 pDCB
->pWaitingSRB
= pSRB
;
762 static void dc390_RewaitSRB( PDCB pDCB
, PSRB pSRB
)
767 pDCB
->GoingSRBCnt
--; pDCB
->pDCBACB
->SelLost
++;
768 DEBUG0(printk(KERN_INFO
"DC390: RewaitSRB (%p, %p) pid = %li\n", pDCB
, pSRB
, pSRB
->pcmd
->pid
);)
769 psrb1
= pDCB
->pGoingSRB
;
772 pDCB
->pGoingSRB
= psrb1
->pNextSRB
;
776 while( pSRB
!= psrb1
->pNextSRB
)
777 psrb1
= psrb1
->pNextSRB
;
778 psrb1
->pNextSRB
= pSRB
->pNextSRB
;
779 if( pSRB
== pDCB
->pGoingLast
)
780 pDCB
->pGoingLast
= psrb1
;
782 if( (psrb1
= pDCB
->pWaitingSRB
) )
784 pSRB
->pNextSRB
= psrb1
;
785 pDCB
->pWaitingSRB
= pSRB
;
789 pSRB
->pNextSRB
= NULL
;
790 pDCB
->pWaitingSRB
= pSRB
;
791 pDCB
->pWaitLast
= pSRB
;
794 bval
= pSRB
->TagNumber
;
795 pDCB
->TagMask
&= (~(1 << bval
)); /* Free TAG number */
799 static void dc390_DoWaitingSRB( PACB pACB
)
804 if( !(pACB
->pActiveDCB
) && !(pACB
->ACBFlag
& (RESET_DETECT
+RESET_DONE
+RESET_DEV
) ) )
806 ptr
= pACB
->pDCBRunRobin
;
809 ptr
= pACB
->pLinkDCB
;
810 pACB
->pDCBRunRobin
= ptr
;
815 pACB
->pDCBRunRobin
= ptr1
->pNextDCB
;
816 if( !( ptr1
->MaxCommand
> ptr1
->GoingSRBCnt
) ||
817 !( pSRB
= ptr1
->pWaitingSRB
) )
819 if(pACB
->pDCBRunRobin
== ptr
)
821 ptr1
= ptr1
->pNextDCB
;
825 if( !dc390_StartSCSI(pACB
, ptr1
, pSRB
) )
828 if( ptr1
->pWaitLast
== pSRB
)
830 ptr1
->pWaitingSRB
= NULL
;
831 ptr1
->pWaitLast
= NULL
;
835 ptr1
->pWaitingSRB
= pSRB
->pNextSRB
;
837 pSRB
->pNextSRB
= NULL
;
839 if( ptr1
->pGoingSRB
)
840 ptr1
->pGoingLast
->pNextSRB
= pSRB
;
842 ptr1
->pGoingSRB
= pSRB
;
843 ptr1
->pGoingLast
= pSRB
;
853 static __inline__
void dc390_SRBwaiting( PDCB pDCB
, PSRB pSRB
)
855 if( pDCB
->pWaitingSRB
)
857 pDCB
->pWaitLast
->pNextSRB
= pSRB
;
858 pSRB
->pNextSRB
= NULL
;
862 pDCB
->pWaitingSRB
= pSRB
;
864 pDCB
->pWaitLast
= pSRB
;
868 /***********************************************************************
869 * Function: static void dc390_SendSRB (PACB pACB, PSRB pSRB)
871 * Purpose: Send SCSI Request Block (pSRB) to adapter (pACB)
873 ***********************************************************************/
875 static void dc390_SendSRB( PACB pACB
, PSRB pSRB
)
879 pDCB
= pSRB
->pSRBDCB
;
880 if( !(pDCB
->MaxCommand
> pDCB
->GoingSRBCnt
) || (pACB
->pActiveDCB
) ||
881 (pACB
->ACBFlag
& (RESET_DETECT
+RESET_DONE
+RESET_DEV
)) )
883 dc390_SRBwaiting(pDCB
, pSRB
);
887 if( pDCB
->pWaitingSRB
)
889 dc390_SRBwaiting(pDCB
, pSRB
);
890 /* pSRB = GetWaitingSRB(pDCB); */ /* non-existent */
891 pSRB
= pDCB
->pWaitingSRB
;
892 pDCB
->pWaitingSRB
= pSRB
->pNextSRB
;
893 pSRB
->pNextSRB
= NULL
;
896 if( !dc390_StartSCSI(pACB
, pDCB
, pSRB
) )
899 if( pDCB
->pGoingSRB
)
901 pDCB
->pGoingLast
->pNextSRB
= pSRB
;
902 pDCB
->pGoingLast
= pSRB
;
906 pDCB
->pGoingSRB
= pSRB
;
907 pDCB
->pGoingLast
= pSRB
;
911 dc390_RewaitSRB0( pDCB
, pSRB
);
917 /***********************************************************************
918 * Function: static void dc390_BuildSRB (Scsi_Cmd *pcmd, PDCB pDCB,
921 * Purpose: Prepare SRB for being sent to Device DCB w/ command *pcmd
923 ***********************************************************************/
925 static void dc390_BuildSRB (Scsi_Cmnd
* pcmd
, PDCB pDCB
, PSRB pSRB
)
927 pSRB
->pSRBDCB
= pDCB
;
929 pSRB
->ScsiCmdLen
= pcmd
->cmd_len
;
930 memcpy (pSRB
->CmdBlock
, pcmd
->cmnd
, pcmd
->cmd_len
);
934 pSRB
->SGcount
= (UCHAR
) pcmd
->use_sg
;
935 pSRB
->pSegmentList
= (PSGL
) pcmd
->request_buffer
;
937 else if( pcmd
->request_buffer
)
940 pSRB
->pSegmentList
= (PSGL
) &pSRB
->Segmentx
;
941 pSRB
->Segmentx
.address
= (PUCHAR
) pcmd
->request_buffer
;
942 pSRB
->Segmentx
.length
= pcmd
->request_bufflen
;
948 pSRB
->AdaptStatus
= 0;
949 pSRB
->TargetStatus
= 0;
951 if( pDCB
->DevType
!= TYPE_TAPE
)
958 pSRB
->TotalXferredLen
= 0;
960 pSRB
->SGToBeXferLen
= 0;
962 pSRB
->EndMessage
= 0;
966 /***********************************************************************
967 * Function : static int DC390_queue_command (Scsi_Cmnd *cmd,
968 * void (*done)(Scsi_Cmnd *))
970 * Purpose : enqueues a SCSI command
972 * Inputs : cmd - SCSI command, done - callback function called on
973 * completion, with a pointer to the command descriptor.
975 * Returns : (depending on kernel version)
976 * 2.0.x: always return 0
977 * 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x
979 * new model: return 0 if successful
980 * return 1 if command cannot be queued (queue full)
981 * command will be inserted in midlevel queue then ...
983 ***********************************************************************/
985 int DC390_queue_command (Scsi_Cmnd
*cmd
, void (* done
)(Scsi_Cmnd
*))
991 PACB pACB
= (PACB
) cmd
->host
->hostdata
;
994 DEBUG0(/* if(pACB->scan_devices) */ \
995 printk(KERN_INFO
"DC390: Queue Cmd=%02x,ID=%d,LUN=%d (pid=%li)\n",\
996 cmd
->cmnd
[0],cmd
->target
,cmd
->lun
,cmd
->pid
);)
1000 /* Assume BAD_TARGET; will be cleared later */
1001 cmd
->result
= DID_BAD_TARGET
<< 16;
1003 /* TODO: Change the policy: Alway accept TEST_UNIT_READY or INQUIRY
1004 * commands and alloc a DCB for the device if not yet there. DCB will
1005 * be removed in dc390_SRBdone if SEL_TIMEOUT */
1007 if( (pACB
->scan_devices
== END_SCAN
) && (cmd
->cmnd
[0] != INQUIRY
) )
1008 pACB
->scan_devices
= 0;
1010 else if( (pACB
->scan_devices
) && (cmd
->cmnd
[0] == READ_6
) )
1011 pACB
->scan_devices
= 0;
1013 if ( ( cmd
->target
>= pACB
->pScsiHost
->max_id
) ||
1014 (cmd
->lun
>= pACB
->pScsiHost
->max_lun
) )
1016 /* printk("DC390: Ignore target %d lun %d\n",
1017 cmd->target, cmd->lun); */
1023 if( (pACB
->scan_devices
|| cmd
->cmnd
[0] == TEST_UNIT_READY
) && !(pACB
->DCBmap
[cmd
->target
] & (1 << cmd
->lun
)) )
1025 pACB
->DCBmap
[cmd
->target
] |= (1 << cmd
->lun
);
1026 pACB
->scan_devices
= 1;
1028 dc390_initDCB( pACB
, &pDCB
, cmd
);
1031 printk (KERN_ERR
"DC390: kmalloc for DCB failed, ID=%2x\n", cmd
->target
);
1038 else if( !(pACB
->scan_devices
) && !(pACB
->DCBmap
[cmd
->target
] & (1 << cmd
->lun
)) )
1040 printk(KERN_INFO
"DC390: Ignore target %02x lun %02x\n",
1041 cmd
->target
, cmd
->lun
);
1048 pDCB
= dc390_findDCB (pACB
, cmd
);
1050 { /* should never happen */
1058 cmd
->scsi_done
= done
;
1061 if( pDCB
->QIORBCnt
) /* Unsent commands ? */
1063 dc390_QLinkcmd( cmd
, pDCB
);
1064 pcmd
= dc390_Getcmd( pDCB
); /* Get first command */
1070 pSRB
= dc390_GetSRB( pACB
);
1074 dc390_QLinkcmd( pcmd
, pDCB
); /* Queue command at the end */
1075 pACB
->CmdOutOfSRB
++;
1080 dc390_BuildSRB (pcmd
, pDCB
, pSRB
);
1081 dc390_SendSRB( pACB
, pSRB
);
1084 DEBUG1(printk (KERN_DEBUG
" ... command (%02x) queued successfully.\n", pcmd
->cmnd
[0]);)
1089 static void dc390_DoNextCmd( PACB pACB
, PDCB pDCB
)
1094 if( pACB
->ACBFlag
& (RESET_DETECT
+RESET_DONE
+RESET_DEV
) )
1097 pcmd
= dc390_Getcmd( pDCB
);
1098 pSRB
= dc390_GetSRB( pACB
);
1100 dc390_QLinkcmd( pcmd
, pDCB
);
1103 dc390_BuildSRB (pcmd
, pDCB
, pSRB
);
1104 dc390_SendSRB( pACB
, pSRB
);
1108 /* We ignore mapping problems, as we expect everybody to respect
1109 * valid partition tables. Waiting for complaints ;-) */
1111 #ifdef CONFIG_SCSI_DC390T_TRADMAP
1113 * The next function, partsize(), is copied from scsicam.c.
1115 * This is ugly code duplication, but I didn't find another way to solve it:
1116 * We want to respect the partition table and if it fails, we apply the
1117 * DC390 BIOS heuristic. Too bad, just calling scsicam_bios_param() doesn't do
1118 * the job, because we don't know, whether the values returned are from
1119 * the part. table or determined by setsize(). Unfortunately the setsize()
1120 * values differ from the ones chosen by the DC390 BIOS.
1122 * Looking forward to seeing suggestions for a better solution! KG, 98/10/14
1124 #include <asm/unaligned.h>
1127 * Function : static int partsize(struct buffer_head *bh, unsigned long
1128 * capacity,unsigned int *cyls, unsigned int *hds, unsigned int *secs);
1130 * Purpose : to determine the BIOS mapping used to create the partition
1131 * table, storing the results in *cyls, *hds, and *secs
1133 * Returns : -1 on failure, 0 on success.
1137 static int partsize(struct buffer_head
*bh
, unsigned long capacity
,
1138 unsigned int *cyls
, unsigned int *hds
, unsigned int *secs
) {
1139 struct partition
*p
, *largest
= NULL
;
1141 int cyl
, ext_cyl
, end_head
, end_cyl
, end_sector
;
1142 unsigned int logical_end
, physical_end
, ext_physical_end
;
1145 if (*(unsigned short *) (bh
->b_data
+510) == 0xAA55) {
1146 for (largest_cyl
= -1, p
= (struct partition
*)
1147 (0x1BE + bh
->b_data
), i
= 0; i
< 4; ++i
, ++p
) {
1150 cyl
= p
->cyl
+ ((p
->sector
& 0xc0) << 2);
1151 if (cyl
> largest_cyl
) {
1159 end_cyl
= largest
->end_cyl
+ ((largest
->end_sector
& 0xc0) << 2);
1160 end_head
= largest
->end_head
;
1161 end_sector
= largest
->end_sector
& 0x3f;
1163 physical_end
= end_cyl
* (end_head
+ 1) * end_sector
+
1164 end_head
* end_sector
+ end_sector
;
1166 /* This is the actual _sector_ number at the end */
1167 logical_end
= get_unaligned(&largest
->start_sect
)
1168 + get_unaligned(&largest
->nr_sects
);
1170 /* This is for >1023 cylinders */
1171 ext_cyl
= (logical_end
-(end_head
* end_sector
+ end_sector
))
1172 /(end_head
+ 1) / end_sector
;
1173 ext_physical_end
= ext_cyl
* (end_head
+ 1) * end_sector
+
1174 end_head
* end_sector
+ end_sector
;
1176 if ((logical_end
== physical_end
) ||
1177 (end_cyl
==1023 && ext_physical_end
==logical_end
)) {
1179 *hds
= end_head
+ 1;
1180 *cyls
= capacity
/ ((end_head
+ 1) * end_sector
);
1187 /***********************************************************************
1192 * Return the disk geometry for the given SCSI device.
1193 * Respect the partition table, otherwise try own heuristic
1196 * In contrary to other externally callable funcs (DC390_), we don't lock
1197 ***********************************************************************/
1198 int DC390_bios_param (Disk
*disk
, kdev_t devno
, int geom
[])
1200 int heads
, sectors
, cylinders
;
1201 PACB pACB
= (PACB
) disk
->device
->host
->hostdata
;
1202 struct buffer_head
*bh
;
1204 int size
= disk
->capacity
;
1206 if ((bh
= bread(MKDEV(MAJOR(devno
), MINOR(devno
)&~0xf), 0, 1024)))
1208 /* try to infer mapping from partition table */
1209 ret_code
= partsize (bh
, (unsigned long) size
, (unsigned int *) geom
+ 2,
1210 (unsigned int *) geom
+ 0, (unsigned int *) geom
+ 1);
1217 cylinders
= size
/ (heads
* sectors
);
1219 if ( (pACB
->Gmode2
& GREATER_1G
) && (cylinders
> 1024) )
1223 cylinders
= size
/ (heads
* sectors
);
1228 geom
[2] = cylinders
;
1234 int DC390_bios_param (Disk
*disk
, kdev_t devno
, int geom
[])
1236 return scsicam_bios_param (disk
, devno
, geom
);
1241 void dc390_dumpinfo (PACB pACB
, PDCB pDCB
, PSRB pSRB
)
1243 USHORT pstat
; PDEVDECL1
;
1247 printk ("DC390: SRB: Xferred %08lx, Remain %08lx, State %08lx, Phase %02x\n",
1248 pSRB
->TotalXferredLen
, pSRB
->SGToBeXferLen
, pSRB
->SRBState
,
1250 printk ("DC390: AdpaterStatus: %02x, SRB Status %02x\n", pSRB
->AdaptStatus
, pSRB
->SRBStatus
);
1252 printk ("DC390: Status of last IRQ (DMA/SC/Int/IRQ): %08lx\n", dc390_laststatus
);
1253 printk ("DC390: Register dump: SCSI block:\n");
1254 printk ("DC390: XferCnt Cmd Stat IntS IRQS FFIS Ctl1 Ctl2 Ctl3 Ctl4\n");
1255 printk ("DC390: %06x %02x %02x %02x",
1256 DC390_read8(CtcReg_Low
) + (DC390_read8(CtcReg_Mid
) << 8) + (DC390_read8(CtcReg_High
) << 16),
1257 DC390_read8(ScsiCmd
), DC390_read8(Scsi_Status
), DC390_read8(Intern_State
));
1258 printk (" %02x %02x %02x %02x %02x %02x\n",
1259 DC390_read8(INT_Status
), DC390_read8(Current_Fifo
), DC390_read8(CtrlReg1
),
1260 DC390_read8(CtrlReg2
), DC390_read8(CtrlReg3
), DC390_read8(CtrlReg4
));
1261 DC390_write32 (DMA_ScsiBusCtrl
, WRT_ERASE_DMA_STAT
| EN_INT_ON_PCI_ABORT
);
1262 printk ("DC390: Register dump: DMA engine:\n");
1263 printk ("DC390: Cmd STrCnt SBusA WrkBC WrkAC Stat SBusCtrl\n");
1264 printk ("DC390: %02x %08x %08x %08x %08x %02x %08x\n",
1265 DC390_read8(DMA_Cmd
), DC390_read32(DMA_XferCnt
), DC390_read32(DMA_XferAddr
),
1266 DC390_read32(DMA_Wk_ByteCntr
), DC390_read32(DMA_Wk_AddrCntr
),
1267 DC390_read8(DMA_Status
), DC390_read32(DMA_ScsiBusCtrl
));
1268 DC390_write32 (DMA_ScsiBusCtrl
, EN_INT_ON_PCI_ABORT
);
1269 PDEVSET1
; PCI_READ_CONFIG_WORD(PDEV
, PCI_STATUS
, &pstat
);
1270 printk ("DC390: Register dump: PCI Status: %04x\n", pstat
);
1271 printk ("DC390: In case of driver trouble read linux/drivers/scsi/README.tmscsim\n");
1275 /***********************************************************************
1276 * Function : int DC390_abort (Scsi_Cmnd *cmd)
1278 * Purpose : Abort an errant SCSI command
1280 * Inputs : cmd - command to abort
1282 * Returns : 0 on success, -1 on failure.
1285 ***********************************************************************/
1287 int DC390_abort (Scsi_Cmnd
*cmd
)
1292 PSCSICMD pcmd
, pcmd1
;
1296 PACB pACB
= (PACB
) cmd
->host
->hostdata
;
1300 pDCB
= dc390_findDCB (pACB
, cmd
);
1301 /* abort() is too buggy at the moment. If it's called we are in trouble anyway.
1302 * so let's dump some info into the syslog at least. (KG, 98/08/20) */
1303 if (pDCB
) pSRB
= pDCB
->pActiveSRB
; else pSRB
= 0;
1304 printk ("DC390: Abort command (pid %li, DCB %p, SRB %p)\n",
1305 cmd
->pid
, pDCB
, pSRB
);
1306 dc390_dumpinfo (pACB
, pDCB
, pSRB
);
1308 if( !pDCB
) goto NOT_RUN
;
1310 if( pDCB
->QIORBCnt
)
1312 pcmd
= pDCB
->pQIORBhead
;
1315 pDCB
->pQIORBhead
= pcmd
->next
;
1318 status
= SCSI_ABORT_SUCCESS
;
1321 for( count
= pDCB
->QIORBCnt
, i
=0; i
<count
-1; i
++)
1323 if( pcmd
->next
== cmd
)
1326 pcmd
->next
= pcmd1
->next
;
1329 status
= SCSI_ABORT_SUCCESS
;
1339 /* Added 98/07/02 KG */
1340 pSRB
= pDCB
->pActiveSRB
;
1341 if (pSRB
&& pSRB
->pcmd
== cmd
)
1344 pSRB
= pDCB
->pWaitingSRB
;
1347 if( pSRB
->pcmd
== cmd
)
1349 pDCB
->pWaitingSRB
= pSRB
->pNextSRB
;
1355 if( !(psrb
->pNextSRB
) )
1357 while( psrb
->pNextSRB
->pcmd
!= cmd
)
1359 psrb
= psrb
->pNextSRB
;
1360 if( !(psrb
->pNextSRB
) || psrb
== pSRB
)
1363 pSRB
= psrb
->pNextSRB
;
1364 psrb
->pNextSRB
= pSRB
->pNextSRB
;
1365 if( pSRB
== pDCB
->pWaitLast
)
1366 pDCB
->pWaitLast
= psrb
; /* No check for psrb == NULL ? */
1368 pSRB
->pNextSRB
= pACB
->pFreeSRB
;
1369 pACB
->pFreeSRB
= pSRB
;
1371 status
= SCSI_ABORT_SUCCESS
;
1376 pSRB
= pDCB
->pGoingSRB
;
1377 pDCB
->DCBFlag
|= ABORT_DEV_
;
1378 /* Now for the hard part: The command is currently processed */
1379 for( count
= pDCB
->GoingSRBCnt
, i
=0; i
<count
; i
++)
1381 if( pSRB
->pcmd
!= cmd
)
1382 pSRB
= pSRB
->pNextSRB
;
1385 if( (pACB
->pActiveDCB
== pDCB
) && (pDCB
->pActiveSRB
== pSRB
) )
1387 status
= SCSI_ABORT_BUSY
;
1388 printk ("DC390: Abort current command (pid %li, SRB %p)\n",
1394 status
= SCSI_ABORT_SNOOZE
;
1401 status
= SCSI_ABORT_NOT_RUNNING
;
1404 cmd
->result
= DID_ABORT
<< 16;
1405 printk(KERN_INFO
"DC390: Aborted pid %li with status %i\n", cmd
->pid
, status
);
1406 if (cmd
->pid
== dc390_lastabortedpid
) /* repeated failure ? */
1408 /* Let's do something to help the bus getting clean again */
1409 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
1410 DC390_write8 (ScsiCmd
, DMA_COMMAND
);
1411 //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1412 //DC390_write8 (ScsiCmd, RESET_ATN_CMD);
1413 DC390_write8 (ScsiCmd
, NOP_CMD
);
1415 //DC390_read8 (INT_Status);
1416 //DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1418 sbac
= DC390_read32 (DMA_ScsiBusCtrl
);
1419 if (sbac
& SCSI_BUSY
)
1420 { /* clear BSY, SEL and ATN */
1421 printk (KERN_WARNING
"DC390: Reset SCSI device: ");
1422 //DC390_write32 (DMA_ScsiBusCtrl, (sbac | SCAM) & ~SCSI_LINES);
1424 //sbac = DC390_read32 (DMA_ScsiBusCtrl);
1425 //printk ("%08lx ", sbac);
1426 //DC390_write32 (DMA_ScsiBusCtrl, sbac & ~(SCSI_LINES | SCAM));
1428 //sbac = DC390_read32 (DMA_ScsiBusCtrl);
1429 //printk ("%08lx ", sbac);
1430 DC390_write8 (ScsiCmd
, RST_DEVICE_CMD
);
1432 DC390_write8 (ScsiCmd
, NOP_CMD
);
1433 sbac
= DC390_read32 (DMA_ScsiBusCtrl
);
1434 printk ("%08lx\n", sbac
);
1436 dc390_lastabortedpid
= cmd
->pid
;
1438 //do_DC390_Interrupt (pACB->IRQLevel, 0, 0);
1439 cmd
->scsi_done(cmd
);
1444 static void dc390_ResetDevParam( PACB pACB
)
1448 pDCB
= pACB
->pLinkDCB
;
1453 pDCB
->SyncMode
&= ~SYNC_NEGO_DONE
;
1454 pDCB
->SyncPeriod
= 0;
1455 pDCB
->SyncOffset
= 0;
1456 pDCB
->CtrlR3
= FAST_CLK
;
1457 pDCB
->CtrlR4
&= NEGATE_REQACKDATA
| CTRL4_RESERVED
| NEGATE_REQACK
;
1458 pDCB
->CtrlR4
|= pACB
->glitch_cfg
;
1459 pDCB
= pDCB
->pNextDCB
;
1461 while( pdcb
!= pDCB
);
1465 static void dc390_RecoverSRB( PACB pACB
)
1471 pDCB
= pACB
->pLinkDCB
;
1476 cnt
= pdcb
->GoingSRBCnt
;
1477 psrb
= pdcb
->pGoingSRB
;
1478 for (i
=0; i
<cnt
; i
++)
1481 psrb
= psrb
->pNextSRB
;
1482 /* dc390_RewaitSRB( pDCB, psrb ); */
1483 if( pdcb
->pWaitingSRB
)
1485 psrb2
->pNextSRB
= pdcb
->pWaitingSRB
;
1486 pdcb
->pWaitingSRB
= psrb2
;
1490 pdcb
->pWaitingSRB
= psrb2
;
1491 pdcb
->pWaitLast
= psrb2
;
1492 psrb2
->pNextSRB
= NULL
;
1495 pdcb
->GoingSRBCnt
= 0;
1496 pdcb
->pGoingSRB
= NULL
;
1498 pdcb
= pdcb
->pNextDCB
;
1499 } while( pdcb
!= pDCB
);
1503 /***********************************************************************
1504 * Function : int DC390_reset (Scsi_Cmnd *cmd, ...)
1506 * Purpose : perform a hard reset on the SCSI bus
1508 * Inputs : cmd - command which caused the SCSI RESET
1510 * Returns : 0 on success.
1511 ***********************************************************************/
1513 int DC390_reset(Scsi_Cmnd
*cmd
, unsigned int resetFlags
)
1518 PACB pACB
= (PACB
) cmd
->host
->hostdata
;
1520 printk(KERN_INFO
"DC390: RESET ... ");
1523 bval
= DC390_read8 (CtrlReg1
);
1524 bval
|= DIS_INT_ON_SCSI_RST
;
1525 DC390_write8 (CtrlReg1
, bval
); /* disable interrupt */
1527 dc390_ResetSCSIBus( pACB
);
1529 for( i
=0; i
<600; i
++ )
1532 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1533 DC390_read8 (INT_Status
); /* Reset Pending INT */
1535 dc390_ResetDevParam( pACB
);
1536 dc390_DoingSRB_Done( pACB
);
1537 /* dc390_RecoverSRB (pACB); */
1538 pACB
->pActiveDCB
= NULL
;
1541 bval
= DC390_read8 (CtrlReg1
);
1542 bval
&= ~DIS_INT_ON_SCSI_RST
;
1543 DC390_write8 (CtrlReg1
, bval
); /* re-enable interrupt */
1545 dc390_DoWaitingSRB( pACB
);
1549 return( SCSI_RESET_SUCCESS
);
1552 #include "scsiiom.c"
1555 /***********************************************************************
1556 * Function : static void dc390_initDCB()
1558 * Purpose : initialize the internal structures for a given DCB
1560 * Inputs : cmd - pointer to this scsi cmd request block structure
1561 ***********************************************************************/
1563 void dc390_initDCB( PACB pACB
, PDCB
*ppDCB
, PSCSICMD cmd
)
1569 pDCB
= kmalloc (sizeof(DC390_DCB
), GFP_ATOMIC
);
1570 DCBDEBUG(printk (KERN_INFO
"DC390: alloc mem for DCB (ID %i, LUN %i): 0x%08x\n", \
1571 cmd
->target
, cmd
->lun
, (int)pDCB
);)
1575 if( pACB
->DCBCnt
== 0 )
1577 pACB
->pLinkDCB
= pDCB
;
1578 pACB
->pDCBRunRobin
= pDCB
;
1582 pACB
->pLastDCB
->pNextDCB
= pDCB
;
1587 pACB
->pLastDCB
= pDCB
;
1588 pDCB
->pNextDCB
= pACB
->pLinkDCB
;
1590 pDCB
->pDCBACB
= pACB
;
1592 pDCB
->UnitSCSIID
= cmd
->target
;
1593 pDCB
->UnitSCSILUN
= cmd
->lun
;
1594 pDCB
->pWaitingSRB
= NULL
;
1595 pDCB
->pGoingSRB
= NULL
;
1596 pDCB
->GoingSRBCnt
= 0;
1597 pDCB
->pActiveSRB
= NULL
;
1599 pDCB
->MaxCommand
= 1;
1600 index
= pACB
->AdapterIndex
;
1603 prom
= (PEEprom
) &dc390_eepromBuf
[index
][cmd
->target
<< 2];
1604 pDCB
->DevMode
= prom
->EE_MODE1
;
1607 dc390_updateDCB(pACB
, pDCB
);
1609 pDCB
->SyncPeriod
= 0;
1610 pDCB
->SyncOffset
= 0;
1611 pDCB
->NegoPeriod
= (dc390_clock_period1
[prom
->EE_SPEED
] * 25) >> 2;
1613 pDCB
->CtrlR3
= FAST_CLK
;
1615 pDCB
->CtrlR4
= pACB
->glitch_cfg
| CTRL4_RESERVED
;
1616 if( dc390_eepromBuf
[index
][EE_MODE2
] & ACTIVE_NEGATION
)
1617 pDCB
->CtrlR4
|= NEGATE_REQACKDATA
| NEGATE_REQACK
;
1620 /***********************************************************************
1621 * Function : static void dc390_updateDCB()
1623 * Purpose : Set the configuration dependent DCB parameters
1624 ***********************************************************************/
1626 void dc390_updateDCB (PACB pACB
, PDCB pDCB
)
1628 pDCB
->IdentifyMsg
= IDENTIFY (pDCB
->DevMode
& EN_DISCONNECT_
, pDCB
->UnitSCSILUN
);
1630 if (pDCB
->DevMode
& TAG_QUEUEING_
) pDCB
->SyncMode
&= EN_TAG_QUEUEING
| SYNC_NEGO_DONE
| EN_ATN_STOP
;
1631 else pDCB
->SyncMode
&= SYNC_NEGO_DONE
| EN_ATN_STOP
;
1633 if( pDCB
->DevMode
& SYNC_NEGO_
&& (!(pDCB
->UnitSCSILUN
) || dc390_CurrSyncOffset
) )
1634 pDCB
->SyncMode
|= SYNC_ENABLE
;
1637 pDCB
->SyncMode
&= ~(SYNC_NEGO_DONE
| SYNC_ENABLE
);
1638 pDCB
->SyncOffset
&= ~0x0f;
1641 if (! (pDCB
->DevMode
& EN_DISCONNECT_
)) pDCB
->SyncMode
&= ~EN_ATN_STOP
;
1643 pDCB
->CtrlR1
= pACB
->pScsiHost
->this_id
;
1644 if( pDCB
->DevMode
& PARITY_CHK_
)
1645 pDCB
->CtrlR1
|= PARITY_ERR_REPO
;
1649 /***********************************************************************
1650 * Function : static void dc390_updateDCBs ()
1652 * Purpose : Set the configuration dependent DCB params for all DCBs
1653 ***********************************************************************/
1655 static void dc390_updateDCBs (PACB pACB
)
1658 PDCB pDCB
= pACB
->pLinkDCB
;
1659 for (i
= 0; i
< pACB
->DeviceCnt
; i
++)
1661 dc390_updateDCB (pACB
, pDCB
);
1662 pDCB
= pDCB
->pNextDCB
;
1667 /***********************************************************************
1668 * Function : static void dc390_initSRB()
1670 * Purpose : initialize the internal structures for a given SRB
1672 * Inputs : psrb - pointer to this scsi request block structure
1673 ***********************************************************************/
1675 static void __inline__
dc390_initSRB( PSRB psrb
)
1677 /* psrb->PhysSRB = virt_to_phys( psrb ); */
1681 void dc390_linkSRB( PACB pACB
)
1685 count
= pACB
->SRBCount
;
1686 for( i
=0; i
< count
; i
++)
1689 pACB
->SRB_array
[i
].pNextSRB
= &pACB
->SRB_array
[i
+1];
1691 pACB
->SRB_array
[i
].pNextSRB
= NULL
;
1692 dc390_initSRB( &pACB
->SRB_array
[i
] );
1697 /***********************************************************************
1698 * Function : static void dc390_initACB ()
1700 * Purpose : initialize the internal structures for a given SCSI host
1702 * Inputs : psh - pointer to this host adapter's structure
1703 * io_port, Irq, index: Resources and adapter index
1704 ***********************************************************************/
1706 void __init
dc390_initACB (PSH psh
, ULONG io_port
, UCHAR Irq
, UCHAR index
)
1712 psh
->can_queue
= MAX_CMD_QUEUE
;
1713 psh
->cmd_per_lun
= MAX_CMD_PER_LUN
;
1714 psh
->this_id
= (int) dc390_eepromBuf
[index
][EE_ADAPT_SCSI_ID
];
1715 psh
->io_port
= io_port
;
1716 psh
->n_io_port
= 0x80;
1719 pACB
= (PACB
) psh
->hostdata
;
1723 pACB
->pScsiHost
= psh
;
1724 pACB
->IOPortBase
= (USHORT
) io_port
;
1725 pACB
->IRQLevel
= Irq
;
1727 DEBUG0(printk (KERN_INFO
"DC390: Adapter index %i, ID %i, IO 0x%08x, IRQ 0x%02x\n", \
1728 index
, psh
->this_id
, (int)io_port
, Irq
);)
1732 if( psh
->max_id
- 1 == dc390_eepromBuf
[index
][EE_ADAPT_SCSI_ID
] )
1735 if( dc390_eepromBuf
[index
][EE_MODE2
] & LUN_CHECK
)
1738 pACB
->pLinkDCB
= NULL
;
1739 pACB
->pDCBRunRobin
= NULL
;
1740 pACB
->pActiveDCB
= NULL
;
1741 pACB
->pFreeSRB
= pACB
->SRB_array
;
1742 pACB
->SRBCount
= MAX_SRB_CNT
;
1743 pACB
->AdapterIndex
= index
;
1745 psh
->this_id
= dc390_eepromBuf
[index
][EE_ADAPT_SCSI_ID
];
1746 pACB
->DeviceCnt
= 0;
1748 pACB
->TagMaxNum
= 2 << dc390_eepromBuf
[index
][EE_TAG_CMD_NUM
];
1750 pACB
->scan_devices
= 1;
1752 pACB
->Ignore_IRQ
= 0;
1753 pACB
->Gmode2
= dc390_eepromBuf
[index
][EE_MODE2
];
1754 dc390_linkSRB( pACB
);
1755 pACB
->pTmpSRB
= &pACB
->TmpSRB
;
1756 dc390_initSRB( pACB
->pTmpSRB
);
1757 for(i
=0; i
<MAX_SCSI_ID
; i
++)
1758 pACB
->DCBmap
[i
] = 0;
1759 pACB
->sel_timeout
= SEL_TIMEOUT
;
1760 pACB
->glitch_cfg
= EATER_25NS
;
1761 pACB
->Cmds
= pACB
->CmdInQ
= pACB
->CmdOutOfSRB
= pACB
->SelLost
= 0;
1765 /***********************************************************************
1766 * Function : static int dc390_initAdapter ()
1768 * Purpose : initialize the SCSI chip ctrl registers
1770 * Inputs : psh - pointer to this host adapter's structure
1771 * io_port, Irq, index: Resources
1773 * Outputs: 0 on success, -1 on error
1774 ***********************************************************************/
1776 int __init
dc390_initAdapter (PSH psh
, ULONG io_port
, UCHAR Irq
, UCHAR index
)
1779 UCHAR used_irq
= 0, dstate
;
1782 pACB
= (PACB
) psh
->hostdata
;
1784 for ( pACB2
= dc390_pACB_start
; pACB2
; )
1786 if( pACB2
->IRQLevel
== Irq
)
1792 pACB2
= pACB2
->pNextACB
;
1795 if (check_region (io_port
, psh
->n_io_port
))
1797 printk(KERN_ERR
"DC390: register IO ports error!\n");
1801 request_region (io_port
, psh
->n_io_port
, "tmscsim");
1803 DC390_read8_ (INT_Status
, io_port
); /* Reset Pending INT */
1807 if( (i
= request_irq(Irq
, do_DC390_Interrupt
, DC390_IRQ
, "tmscsim", NULL
) ))
1809 printk(KERN_ERR
"DC390: register IRQ error!\n");
1814 if( !dc390_pACB_start
)
1817 dc390_pACB_start
= pACB
;
1818 dc390_pACB_current
= pACB
;
1819 pACB
->pNextACB
= NULL
;
1823 pACB2
= dc390_pACB_current
;
1824 dc390_pACB_current
->pNextACB
= pACB
;
1825 dc390_pACB_current
= pACB
;
1826 pACB
->pNextACB
= NULL
;
1829 DC390_write8 (CtrlReg1
, DIS_INT_ON_SCSI_RST
| psh
->this_id
); /* Disable SCSI bus reset interrupt */
1831 if (pACB
->Gmode2
& RST_SCSI_BUS
)
1833 dc390_ResetSCSIBus( pACB
);
1834 /* Unlock before ? */
1835 for( i
=0; i
<600; i
++ )
1839 DC390_read8 (INT_Status
); /* Reset Pending INT */
1841 DC390_write8 (Scsi_TimeOut
, SEL_TIMEOUT
); /* 250ms selection timeout */
1842 DC390_write8 (Clk_Factor
, CLK_FREQ_40MHZ
); /* Conversion factor = 0 , 40MHz clock */
1843 DC390_write8 (ScsiCmd
, NOP_CMD
); /* NOP cmd - clear command register */
1844 DC390_write8 (CtrlReg2
, EN_FEATURE
+EN_SCSI2_CMD
); /* Enable Feature and SCSI-2 */
1845 DC390_write8 (CtrlReg3
, FAST_CLK
); /* fast clock */
1846 DC390_write8 (CtrlReg4
, pACB
->glitch_cfg
| /* glitch eater */
1847 (dc390_eepromBuf
[index
][EE_MODE2
] & ACTIVE_NEGATION
) ? NEGATE_REQACKDATA
: 0); /* Negation */
1848 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
1849 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1850 DC390_write32 (DMA_ScsiBusCtrl
, EN_INT_ON_PCI_ABORT
);
1851 dstate
= DC390_read8 (DMA_Status
);
1852 DC390_write8 (DMA_Status
, dstate
); /* clear */
1858 /***********************************************************************
1859 * Function : static int DC390_init (struct Scsi_Host *host, ...)
1861 * Purpose : initialize the internal structures for a given SCSI host
1863 * Inputs : host - pointer to this host adapter's structure
1864 * io_port - IO ports mapped to this adapter
1865 * Irq - IRQ assigned to this adpater
1866 * PDEVDECL - PCI access handle
1867 * index - Adapter index
1869 * Outputs: 0 on success, -1 on error
1871 * Note: written in capitals, because the locking is only done here,
1872 * not in DC390_detect, called from outside
1873 ***********************************************************************/
1875 static int __init
DC390_init (PSHT psht
, ULONG io_port
, UCHAR Irq
, PDEVDECL
, UCHAR index
)
1881 if (dc390_CheckEEpromCheckSum (PDEV
, index
))
1883 #ifdef CONFIG_SCSI_DC390T_NOGENSUPP
1884 printk (KERN_ERR
"DC390_init: No EEPROM found!\n");
1888 printk (KERN_INFO
"DC390_init: No EEPROM found!\n");
1889 printk (KERN_INFO
"DC390_init: Trying default EEPROM settings:\n");
1890 dc390_checkparams ();
1891 period
= dc390_clock_period1
[tmscsim
[1]];
1892 printk (KERN_INFO
"DC390: Used defaults: AdaptID=%i, SpeedIdx=%i (%i.%i MHz),"
1893 " DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i)\n", tmscsim
[0], tmscsim
[1],
1894 40 / period
, ((40%period
)*10 + period
/2) / period
,
1895 (UCHAR
)tmscsim
[2], (UCHAR
)tmscsim
[3], tmscsim
[4], 2 << (tmscsim
[4]));
1896 dc390_EEpromDefaults (index
);
1900 psh
= scsi_register( psht
, sizeof(DC390_ACB
) );
1901 if( !psh
) return( -1 );
1903 pACB
= (PACB
) psh
->hostdata
;
1908 if( !dc390_pSH_start
)
1910 dc390_pSH_start
= psh
;
1911 dc390_pSH_current
= psh
;
1915 dc390_pSH_current
->next
= psh
;
1916 dc390_pSH_current
= psh
;
1920 DEBUG0(printk(KERN_INFO
"DC390: pSH = %8x,", (UINT
) psh
);)
1921 DEBUG0(printk(" Index %02i,", index
);)
1923 dc390_initACB( psh
, io_port
, Irq
, index
);
1924 pACB
= (PACB
) psh
->hostdata
;
1928 if( !dc390_initAdapter( psh
, io_port
, Irq
, index
) )
1930 DEBUG0(printk("\nDC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
1931 (UINT
) pACB
, (UINT
) pACB
->DCBmap
, (UINT
) pACB
->SRB_array
);)
1932 DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\
1933 sizeof(DC390_ACB
), sizeof(DC390_DCB
), sizeof(DC390_SRB
) );)
1940 //dc390_pSH_start = NULL;
1941 scsi_unregister( psh
);
1948 /***********************************************************************
1949 * Function : int DC390_detect(Scsi_Host_Template *psht)
1951 * Purpose : detects and initializes AMD53C974 SCSI chips
1952 * that were autoprobed, overridden on the LILO command line,
1953 * or specified at compile time.
1955 * Inputs : psht - template for this SCSI adapter
1957 * Returns : number of host adapters detected
1959 ***********************************************************************/
1962 /* Acc. to PCI 2.1 spec it's up to the driver to enable Bus mastering:
1963 * We use pci_set_master () for 2.1.x and this func for 2.0.x: */
1964 static void __init
dc390_set_master (PDEVDECL
)
1969 PCI_READ_CONFIG_WORD (PDEV
, PCI_COMMAND
, &cmd
);
1971 if (! (cmd
& PCI_COMMAND_MASTER
)) {
1972 printk("PCI: Enabling bus mastering for device %02x:%02x\n",
1974 cmd
|= PCI_COMMAND_MASTER
;
1975 PCI_WRITE_CONFIG_WORD(PDEV
, PCI_COMMAND
, cmd
);
1977 PCI_READ_CONFIG_BYTE (PDEV
, PCI_LATENCY_TIMER
, &lat
);
1978 if (lat
< 16 /* || lat == 255 */) {
1979 printk("PCI: Setting latency timer of device %02x:%02x from %i to 64\n",
1981 PCI_WRITE_CONFIG_BYTE(PDEV
, PCI_LATENCY_TIMER
, 64);
1985 #endif /* ! NEW_PCI */
1987 static void __init
dc390_set_pci_cfg (PDEVDECL
)
1990 PCI_READ_CONFIG_WORD (PDEV
, PCI_COMMAND
, &cmd
);
1991 cmd
|= PCI_COMMAND_SERR
| PCI_COMMAND_PARITY
| PCI_COMMAND_IO
;
1992 PCI_WRITE_CONFIG_WORD (PDEV
, PCI_COMMAND
, cmd
);
1993 PCI_WRITE_CONFIG_WORD (PDEV
, PCI_STATUS
, (PCI_STATUS_SIG_SYSTEM_ERROR
| PCI_STATUS_DETECTED_PARITY
));
1997 int __init
DC390_detect (Scsi_Host_Template
*psht
)
2002 DC390_IFLAGS DC390_DFLAGS
2005 //dc390_pSHT_start = psht;
2006 dc390_pACB_start
= NULL
;
2009 while (PCI_FIND_DEVICE (PCI_VENDOR_ID_AMD
, PCI_DEVICE_ID_AMD53C974
))
2011 DC390_LOCK_IO
; /* Remove this when going to new eh */
2013 DEBUG0(printk(KERN_INFO
"DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt
, (UINT
) io_port
, irq
);)
2015 if( !DC390_init(psht
, io_port
, irq
, PDEV
, dc390_adapterCnt
))
2018 dc390_set_pci_cfg (PDEV
);
2021 DC390_UNLOCK_IO
; /* Remove when going to new eh */
2024 printk (KERN_ERR
"DC390: No PCI BIOS found!\n");
2026 if (dc390_adapterCnt
)
2027 psht
->proc_dir
= &DC390_proc_scsi_tmscsim
;
2029 printk(KERN_INFO
"DC390: %i adapters found\n", dc390_adapterCnt
);
2031 return( dc390_adapterCnt
);
2035 /***********************************************************************
2036 * Functions: dc390_inquiry(), dc390_inquiry_done()
2038 * Purpose: When changing speed etc., we have to issue an INQUIRY
2039 * command to make sure, we agree upon the nego parameters
2041 ***********************************************************************/
2043 static void dc390_inquiry_done (Scsi_Cmnd
* cmd
)
2045 printk (KERN_INFO
"DC390: INQUIRY (ID %02x LUN %02x) returned %08x\n",
2046 cmd
->target
, cmd
->lun
, cmd
->result
);
2049 PACB pACB
= (PACB
)cmd
->host
->hostdata
;
2050 PDCB pDCB
= dc390_findDCB (pACB
, cmd
);
2051 printk ("DC390: Unsetting DsCn, Sync and TagQ!\n");
2054 pDCB
->DevMode
&= ~(SYNC_NEGO_
| TAG_QUEUEING_
| EN_DISCONNECT_
);
2055 dc390_updateDCB (pACB
, pDCB
);
2058 kfree (cmd
->buffer
);
2062 void dc390_inquiry (PACB pACB
, PDCB pDCB
)
2066 buffer
= kmalloc (256, GFP_ATOMIC
);
2067 cmd
= kmalloc (sizeof (Scsi_Cmnd
), GFP_ATOMIC
);
2069 memset (buffer
, 0, 256);
2070 memset (cmd
, 0, sizeof(Scsi_Cmnd
));
2071 cmd
->cmnd
[0] = INQUIRY
;
2072 cmd
->cmnd
[1] = (pDCB
->UnitSCSILUN
<< 5) & 0xe0;
2073 cmd
->cmnd
[4] = 0xff;
2075 cmd
->cmd_len
= 6; cmd
->old_cmd_len
= 6;
2076 cmd
->host
= pACB
->pScsiHost
;
2077 cmd
->target
= pDCB
->UnitSCSIID
;
2078 cmd
->lun
= pDCB
->UnitSCSILUN
;
2079 cmd
->serial_number
= 1;
2081 cmd
->buffer
= buffer
;
2082 cmd
->request_bufflen
= 128;
2083 cmd
->request_buffer
= &buffer
[128];
2084 cmd
->done
= dc390_inquiry_done
;
2085 cmd
->scsi_done
= dc390_inquiry_done
;
2086 cmd
->timeout_per_command
= HZ
;
2088 cmd
->request
.rq_status
= RQ_SCSI_BUSY
;
2090 printk (KERN_INFO
"DC390: Queue INQUIRY command to dev ID %02x LUN %02x\n",
2091 pDCB
->UnitSCSIID
, pDCB
->UnitSCSILUN
);
2092 DC390_queue_command (cmd
, dc390_inquiry_done
);
2095 /********************************************************************
2096 * Function: dc390_set_info()
2098 * Purpose: Change adapter config
2100 * Strings are parsed similar to the output of tmscsim_proc_info ()
2101 * '-' means no change
2102 *******************************************************************/
2104 static int dc390_scanf (char** p1
, char** p2
, int* var
)
2107 *var
= simple_strtoul (*p2
, p1
, 10);
2108 if (*p2
== *p1
) return -1;
2109 *p1
= strtok (0, " \t\n:=,;.");
2113 #define SCANF(p1, p2, var, min, max) \
2114 if (dc390_scanf (&p1, &p2, &var)) goto einv; \
2115 else if (var<min || var>max) goto einv2
2117 static int dc390_yesno (char** p
, char* var
, char bmask
)
2121 case 'Y': *var
|= bmask
; break;
2122 case 'N': *var
&= ~bmask
; break;
2126 *p
= strtok (0, " \t\n:=,;");
2130 #define YESNO(p, var, bmask) \
2131 if (dc390_yesno (&p, &var, bmask)) goto einv; \
2132 else dc390_updateDCB (pACB, pDCB); \
2135 static int dc390_search (char **p1
, char **p2
, char *var
, char* txt
, int max
, int scale
, char* ign
)
2138 if (! memcmp (*p1
, txt
, strlen(txt
)))
2140 *p2
= strtok (0, " \t\n:=,;");
2141 if (!*p2
) return -1;
2142 dum
= simple_strtoul (*p2
, p1
, 10);
2143 if (*p2
== *p1
) return -1;
2144 if (dum
>= 0 && dum
<= max
)
2145 { *var
= (dum
* 100) / scale
; }
2147 *p1
= strtok (0, " \t\n:=,;");
2148 if (*ign
&& *p1
&& strlen(*p1
) >= strlen(ign
) &&
2149 !(memcmp (*p1
, ign
, strlen(ign
))))
2150 *p1
= strtok (0, " \t\n:=,;");
2156 #define SEARCH(p1, p2, var, txt, max) \
2157 if (dc390_search (&p1, &p2, (PUCHAR)(&var), txt, max, 100, "")) goto einv2; \
2158 else if (!p1) goto ok2
2160 #define SEARCH2(p1, p2, var, txt, max, scale) \
2161 if (dc390_search (&p1, &p2, &var, txt, max, scale, "")) goto einv2; \
2162 else if (!p1) goto ok2
2164 #define SEARCH3(p1, p2, var, txt, max, scale, ign) \
2165 if (dc390_search (&p1, &p2, &var, txt, max, scale, ign)) goto einv2; \
2166 else if (!p1) goto ok2
2169 #ifdef DC390_PARSEDEBUG
2170 static char _prstr
[256];
2171 char* prstr (char* p
, char* e
)
2175 if (*p
== 0) { *c
++ = ':'; p
++; }
2176 else if (*p
== 10) { *c
++ = '\\'; *c
++ = 'n'; p
++; }
2183 int dc390_set_info (char *buffer
, int length
, PACB pACB
)
2185 char *pos
= buffer
, *p0
= buffer
;
2186 char needs_inquiry
= 0;
2189 PDCB pDCB
= pACB
->pLinkDCB
;
2197 /* Don't use kernel toupper, because of 2.0.x bug: ctmp unexported */
2199 { if (*pos
>='a' && *pos
<= 'z') *pos
= *pos
+ 'A' - 'a'; pos
++; };
2201 /* We should protect __strtok ! */
2202 /* spin_lock (strtok_lock); */
2205 pos
= strtok (buffer
, " \t:\n=,;");
2209 if (!memcmp (pos
, "RESET", 5)) goto reset
;
2210 else if (!memcmp (pos
, "INQUIRY", 7)) goto inquiry
;
2211 else if (!memcmp (pos
, "REMOVE", 6)) goto remove
;
2215 /* Device config line */
2216 int dev
, id
, lun
; char* pdec
;
2219 SCANF (pos
, p0
, dev
, 0, pACB
->DCBCnt
-1);
2220 if (pos
) { SCANF (pos
, p0
, id
, 0, 7); } else goto einv
;
2221 if (pos
) { SCANF (pos
, p0
, lun
, 0, 7); } else goto einv
;
2222 if (!pos
) goto einv
;
2224 PARSEDEBUG(printk (KERN_INFO
"DC390: config line %i %i %i:\"%s\"\n", dev
, id
, lun
, prstr (pos
, &buffer
[length
]));)
2225 pDCB
= pACB
->pLinkDCB
;
2226 for (dum
= 0; dum
< dev
; dum
++) pDCB
= pDCB
->pNextDCB
;
2228 if (pDCB
->UnitSCSIID
!= id
|| pDCB
->UnitSCSILUN
!= lun
)
2230 printk (KERN_ERR
"DC390: no such device: Idx=%02i ID=%02i LUN=%02i\n",
2235 olddevmode
= pDCB
->DevMode
;
2236 YESNO (pos
, pDCB
->DevMode
, PARITY_CHK_
);
2238 YESNO (pos
, pDCB
->DevMode
, SYNC_NEGO_
);
2239 if ((olddevmode
& SYNC_NEGO_
) == (pDCB
->DevMode
& SYNC_NEGO_
)) needs_inquiry
--;
2241 YESNO (pos
, pDCB
->DevMode
, EN_DISCONNECT_
);
2242 if ((olddevmode
& EN_DISCONNECT_
) == (pDCB
->DevMode
& EN_DISCONNECT_
)) needs_inquiry
--;
2243 YESNO (pos
, pDCB
->DevMode
, SEND_START_
);
2245 YESNO (pos
, pDCB
->DevMode
, TAG_QUEUEING_
);
2246 if ((olddevmode
& TAG_QUEUEING_
) == (pDCB
->DevMode
& TAG_QUEUEING_
)) needs_inquiry
--;
2247 YESNO (pos
, pDCB
->SyncMode
, EN_ATN_STOP
);
2249 dc390_updateDCB (pACB
, pDCB
);
2252 olddevmode
= pDCB
->NegoPeriod
;
2253 /* Look for decimal point (Speed) */
2255 while (pdec
++ < &buffer
[length
]) if (*pdec
== '.') break;
2259 SCANF (pos
, p0
, dum
, 72, 800);
2260 pDCB
->NegoPeriod
= dum
>> 2;
2261 if (pDCB
->NegoPeriod
!= olddevmode
) needs_inquiry
++;
2263 if (memcmp (pos
, "NS", 2) == 0) pos
= strtok (0, " \t\n:=,;.");
2265 else pos
= strtok (0, " \t\n:=,;.");
2268 /* Speed: NegoPeriod */
2271 SCANF (pos
, p0
, dum
, 1, 13);
2272 pDCB
->NegoPeriod
= (1000/dum
) >> 2;
2273 if (pDCB
->NegoPeriod
!= olddevmode
&& !pos
) needs_inquiry
++;
2279 dum
= simple_strtoul (pos
, &p0
, 10) * 10;
2280 for (; p0
-pos
> 1; p0
--) dum
/= 10;
2281 pDCB
->NegoPeriod
= (100000/(100*dumold
+ dum
)) >> 2;
2282 if (pDCB
->NegoPeriod
< 19) pDCB
->NegoPeriod
= 19;
2283 if (pDCB
->NegoPeriod
!= olddevmode
) needs_inquiry
++;
2284 pos
= strtok (0, " \t\n:=,;");
2287 if (*pos
== 'M') pos
= strtok (0, " \t\n:=,;");
2289 else pos
= strtok (0, " \t\n:=,;");
2290 /* dc390_updateDCB (pACB, pDCB); */
2293 olddevmode
= pDCB
->SyncOffset
;
2297 SCANF (pos
, p0
, dum
, 0, 0x0f);
2298 pDCB
->SyncOffset
= dum
;
2299 if (pDCB
->SyncOffset
> olddevmode
) needs_inquiry
++;
2301 else pos
= strtok (0, " \t\n:=,;");
2302 dc390_updateDCB (pACB
, pDCB
);
2306 char* p1
= pos
; UCHAR dum
;
2307 PARSEDEBUG(printk (KERN_INFO
"DC390: chg adapt cfg \"%s\"\n", prstr (pos
, &buffer
[length
]));)
2308 dum
= GLITCH_TO_NS (pACB
->glitch_cfg
);
2309 /* Adapter setting */
2310 SEARCH (pos
, p0
, pACB
->pScsiHost
->max_id
, "MAXID", 8);
2311 SEARCH (pos
, p0
, pACB
->pScsiHost
->max_lun
, "MAXLUN", 8);
2312 SEARCH (pos
, p0
, pACB
->pScsiHost
->this_id
, "ADAPTERID", 7);
2313 SEARCH (pos
, p0
, pACB
->TagMaxNum
, "TAGMAXNUM", 32);
2314 SEARCH (pos
, p0
, pACB
->ACBFlag
, "ACBFLAG", 255);
2315 SEARCH3 (pos
, p0
, dum
, "GLITCHEATER", 40, 1000, "NS");
2316 SEARCH3 (pos
, p0
, pACB
->sel_timeout
, "SELTIMEOUT", 400, 163, "MS");
2318 pACB
->glitch_cfg
= NS_TO_GLITCH (dum
);
2319 if (pACB
->sel_timeout
< 60) pACB
->sel_timeout
= 60;
2320 dum
= 0; while (1 << dum
<= pACB
->TagMaxNum
) dum
++;
2321 pACB
->TagMaxNum
&= (1 << --dum
);
2322 if (pos
== p1
) goto einv
;
2323 dc390_updateDCBs (pACB
);
2328 /* spin_unlock (strtok_lock); */
2331 { dc390_updateDCB (pACB
, pDCB
); dc390_inquiry (pACB
, pDCB
); };
2338 /* spin_unlock (strtok_lock); */
2341 printk (KERN_WARNING
"DC390: parse error near \"%s\"\n", (pos
? pos
: "NULL"));
2346 Scsi_Cmnd cmd
; cmd
.host
= pACB
->pScsiHost
;
2347 printk (KERN_WARNING
"DC390: Driver reset requested!\n");
2349 DC390_reset (&cmd
, 0);
2356 pos
= strtok (0, " \t\n.:;="); if (!pos
) goto einv
;
2357 dev
= simple_strtoul (pos
, &p0
, 10);
2358 if (dev
>= pACB
->DCBCnt
) goto einv_dev
;
2359 for (dum
= 0; dum
< dev
; dum
++) pDCB
= pDCB
->pNextDCB
;
2360 printk (KERN_NOTICE
" DC390: Issue INQUIRY command to Dev(Idx) %i SCSI ID %i LUN %i\n",
2361 dev
, pDCB
->UnitSCSIID
, pDCB
->UnitSCSILUN
);
2363 dc390_inquiry (pACB
, pDCB
);
2370 pos
= strtok (0, " \t\n.:;="); if (!pos
) goto einv
;
2371 dev
= simple_strtoul (pos
, &p0
, 10);
2372 if (dev
>= pACB
->DCBCnt
) goto einv_dev
;
2373 for (dum
= 0; dum
< dev
; dum
++) pDCB
= pDCB
->pNextDCB
;
2374 printk (KERN_NOTICE
" DC390: Remove DCB for Dev(Idx) %i SCSI ID %i LUN %i\n",
2375 dev
, pDCB
->UnitSCSIID
, pDCB
->UnitSCSILUN
);
2376 dc390_remove_dev (pACB
, pDCB
);
2383 printk (KERN_WARNING
"DC390: Ignore cmnd to illegal Dev(Idx) %i. Valid range: 0 - %i.\n",
2384 dev
, pACB
->DCBCnt
- 1);
2396 /********************************************************************
2397 * Function: DC390_proc_info(char* buffer, char **start,
2398 * off_t offset, int length, int hostno, int inout)
2400 * Purpose: return SCSI Adapter/Device Info
2402 * Input: buffer: Pointer to a buffer where to write info
2405 * hostno: Host adapter index
2406 * inout : Read (=0) or set(!=0) info
2408 * Output: buffer: contains info
2409 * length; length of info in buffer
2411 * return value: length
2413 ********************************************************************/
2416 #define SPRINTF(args...) pos += sprintf(pos, ## args)
2419 if (YN) SPRINTF(" Yes "); \
2420 else SPRINTF(" No ")
2423 int DC390_proc_info (char *buffer
, char **start
,
2424 off_t offset
, int length
, int hostno
, int inout
)
2433 pACB
= dc390_pACB_start
;
2435 while(pACB
!= (PACB
)-1)
2437 shpnt
= pACB
->pScsiHost
;
2438 if (shpnt
->host_no
== hostno
) break;
2439 pACB
= pACB
->pNextACB
;
2442 if (pACB
== (PACB
)-1) return(-ESRCH
);
2443 if(!shpnt
) return(-ESRCH
);
2445 if(inout
) /* Has data been written to the file ? */
2446 return dc390_set_info(buffer
, length
, pACB
);
2448 SPRINTF("Tekram DC390/AM53C974 PCI SCSI Host Adapter, ");
2449 SPRINTF("Driver Version %s\n", DC390_VERSION
);
2453 SPRINTF("SCSI Host Nr %i, ", shpnt
->host_no
);
2454 SPRINTF("%s Adapter Nr %i\n", dc390_adapname
, pACB
->AdapterIndex
);
2455 SPRINTF("IOPortBase 0x%04x, ", pACB
->IOPortBase
);
2456 SPRINTF("IRQLevel 0x%02x\n", pACB
->IRQLevel
);
2458 SPRINTF("MaxID %i, MaxLUN %i, ", shpnt
->max_id
, shpnt
->max_lun
);
2459 SPRINTF("AdapterID %i, SelTimeout %i ms\n",
2460 shpnt
->this_id
, (pACB
->sel_timeout
*164)/100);
2462 SPRINTF("TagMaxNum %i, Status %i, ACBFlag %i, GlitchEater %i ns\n",
2463 pACB
->TagMaxNum
, pACB
->status
, pACB
->ACBFlag
, GLITCH_TO_NS(pACB
->glitch_cfg
)*12);
2465 SPRINTF("Statistics: Cmnds %li, Cmnds not sent directly %li, Out of SRB conds %li\n",
2466 pACB
->Cmds
, pACB
->CmdInQ
, pACB
->CmdOutOfSRB
);
2467 SPRINTF(" Lost arbitrations %li\n", pACB
->SelLost
);
2469 SPRINTF("Nr of attached devices: %i, Nr of DCBs: %i\n", pACB
->DeviceCnt
, pACB
->DCBCnt
);
2471 SPRINTF("Idx ID LUN Prty Sync DsCn SndS TagQ STOP NegoPeriod SyncSpeed SyncOffs\n");
2473 pDCB
= pACB
->pLinkDCB
;
2474 for (dev
= 0; dev
< pACB
->DCBCnt
; dev
++)
2476 SPRINTF("%02i %02i %02i ", dev
, pDCB
->UnitSCSIID
, pDCB
->UnitSCSILUN
);
2477 YESNO(pDCB
->DevMode
& PARITY_CHK_
);
2478 YESNO(pDCB
->SyncMode
& SYNC_NEGO_DONE
);
2479 YESNO(pDCB
->DevMode
& EN_DISCONNECT_
);
2480 //YESNO(pDCB->SyncMode & EN_ATN_STOP);
2481 YESNO(pDCB
->DevMode
& SEND_START_
);
2482 YESNO(pDCB
->SyncMode
& EN_TAG_QUEUEING
);
2483 YESNO(pDCB
->SyncMode
& EN_ATN_STOP
);
2484 if (pDCB
->SyncOffset
& 0x0f)
2486 int sp
= pDCB
->SyncPeriod
; if (! (pDCB
->CtrlR3
& FAST_SCSI
)) sp
++;
2487 SPRINTF(" %03i ns ", (pDCB
->NegoPeriod
) << 2);
2488 spd
= 40/(sp
); spd1
= 40%(sp
);
2489 spd1
= (spd1
* 10 + sp
/2) / (sp
);
2490 SPRINTF(" %2i.%1i M %02i\n", spd
, spd1
, (pDCB
->SyncOffset
& 0x0f));
2492 else SPRINTF(" (%03i ns)\n", (pDCB
->NegoPeriod
) << 2);
2493 /* Add more info ...*/
2494 pDCB
= pDCB
->pNextDCB
;
2498 *start
= buffer
+ offset
;
2500 if (pos
- buffer
< offset
)
2502 else if (pos
- buffer
- offset
< length
)
2503 return pos
- buffer
- offset
;
2513 /***********************************************************************
2514 * Function : static int dc390_shutdown (struct Scsi_Host *host)
2516 * Purpose : does a clean (we hope) shutdown of the SCSI chip.
2517 * Use prior to dumping core, unloading the driver, etc.
2519 * Returns : 0 on success
2520 ***********************************************************************/
2521 static int dc390_shutdown (struct Scsi_Host
*host
)
2524 PACB pACB
= (PACB
)(host
->hostdata
);
2526 /* pACB->soft_reset(host); */
2528 printk(KERN_INFO
"DC390: shutdown\n");
2530 pACB
->ACBFlag
= RESET_DONE
;
2531 bval
= DC390_read8 (CtrlReg1
);
2532 bval
|= DIS_INT_ON_SCSI_RST
;
2533 DC390_write8 (CtrlReg1
, bval
); /* disable interrupt */
2534 if (pACB
->Gmode2
& RST_SCSI_BUS
)
2535 dc390_ResetSCSIBus (pACB
);
2540 void dc390_freeDCBs (struct Scsi_Host
*host
)
2543 PACB pACB
= (PACB
)(host
->hostdata
);
2545 pDCB
= pACB
->pLinkDCB
;
2549 nDCB
= pDCB
->pNextDCB
;
2550 DCBDEBUG(printk (KERN_INFO
"DC390: Free DCB (ID %i, LUN %i): 0x%08x\n",\
2551 pDCB
->UnitSCSIID
, pDCB
->UnitSCSILUN
, (int)pDCB
);)
2554 } while (pDCB
&& pDCB
!= pACB
->pLinkDCB
);
2558 int DC390_release(struct Scsi_Host
*host
)
2562 DC390_AFLAGS DC390_IFLAGS
2563 #if USE_SPINLOCKS > 1
2564 PACB pACB
= (PACB
)(host
->hostdata
);
2570 dc390_shutdown (host
);
2572 if (host
->irq
!= IRQ_NONE
)
2574 for (irq_count
= 0, pACB
= dc390_pACB_start
;
2575 pACB
; pACB
= pACB
->pNextACB
)
2577 if ( pACB
->IRQLevel
== host
->irq
)
2582 DEBUG0(printk(KERN_INFO
"DC390: Free IRQ %i\n",host
->irq
);)
2583 free_irq(host
->irq
,NULL
);
2587 release_region(host
->io_port
,host
->n_io_port
);
2588 dc390_freeDCBs (host
);
2594 Scsi_Host_Template driver_template
= DC390_T
;
2595 #include "scsi_module.c"
2596 #endif /* def MODULE */