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 (see README.tmscsim) *
9 *************************************************************************/
10 /* $Id: tmscsim.c,v 2.60.2.30 2000/12/20 01:07:12 garloff Exp $ */
11 /* Enhancements and bugfixes by *
12 * Kurt Garloff <kurt@garloff.de> <garloff@suse.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 * completely reworked. Handle target ini- *
99 * tiated SDTR correctly. *
100 * 2.0d1 99/01/25 KG Try to handle RESTORE_PTR *
101 * 2.0d2 99/02/08 KG Check for failure of kmalloc, correct *
102 * inclusion of scsicam.h, DelayReset *
103 * 2.0d3 99/05/31 KG DRIVER_OK -> DID_OK, DID_NO_CONNECT, *
104 * detect Target mode and warn. *
105 * pcmd->result handling cleaned up. *
106 * 2.0d4 99/06/01 KG Cleaned selection process. Found bug *
107 * which prevented more than 16 tags. Now: *
108 * 24. SDTR cleanup. Cleaner multi-LUN *
109 * handling. Don't modify ControlRegs/FIFO *
111 * 2.0d5 99/06/01 KG Clear DevID, Fix INQUIRY after cfg chg. *
112 * 2.0d6 99/06/02 KG Added ADD special command to allow cfg. *
113 * before detection. Reset SYNC_NEGO_DONE *
114 * after a bus reset. *
115 * 2.0d7 99/06/03 KG Fixed bugs wrt add,remove commands *
116 * 2.0d8 99/06/04 KG Removed copying of cmnd into CmdBlock. *
117 * Fixed Oops in _release(). *
118 * 2.0d9 99/06/06 KG Also tag queue INQUIRY, T_U_R, ... *
119 * Allow arb. no. of Tagged Cmnds. Max 32 *
120 * 2.0d1099/06/20 KG TagMaxNo changes now honoured! Queueing *
121 * clearified (renamed ..) TagMask handling*
123 * 2.0d1199/06/28 KG cmd->result now identical to 2.0d2 *
124 * 2.0d1299/07/04 KG Changed order of processing in IRQ *
125 * 2.0d1399/07/05 KG Don't update DCB fields if removed *
126 * 2.0d1499/07/05 KG remove_dev: Move kfree() to the end *
127 * 2.0d1599/07/12 KG use_new_eh_code: 0, ULONG -> UINT where *
129 * 2.0d1699/07/13 KG Reenable StartSCSI interrupt, Retry msg *
130 * 2.0d1799/07/15 KG Remove debug msg. Disable recfg. when *
131 * there are queued cmnds *
132 * 2.0d1899/07/18 KG Selection timeout: Don't requeue *
133 * 2.0d1999/07/18 KG Abort: Only call scsi_done if dequeued *
134 * 2.0d2099/07/19 KG Rst_Detect: DoingSRB_Done *
135 * 2.0d2199/08/15 KG dev_id for request/free_irq, cmnd[0] for*
136 * RETRY, SRBdone does DID_ABORT for the *
137 * cmd passed by DC390_reset() *
138 * 2.0d2299/08/25 KG dev_id fixed. can_queue: 42 *
139 * 2.0d2399/08/25 KG Removed some debugging code. dev_id *
140 * now is set to pACB. Use u8,u16,u32. *
141 * 2.0d2499/11/14 KG Unreg. I/O if failed IRQ alloc. Call *
142 * done () w/ DID_BAD_TARGET in case of *
143 * missing DCB. We are old EH!! *
144 * 2.0d2500/01/15 KG 2.3.3x compat from Andreas Schultz *
145 * set unique_id. Disable RETRY message. *
146 * 2.0d2600/01/29 KG Go to new EH. *
147 * 2.0d2700/01/31 KG ... but maintain 2.0 compat. *
148 * and fix DCB freeing *
149 * 2.0d2800/02/14 KG Queue statistics fixed, dump special cmd*
150 * Waiting_Timer for failed StartSCSI *
151 * New EH: Don't return cmnds to ML on RST *
152 * Use old EH (don't have new EH fns yet) *
153 * Reset: Unlock, but refuse to queue *
154 * 2.3 __setup function *
155 * 2.0e 00/05/22 KG Return residual for 2.3 *
156 * 2.0e1 00/05/25 KG Compile fixes for 2.3.99 *
157 * 2.0e2 00/05/27 KG Jeff Garzik's pci_enable_device() *
158 * 2.0e3 00/09/29 KG Some 2.4 changes. Don't try Sync Nego *
159 * before INQUIRY has reported ability. *
160 * Recognise INQUIRY as scanning command. *
161 * 2.0e4 00/10/13 KG Allow compilation into 2.4 kernel *
162 * 2.0e5 00/11/17 KG Store Inq.flags in DCB *
163 * 2.0e6 00/11/22 KG 2.4 init function (Thx to O.Schumann) *
164 * 2.4 PCI device table (Thx to A.Richter) *
165 * 2.0e7 00/11/28 KG Allow overriding of BIOS settings *
166 * 2.0f 00/12/20 KG Handle failed INQUIRYs during scan *
167 ***********************************************************************/
169 /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */
170 #define DC390_IRQ SA_SHIRQ /* | SA_INTERRUPT */
173 //#define DC390_DEBUG0
174 //#define DC390_DEBUG1
175 //#define DC390_DCBDEBUG
176 //#define DC390_PARSEDEBUG
177 //#define DC390_REMOVABLEDEBUG
178 //#define DC390_LOCKDEBUG
180 /* Debug definitions */
182 # define DEBUG0(x) x;
187 # define DEBUG1(x) x;
191 #ifdef DC390_DCBDEBUG
192 # define DCBDEBUG(x) x;
196 #ifdef DC390_PARSEDEBUG
197 # define PARSEDEBUG(x) x;
199 # define PARSEDEBUG(x)
201 #ifdef DC390_REMOVABLEDEBUG
202 # define REMOVABLEDEBUG(x) x;
204 # define REMOVABLEDEBUG(x)
210 # include <linux/module.h>
215 #include <asm/system.h>
216 #include <linux/delay.h>
217 #include <linux/signal.h>
218 #include <linux/sched.h>
219 #include <linux/errno.h>
220 #include <linux/kernel.h>
221 #include <linux/ioport.h>
222 #include <linux/pci.h>
223 #include <linux/proc_fs.h>
224 #include <linux/string.h>
225 #include <linux/ctype.h>
226 #include <linux/mm.h>
227 #include <linux/config.h>
228 #include <linux/version.h>
229 #include <linux/blk.h>
230 #include <linux/timer.h>
234 #include "constants.h"
236 #include <linux/stat.h>
237 #include <scsi/scsicam.h>
241 #define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI
245 /* Note: Starting from 2.1.9x, the mid-level scsi code issues a
246 * spinlock_irqsave (&io_request_lock) before calling the driver's
247 * routines, so we don't need to lock, except in the IRQ handler.
248 * The policy 3, let the midlevel scsi code do the io_request_locks
249 * and us locking on a driver specific lock, shouldn't hurt anybody; it
250 * just causes a minor performance degradation for setting the locks.
254 * level 3: lock on both adapter specific locks and (global) io_request_lock
255 * level 2: lock on adapter specific locks only
256 * level 1: rely on the locking of the mid level code (io_request_lock)
257 * undef : traditional save_flags; cli; restore_flags;
260 //#define DEBUG_SPINLOCKS 2 /* Set to 0, 1 or 2 in include/linux/spinlock.h */
262 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
263 # include <linux/init.h>
264 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
265 # include <linux/spinlock.h>
267 # include <asm/spinlock.h>
272 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
273 # define USE_SPINLOCKS 1
277 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
278 # define USE_SPINLOCKS 2
282 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,99)
283 static struct pci_device_id tmscsim_pci_tbl
[] __initdata
= {
285 vendor
: PCI_VENDOR_ID_AMD
,
286 device
: PCI_DEVICE_ID_AMD53C974
,
287 subvendor
: PCI_ANY_ID
,
288 subdevice
: PCI_ANY_ID
,
290 { } /* Terminating entry */
292 MODULE_DEVICE_TABLE(pci
, tmscsim_pci_tbl
);
297 # if USE_SPINLOCKS == 3 /* both */
299 # if defined (CONFIG_SMP) || DEBUG_SPINLOCKS > 0
300 # define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
302 # define DC390_LOCKA_INIT
304 spinlock_t dc390_drvlock
= SPIN_LOCK_UNLOCKED
;
306 # define DC390_AFLAGS unsigned long aflags;
307 # define DC390_IFLAGS unsigned long iflags;
308 # define DC390_DFLAGS unsigned long dflags;
310 # define DC390_LOCK_IO spin_lock_irqsave (&io_request_lock, iflags)
311 # define DC390_UNLOCK_IO spin_unlock_irqrestore (&io_request_lock, iflags)
313 # define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
314 # define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
315 # define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
316 # define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
318 # define DC390_LOCK_ACB spin_lock_irqsave (&(pACB->lock), aflags)
319 # define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags)
320 # define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock))
321 # define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock))
322 //# define DC390_LOCKA_INIT spin_lock_init (&(pACB->lock))
326 # if USE_SPINLOCKS == 2 /* adapter specific locks */
328 # if defined (__SMP__) || DEBUG_SPINLOCKS > 0
329 # define DC390_LOCKA_INIT { spinlock_t __unlocked = SPIN_LOCK_UNLOCKED; pACB->lock = __unlocked; };
331 # define DC390_LOCKA_INIT
333 spinlock_t dc390_drvlock
= SPIN_LOCK_UNLOCKED
;
334 # define DC390_AFLAGS unsigned long aflags;
335 # define DC390_IFLAGS
336 # define DC390_DFLAGS unsigned long dflags;
337 # define DC390_LOCK_IO /* spin_lock_irqsave (&io_request_lock, iflags) */
338 # define DC390_UNLOCK_IO /* spin_unlock_irqrestore (&io_request_lock, iflags) */
339 # define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
340 # define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
341 # define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
342 # define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
343 # define DC390_LOCK_ACB spin_lock_irqsave (&(pACB->lock), aflags)
344 # define DC390_UNLOCK_ACB spin_unlock_irqrestore (&(pACB->lock), aflags)
345 # define DC390_LOCK_ACB_NI spin_lock (&(pACB->lock))
346 # define DC390_UNLOCK_ACB_NI spin_unlock (&(pACB->lock))
347 //# define DC390_LOCKA_INIT spin_lock_init (&(pACB->lock))
349 # else /* USE_SPINLOCKS == 1: global lock io_request_lock */
351 # define DC390_AFLAGS
352 # define DC390_IFLAGS unsigned long iflags;
353 # define DC390_DFLAGS unsigned long dflags;
354 spinlock_t dc390_drvlock
= SPIN_LOCK_UNLOCKED
;
355 # define DC390_LOCK_IO spin_lock_irqsave (&io_request_lock, iflags)
356 # define DC390_UNLOCK_IO spin_unlock_irqrestore (&io_request_lock, iflags)
357 # define DC390_LOCK_DRV spin_lock_irqsave (&dc390_drvlock, dflags)
358 # define DC390_UNLOCK_DRV spin_unlock_irqrestore (&dc390_drvlock, dflags)
359 # define DC390_LOCK_DRV_NI spin_lock (&dc390_drvlock)
360 # define DC390_UNLOCK_DRV_NI spin_unlock (&dc390_drvlock)
361 # define DC390_LOCK_ACB /* DC390_LOCK_IO */
362 # define DC390_UNLOCK_ACB /* DC390_UNLOCK_IO */
363 # define DC390_LOCK_ACB_NI /* spin_lock (&(pACB->lock)) */
364 # define DC390_UNLOCK_ACB_NI /* spin_unlock (&(pACB->lock)) */
365 # define DC390_LOCKA_INIT /* DC390_LOCKA_INIT */
370 #else /* USE_SPINLOCKS undefined */
372 # define DC390_AFLAGS unsigned long aflags;
373 # define DC390_IFLAGS unsigned long iflags;
374 # define DC390_DFLAGS unsigned long dflags;
375 # define DC390_LOCK_IO save_flags (iflags); cli ()
376 # define DC390_UNLOCK_IO restore_flags (iflags)
377 # define DC390_LOCK_DRV save_flags (dflags); cli ()
378 # define DC390_UNLOCK_DRV restore_flags (dflags)
379 # define DC390_LOCK_DRV_NI
380 # define DC390_UNLOCK_DRV_NI
381 # define DC390_LOCK_ACB save_flags (aflags); cli ()
382 # define DC390_UNLOCK_ACB restore_flags (aflags)
383 # define DC390_LOCK_ACB_NI
384 # define DC390_UNLOCK_ACB_NI
385 # define DC390_LOCKA_INIT
389 /* These macros are used for uniform access to 2.0.x and 2.1.x PCI config space*/
393 # define PDEVDECL struct pci_dev *pdev
394 # define PDEVDECL0 struct pci_dev *pdev = NULL
395 # define PDEVDECL1 struct pci_dev *pdev
396 # define PDEVSET pACB->pdev=pdev
397 # define PDEVSET1 pdev=pACB->pdev
398 # define PCI_WRITE_CONFIG_BYTE(pd, rv, bv) pci_write_config_byte (pd, rv, bv)
399 # define PCI_READ_CONFIG_BYTE(pd, rv, bv) pci_read_config_byte (pd, rv, bv)
400 # define PCI_WRITE_CONFIG_WORD(pd, rv, bv) pci_write_config_word (pd, rv, bv)
401 # define PCI_READ_CONFIG_WORD(pd, rv, bv) pci_read_config_word (pd, rv, bv)
402 # define PCI_BUS_DEV pdev->bus->number, pdev->devfn
403 # define PCI_PRESENT pci_present ()
404 # define PCI_SET_MASTER pci_set_master (pdev)
405 # define PCI_FIND_DEVICE(vend, id) (pdev = pci_find_device (vend, id, pdev))
406 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,10)
407 # define PCI_GET_IO_AND_IRQ io_port = pci_resource_start (pdev, 0); irq = pdev->irq
409 # define PCI_GET_IO_AND_IRQ io_port = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; irq = pdev->irq
412 # include <linux/bios32.h>
413 # define PDEV pbus, pdevfn
414 # define PDEVDECL UCHAR pbus, UCHAR pdevfn
415 # define PDEVDECL0 UCHAR pbus = 0; UCHAR pdevfn = 0; USHORT pci_index = 0; int error
416 # define PDEVDECL1 UCHAR pbus; UCHAR pdevfn /*; USHORT pci_index */
417 # define PDEVSET pACB->pbus=pbus; pACB->pdevfn=pdevfn /*; pACB->pci_index=pci_index */
418 # define PDEVSET1 pbus=pACB->pbus; pdevfn=pACB->pdevfn /*; pci_index=pACB->pci_index */
419 # define PCI_WRITE_CONFIG_BYTE(pd, rv, bv) pcibios_write_config_byte (pd, rv, bv)
420 # define PCI_READ_CONFIG_BYTE(pd, rv, bv) pcibios_read_config_byte (pd, rv, bv)
421 # define PCI_WRITE_CONFIG_WORD(pd, rv, bv) pcibios_write_config_word (pd, rv, bv)
422 # define PCI_READ_CONFIG_WORD(pd, rv, bv) pcibios_read_config_word (pd, rv, bv)
423 # define PCI_BUS_DEV pbus, pdevfn
424 # define PCI_PRESENT pcibios_present ()
425 # define PCI_SET_MASTER dc390_set_master (pbus, pdevfn)
426 # define PCI_FIND_DEVICE(vend, id) (!pcibios_find_device (vend, id, pci_index++, &pbus, &pdevfn))
427 # define PCI_GET_IO_AND_IRQ error = pcibios_read_config_dword (pbus, pdevfn, PCI_BASE_ADDRESS_0, &io_port); \
428 error |= pcibios_read_config_byte (pbus, pdevfn, PCI_INTERRUPT_LINE, &irq); \
430 if (error) { printk (KERN_ERR "DC390_detect: Error reading PCI config registers!\n"); continue; }
439 UCHAR
dc390_StartSCSI( PACB pACB
, PDCB pDCB
, PSRB pSRB
);
440 void dc390_DataOut_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
441 void dc390_DataIn_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
442 static void dc390_Command_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
443 static void dc390_Status_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
444 static void dc390_MsgOut_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
445 void dc390_MsgIn_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
446 static void dc390_DataOutPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
447 static void dc390_DataInPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
448 void dc390_CommandPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
449 static void dc390_StatusPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
450 void dc390_MsgOutPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
451 static void dc390_MsgInPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
452 static void dc390_Nop_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
453 static void dc390_Nop_1( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
);
455 static void dc390_SetXferRate( PACB pACB
, PDCB pDCB
);
456 void dc390_Disconnect( PACB pACB
);
457 void dc390_Reselect( PACB pACB
);
458 void dc390_SRBdone( PACB pACB
, PDCB pDCB
, PSRB pSRB
);
459 void dc390_DoingSRB_Done( PACB pACB
, PSCSICMD cmd
);
460 static void dc390_ScsiRstDetect( PACB pACB
);
461 static void dc390_ResetSCSIBus( PACB pACB
);
462 static void __inline__
dc390_RequestSense( PACB pACB
, PDCB pDCB
, PSRB pSRB
);
463 static void __inline__
dc390_InvalidCmd( PACB pACB
);
464 static void __inline__
dc390_EnableMsgOut_Abort (PACB
, PSRB
);
465 static void dc390_remove_dev (PACB pACB
, PDCB pDCB
);
466 void do_DC390_Interrupt( int, void *, struct pt_regs
*);
468 int dc390_initAdapter( PSH psh
, ULONG io_port
, UCHAR Irq
, UCHAR index
);
469 void dc390_initDCB( PACB pACB
, PDCB
*ppDCB
, UCHAR id
, UCHAR lun
);
470 void dc390_updateDCB (PACB pACB
, PDCB pDCB
);
473 static int DC390_release(struct Scsi_Host
*host
);
474 static int dc390_shutdown (struct Scsi_Host
*host
);
478 //static PSHT dc390_pSHT_start = NULL;
479 //static PSH dc390_pSH_start = NULL;
480 //static PSH dc390_pSH_current = NULL;
481 static PACB dc390_pACB_start
= NULL
;
482 static PACB dc390_pACB_current
= NULL
;
483 static ULONG dc390_lastabortedpid
= 0;
484 static UINT dc390_laststatus
= 0;
485 static UCHAR dc390_adapterCnt
= 0;
487 /* Startup values, to be overriden on the commandline */
488 int tmscsim
[] = {-2, -2, -2, -2, -2, -2};
490 # if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
491 MODULE_PARM(tmscsim
, "1-6i");
492 MODULE_PARM_DESC(tmscsim
, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");
495 #if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
496 MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
497 MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
498 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
501 static PVOID dc390_phase0
[]={
513 static PVOID dc390_phase1
[]={
526 static char* dc390_p0_str
[] = {
538 static char* dc390_p1_str
[] = {
539 "dc390_DataOutPhase",
541 "dc390_CommandPhase",
551 /* Devices erroneously pretending to be able to do TagQ */
552 UCHAR dc390_baddevname1
[2][28] ={
553 "SEAGATE ST3390N 9546",
554 "HP C3323-300 4269"};
557 static char* dc390_adapname
= "DC390";
558 UCHAR dc390_eepromBuf
[MAX_ADAPTER_NUM
][EE_LEN
];
559 UCHAR dc390_clock_period1
[] = {4, 5, 6, 7, 8, 10, 13, 20};
560 UCHAR dc390_clock_speed
[] = {100,80,67,57,50, 40, 31, 20};
562 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,30)
563 struct proc_dir_entry DC390_proc_scsi_tmscsim
={
564 PROC_SCSI_DC390T
, 7 ,"tmscsim",
565 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2
569 /***********************************************************************
570 * Functions for access to DC390 EEPROM
571 * and some to emulate it
573 **********************************************************************/
576 static void __init
dc390_EnDisableCE( UCHAR mode
, PDEVDECL
, PUCHAR regval
)
581 if(mode
== ENABLE_CE
)
585 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
586 if(mode
== DISABLE_CE
)
587 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
592 /* Override EEprom values with explicitly set values */
593 static void __init
dc390_EEprom_Override (UCHAR index
)
597 ptr
= (PUCHAR
) dc390_eepromBuf
[index
];
599 /* Adapter Settings */
600 if (tmscsim
[0] != -2)
601 ptr
[EE_ADAPT_SCSI_ID
] = (UCHAR
)tmscsim
[0]; /* Adapter ID */
602 if (tmscsim
[3] != -2)
603 ptr
[EE_MODE2
] = (UCHAR
)tmscsim
[3];
604 if (tmscsim
[5] != -2)
605 ptr
[EE_DELAY
] = tmscsim
[5]; /* Reset delay */
606 if (tmscsim
[4] != -2)
607 ptr
[EE_TAG_CMD_NUM
] = (UCHAR
)tmscsim
[4]; /* Tagged Cmds */
609 /* Device Settings */
610 for (id
= 0; id
< MAX_SCSI_ID
; id
++)
612 if (tmscsim
[2] != -2)
613 ptr
[id
<<2] = (UCHAR
)tmscsim
[2]; /* EE_MODE1 */
614 if (tmscsim
[1] != -2)
615 ptr
[(id
<<2) + 1] = (UCHAR
)tmscsim
[1]; /* EE_Speed */
619 /* Handle "-1" case */
620 static void __init
dc390_check_for_safe_settings (void)
622 if (tmscsim
[0] == -1 || tmscsim
[0] > 15) /* modules-2.0.0 passes -1 as string */
624 tmscsim
[0] = 7; tmscsim
[1] = 4;
625 tmscsim
[2] = 0x09; tmscsim
[3] = 0x0f;
626 tmscsim
[4] = 2; tmscsim
[5] = 10;
627 printk (KERN_INFO
"DC390: Using safe settings.\n");
632 #ifndef CONFIG_SCSI_DC390T_NOGENSUPP
633 int __initdata tmscsim_def
[] = {7, 0 /* 10MHz */,
634 PARITY_CHK_
| SEND_START_
| EN_DISCONNECT_
635 | SYNC_NEGO_
| TAG_QUEUEING_
,
636 MORE2_DRV
| GREATER_1G
| RST_SCSI_BUS
| ACTIVE_NEGATION
638 # ifdef CONFIG_SCSI_MULTI_LUN
641 , 3 /* 16 Tags per LUN */, 1 /* s delay after Reset */ };
643 /* Copy defaults over set values where missing */
644 static void __init
dc390_fill_with_defaults (void)
647 PARSEDEBUG(printk(KERN_INFO
"DC390: setup %08x %08x %08x %08x %08x %08x\n", tmscsim
[0],\
648 tmscsim
[1], tmscsim
[2], tmscsim
[3], tmscsim
[4], tmscsim
[5]);)
649 for (i
= 0; i
< 6; i
++)
651 if (tmscsim
[i
] < 0 || tmscsim
[i
] > 255)
652 tmscsim
[i
] = tmscsim_def
[i
];
655 if (tmscsim
[0] > 7) tmscsim
[0] = 7;
656 if (tmscsim
[1] > 7) tmscsim
[1] = 4;
657 if (tmscsim
[4] > 5) tmscsim
[4] = 4;
658 if (tmscsim
[5] > 180) tmscsim
[5] = 180;
662 /* Override defaults on cmdline:
663 * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped)
665 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13)
666 void __init
dc390_setup (char *str
)
670 (void)get_options (str
, ARRAY_SIZE(ints
), ints
);
672 void __init
dc390_setup (char *str
, int *ints
)
679 printk (KERN_NOTICE
"DC390: ignore extra params!\n");
682 for (i
= 0; i
< im
; i
++)
683 tmscsim
[i
] = ints
[i
+1];
684 /* dc390_checkparams (); */
687 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13)
689 __setup("tmscsim=", dc390_setup
);
694 static void __init
dc390_EEpromOutDI( PDEVDECL
, PUCHAR regval
, UCHAR Carry
)
703 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
707 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
710 PCI_WRITE_CONFIG_BYTE(PDEV
, *regval
, bval
);
715 static UCHAR __init
dc390_EEpromInDO( PDEVDECL
)
719 PCI_WRITE_CONFIG_BYTE(PDEV
, 0x80, 0x80);
721 PCI_WRITE_CONFIG_BYTE(PDEV
, 0x80, 0x40);
723 PCI_READ_CONFIG_BYTE(PDEV
, 0x00, &bval
);
731 static USHORT __init
dc390_EEpromGetData1( PDEVDECL
)
741 carryFlag
= dc390_EEpromInDO(PDEV
);
748 static void __init
dc390_Prepare( PDEVDECL
, PUCHAR regval
, UCHAR EEpromCmd
)
757 dc390_EEpromOutDI(PDEV
,regval
,carryFlag
);
758 carryFlag
= (EEpromCmd
& j
) ? 1 : 0;
764 static void __init
dc390_ReadEEprom( PDEVDECL
, PUSHORT ptr
)
770 for(i
=0; i
<0x40; i
++)
772 dc390_EnDisableCE(ENABLE_CE
, PDEV
, ®val
);
773 dc390_Prepare(PDEV
, ®val
, cmd
++);
774 *ptr
++ = dc390_EEpromGetData1(PDEV
);
775 dc390_EnDisableCE(DISABLE_CE
, PDEV
, ®val
);
780 static void __init
dc390_interpret_delay (UCHAR index
)
782 char interpd
[] = {1,3,5,10,16,30,60,120};
783 dc390_eepromBuf
[index
][EE_DELAY
] = interpd
[dc390_eepromBuf
[index
][EE_DELAY
]];
786 static UCHAR __init
dc390_CheckEEpromCheckSum( PDEVDECL
, UCHAR index
)
790 USHORT wval
, *ptr
= (PUSHORT
)EEbuf
;
792 dc390_ReadEEprom( PDEV
, ptr
);
793 memcpy (dc390_eepromBuf
[index
], EEbuf
, EE_ADAPT_SCSI_ID
);
794 memcpy (&dc390_eepromBuf
[index
][EE_ADAPT_SCSI_ID
],
795 &EEbuf
[REAL_EE_ADAPT_SCSI_ID
], EE_LEN
- EE_ADAPT_SCSI_ID
);
796 dc390_interpret_delay (index
);
799 for(i
=0; i
<0x40; i
++, ptr
++)
801 return (wval
== 0x1234 ? 0 : 1);
805 /***********************************************************************
806 * Functions for the management of the internal structures
807 * (DCBs, SRBs, Queueing)
809 **********************************************************************/
810 static PDCB __inline__
dc390_findDCB ( PACB pACB
, UCHAR id
, UCHAR lun
)
812 PDCB pDCB
= pACB
->pLinkDCB
; if (!pDCB
) return 0;
813 while (pDCB
->TargetID
!= id
|| pDCB
->TargetLUN
!= lun
)
815 pDCB
= pDCB
->pNextDCB
;
816 if (pDCB
== pACB
->pLinkDCB
)
818 DCBDEBUG(printk (KERN_WARNING
"DC390: DCB not found (DCB=%p, DCBmap[%2x]=%2x)\n",
819 pDCB
, id
, pACB
->DCBmap
[id
]);)
823 DCBDEBUG1( printk (KERN_DEBUG
"DCB %p (%02x,%02x) found.\n", \
824 pDCB
, pDCB
->TargetID
, pDCB
->TargetLUN
);)
828 /* Queueing philosphy:
829 * There are a couple of lists:
830 * - Query: Contains the Scsi Commands not yet turned into SRBs (per ACB)
831 * (Note: For new EH, it is unecessary!)
832 * - Waiting: Contains a list of SRBs not yet sent (per DCB)
833 * - Free: List of free SRB slots
835 * If there are no waiting commands for the DCB, the new one is sent to the bus
836 * otherwise the oldest one is taken from the Waiting list and the new one is
837 * queued to the Waiting List
839 * Lists are managed using two pointers and eventually a counter
844 /* Look for a SCSI cmd in a SRB queue */
845 static PSRB
dc390_find_cmd_in_SRBq (PSCSICMD cmd
, PSRB queue
)
850 if (q
->pcmd
== cmd
) return q
;
852 if (q
== queue
) return 0;
859 /* Append to Query List */
860 static void dc390_Query_append( PSCSICMD cmd
, PACB pACB
)
862 DEBUG0(printk ("DC390: Append cmd %li to Query\n", cmd
->pid
);)
863 if( !pACB
->QueryCnt
)
864 pACB
->pQueryHead
= cmd
;
866 pACB
->pQueryTail
->next
= cmd
;
868 pACB
->pQueryTail
= cmd
;
875 /* Return next cmd from Query list */
876 static PSCSICMD
dc390_Query_get ( PACB pACB
)
880 pcmd
= pACB
->pQueryHead
;
881 if (!pcmd
) return pcmd
;
882 DEBUG0(printk ("DC390: Get cmd %li from Query\n", pcmd
->pid
);)
883 pACB
->pQueryHead
= pcmd
->next
;
885 if (!pACB
->pQueryHead
) pACB
->pQueryTail
= NULL
;
891 /* Return next free SRB */
892 static __inline__ PSRB
dc390_Free_get ( PACB pACB
)
896 pSRB
= pACB
->pFreeSRB
;
897 DEBUG0(printk ("DC390: Get Free SRB %p\n", pSRB
);)
900 pACB
->pFreeSRB
= pSRB
->pNextSRB
;
901 pSRB
->pNextSRB
= NULL
;
907 /* Insert SRB oin top of free list */
908 static __inline__
void dc390_Free_insert (PACB pACB
, PSRB pSRB
)
910 DEBUG0(printk ("DC390: Free SRB %p\n", pSRB
);)
911 pSRB
->pNextSRB
= pACB
->pFreeSRB
;
912 pACB
->pFreeSRB
= pSRB
;
916 /* Inserts a SRB to the top of the Waiting list */
917 static __inline__
void dc390_Waiting_insert ( PDCB pDCB
, PSRB pSRB
)
919 DEBUG0(printk ("DC390: Insert pSRB %p cmd %li to Waiting\n", pSRB
, pSRB
->pcmd
->pid
);)
920 pSRB
->pNextSRB
= pDCB
->pWaitingSRB
;
921 if (!pDCB
->pWaitingSRB
)
922 pDCB
->pWaitLast
= pSRB
;
923 pDCB
->pWaitingSRB
= pSRB
;
928 /* Queue SRB to waiting list */
929 static __inline__
void dc390_Waiting_append ( PDCB pDCB
, PSRB pSRB
)
931 DEBUG0(printk ("DC390: Append pSRB %p cmd %li to Waiting\n", pSRB
, pSRB
->pcmd
->pid
);)
932 if( pDCB
->pWaitingSRB
)
933 pDCB
->pWaitLast
->pNextSRB
= pSRB
;
935 pDCB
->pWaitingSRB
= pSRB
;
937 pDCB
->pWaitLast
= pSRB
;
938 pSRB
->pNextSRB
= NULL
;
940 pDCB
->pDCBACB
->CmdInQ
++;
943 static __inline__
void dc390_Going_append (PDCB pDCB
, PSRB pSRB
)
946 DEBUG0(printk("DC390: Append SRB %p to Going\n", pSRB
);)
947 /* Append to the list of Going commands */
948 if( pDCB
->pGoingSRB
)
949 pDCB
->pGoingLast
->pNextSRB
= pSRB
;
951 pDCB
->pGoingSRB
= pSRB
;
953 pDCB
->pGoingLast
= pSRB
;
954 /* No next one in sent list */
955 pSRB
->pNextSRB
= NULL
;
958 static __inline__
void dc390_Going_remove (PDCB pDCB
, PSRB pSRB
)
960 DEBUG0(printk("DC390: Remove SRB %p from Going\n", pSRB
);)
961 if (pSRB
== pDCB
->pGoingSRB
)
962 pDCB
->pGoingSRB
= pSRB
->pNextSRB
;
965 PSRB psrb
= pDCB
->pGoingSRB
;
966 while (psrb
&& psrb
->pNextSRB
!= pSRB
)
967 psrb
= psrb
->pNextSRB
;
969 { printk (KERN_ERR
"DC390: Remove non-ex. SRB %p from Going!\n", pSRB
); return; }
970 psrb
->pNextSRB
= pSRB
->pNextSRB
;
971 if (pSRB
== pDCB
->pGoingLast
)
972 pDCB
->pGoingLast
= psrb
;
977 /* Moves SRB from Going list to the top of Waiting list */
978 static void dc390_Going_to_Waiting ( PDCB pDCB
, PSRB pSRB
)
980 DEBUG0(printk(KERN_INFO
"DC390: Going_to_Waiting (SRB %p) pid = %li\n", pSRB
, pSRB
->pcmd
->pid
);)
981 /* Remove SRB from Going */
982 dc390_Going_remove (pDCB
, pSRB
);
983 /* Insert on top of Waiting */
984 dc390_Waiting_insert (pDCB
, pSRB
);
985 /* Tag Mask must be freed elsewhere ! (KG, 99/06/18) */
988 /* Moves first SRB from Waiting list to Going list */
989 static __inline__
void dc390_Waiting_to_Going ( PDCB pDCB
, PSRB pSRB
)
991 /* Remove from waiting list */
992 DEBUG0(printk("DC390: Remove SRB %p from head of Waiting\n", pSRB
);)
993 pDCB
->pWaitingSRB
= pSRB
->pNextSRB
;
994 if( !pDCB
->pWaitingSRB
) pDCB
->pWaitLast
= NULL
;
996 dc390_Going_append (pDCB
, pSRB
);
999 /* 2.0 timer compatibility */
1000 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,30)
1001 static inline int timer_pending(struct timer_list
* timer
)
1003 return timer
->prev
!= NULL
;
1005 #define time_after(a,b) ((long)(b) - (long)(a) < 0)
1006 #define time_before(a,b) time_after(b,a)
1009 void DC390_waiting_timed_out (unsigned long ptr
);
1010 /* Sets the timer to wake us up */
1011 static void dc390_waiting_timer (PACB pACB
, unsigned long to
)
1013 if (timer_pending (&pACB
->Waiting_Timer
)) return;
1014 init_timer (&pACB
->Waiting_Timer
);
1015 pACB
->Waiting_Timer
.function
= DC390_waiting_timed_out
;
1016 pACB
->Waiting_Timer
.data
= (unsigned long)pACB
;
1017 if (time_before (jiffies
+ to
, pACB
->pScsiHost
->last_reset
))
1018 pACB
->Waiting_Timer
.expires
= pACB
->pScsiHost
->last_reset
+ 1;
1020 pACB
->Waiting_Timer
.expires
= jiffies
+ to
+ 1;
1021 add_timer (&pACB
->Waiting_Timer
);
1025 /* Send the next command from the waiting list to the bus */
1026 static void dc390_Waiting_process ( PACB pACB
)
1031 if( (pACB
->pActiveDCB
) || (pACB
->ACBFlag
& (RESET_DETECT
+RESET_DONE
+RESET_DEV
) ) )
1033 if (timer_pending (&pACB
->Waiting_Timer
)) del_timer (&pACB
->Waiting_Timer
);
1034 ptr
= pACB
->pDCBRunRobin
;
1037 ptr
= pACB
->pLinkDCB
;
1038 pACB
->pDCBRunRobin
= ptr
;
1044 pACB
->pDCBRunRobin
= ptr1
->pNextDCB
;
1045 if( !( pSRB
= ptr1
->pWaitingSRB
) ||
1046 ( ptr1
->MaxCommand
<= ptr1
->GoingSRBCnt
))
1047 ptr1
= ptr1
->pNextDCB
;
1050 /* Try to send to the bus */
1051 if( !dc390_StartSCSI(pACB
, ptr1
, pSRB
) )
1052 dc390_Waiting_to_Going (ptr1
, pSRB
);
1054 dc390_waiting_timer (pACB
, HZ
/5);
1057 } while (ptr1
!= ptr
);
1061 /* Wake up waiting queue */
1062 void DC390_waiting_timed_out (unsigned long ptr
)
1064 PACB pACB
= (PACB
)ptr
;
1067 DEBUG0(printk ("DC390: Debug: Waiting queue woken up by timer!\n");)
1070 dc390_Waiting_process (pACB
);
1075 /***********************************************************************
1076 * Function: static void dc390_SendSRB (PACB pACB, PSRB pSRB)
1078 * Purpose: Send SCSI Request Block (pSRB) to adapter (pACB)
1080 ***********************************************************************/
1082 static void dc390_SendSRB( PACB pACB
, PSRB pSRB
)
1086 pDCB
= pSRB
->pSRBDCB
;
1087 if( (pDCB
->MaxCommand
<= pDCB
->GoingSRBCnt
) || (pACB
->pActiveDCB
) ||
1088 (pACB
->ACBFlag
& (RESET_DETECT
+RESET_DONE
+RESET_DEV
)) )
1090 dc390_Waiting_append (pDCB
, pSRB
);
1091 dc390_Waiting_process (pACB
);
1096 if( pDCB
->pWaitingSRB
)
1098 dc390_Waiting_append (pDCB
, pSRB
);
1099 /* pSRB = GetWaitingSRB(pDCB); */ /* non-existent */
1100 pSRB
= pDCB
->pWaitingSRB
;
1101 /* Remove from waiting list */
1102 pDCB
->pWaitingSRB
= pSRB
->pNextSRB
;
1103 pSRB
->pNextSRB
= NULL
;
1104 if (!pDCB
->pWaitingSRB
) pDCB
->pWaitLast
= NULL
;
1108 if (!dc390_StartSCSI(pACB
, pDCB
, pSRB
))
1109 dc390_Going_append (pDCB
, pSRB
);
1111 dc390_Waiting_insert (pDCB
, pSRB
);
1112 dc390_waiting_timer (pACB
, HZ
/5);
1116 /***********************************************************************
1117 * Function: static void dc390_BuildSRB (Scsi_Cmd *pcmd, PDCB pDCB,
1120 * Purpose: Prepare SRB for being sent to Device DCB w/ command *pcmd
1122 ***********************************************************************/
1124 static void dc390_BuildSRB (Scsi_Cmnd
* pcmd
, PDCB pDCB
, PSRB pSRB
)
1126 pSRB
->pSRBDCB
= pDCB
;
1128 //pSRB->ScsiCmdLen = pcmd->cmd_len;
1129 //memcpy (pSRB->CmdBlock, pcmd->cmnd, pcmd->cmd_len);
1133 pSRB
->SGcount
= (UCHAR
) pcmd
->use_sg
;
1134 pSRB
->pSegmentList
= (PSGL
) pcmd
->request_buffer
;
1136 else if( pcmd
->request_buffer
)
1139 pSRB
->pSegmentList
= (PSGL
) &pSRB
->Segmentx
;
1140 pSRB
->Segmentx
.address
= (PUCHAR
) pcmd
->request_buffer
;
1141 pSRB
->Segmentx
.length
= pcmd
->request_bufflen
;
1147 pSRB
->AdaptStatus
= 0;
1148 pSRB
->TargetStatus
= 0;
1150 if( pDCB
->DevType
!= TYPE_TAPE
)
1154 pSRB
->SRBStatus
= 0;
1157 pSRB
->TotalXferredLen
= 0;
1158 pSRB
->SGBusAddr
= 0;
1159 pSRB
->SGToBeXferLen
= 0;
1160 pSRB
->ScsiPhase
= 0;
1161 pSRB
->EndMessage
= 0;
1162 pSRB
->TagNumber
= 255;
1165 /* Put cmnd from Query to Waiting list and send next Waiting cmnd */
1166 static void dc390_Query_to_Waiting (PACB pACB
)
1172 if( pACB
->ACBFlag
& (RESET_DETECT
+RESET_DONE
+RESET_DEV
) )
1175 while (pACB
->QueryCnt
)
1177 pSRB
= dc390_Free_get ( pACB
);
1179 pcmd
= dc390_Query_get ( pACB
);
1180 if (!pcmd
) { dc390_Free_insert (pACB
, pSRB
); return; }; /* should not happen */
1181 pDCB
= dc390_findDCB (pACB
, pcmd
->target
, pcmd
->lun
);
1184 dc390_Free_insert (pACB
, pSRB
);
1185 printk (KERN_ERR
"DC390: Command in queue to non-existing device!\n");
1186 pcmd
->result
= MK_RES(DRIVER_ERROR
,DID_ERROR
,0,0);
1187 DC390_UNLOCK_ACB_NI
;
1191 dc390_BuildSRB (pcmd
, pDCB
, pSRB
);
1192 dc390_Waiting_append ( pDCB
, pSRB
);
1196 /***********************************************************************
1197 * Function : static int DC390_queue_command (Scsi_Cmnd *cmd,
1198 * void (*done)(Scsi_Cmnd *))
1200 * Purpose : enqueues a SCSI command
1202 * Inputs : cmd - SCSI command, done - callback function called on
1203 * completion, with a pointer to the command descriptor.
1205 * Returns : (depending on kernel version)
1206 * 2.0.x: always return 0
1207 * 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x
1209 * new model: return 0 if successful
1210 * return 1 if command cannot be queued (queue full)
1211 * command will be inserted in midlevel queue then ...
1213 ***********************************************************************/
1215 int DC390_queue_command (Scsi_Cmnd
*cmd
, void (* done
)(Scsi_Cmnd
*))
1220 PACB pACB
= (PACB
) cmd
->host
->hostdata
;
1223 DEBUG0(/* if(pACB->scan_devices) */ \
1224 printk(KERN_INFO
"DC390: Queue Cmd=%02x,Tgt=%d,LUN=%d (pid=%li)\n",\
1225 cmd
->cmnd
[0],cmd
->target
,cmd
->lun
,cmd
->pid
);)
1229 /* Assume BAD_TARGET; will be cleared later */
1230 cmd
->result
= DID_BAD_TARGET
<< 16;
1232 /* TODO: Change the policy: Alway accept TEST_UNIT_READY or INQUIRY
1233 * commands and alloc a DCB for the device if not yet there. DCB will
1234 * be removed in dc390_SRBdone if SEL_TIMEOUT */
1236 if( (pACB
->scan_devices
== END_SCAN
) && (cmd
->cmnd
[0] != INQUIRY
) )
1237 pACB
->scan_devices
= 0;
1239 else if( (pACB
->scan_devices
) && (cmd
->cmnd
[0] == READ_6
) )
1240 pACB
->scan_devices
= 0;
1242 if ( ( cmd
->target
>= pACB
->pScsiHost
->max_id
) ||
1243 (cmd
->lun
>= pACB
->pScsiHost
->max_lun
) )
1245 /* printk ("DC390: Ignore target %d lun %d\n",
1246 cmd->target, cmd->lun); */
1253 if( (pACB
->scan_devices
|| cmd
->cmnd
[0] == TEST_UNIT_READY
|| cmd
->cmnd
[0] == INQUIRY
) &&
1254 !(pACB
->DCBmap
[cmd
->target
] & (1 << cmd
->lun
)) )
1256 pACB
->scan_devices
= 1;
1258 dc390_initDCB( pACB
, &pDCB
, cmd
->target
, cmd
->lun
);
1261 printk (KERN_ERR
"DC390: kmalloc for DCB failed, target %02x lun %02x\n",
1262 cmd
->target
, cmd
->lun
);
1264 printk ("DC390: No DCB in queue_command!\n");
1274 else if( !(pACB
->scan_devices
) && !(pACB
->DCBmap
[cmd
->target
] & (1 << cmd
->lun
)) )
1276 printk(KERN_INFO
"DC390: Ignore target %02x lun %02x\n",
1277 cmd
->target
, cmd
->lun
);
1285 pDCB
= dc390_findDCB (pACB
, cmd
->target
, cmd
->lun
);
1287 { /* should never happen */
1288 printk (KERN_ERR
"DC390: no DCB failed, target %02x lun %02x\n",
1289 cmd
->target
, cmd
->lun
);
1291 printk ("DC390: No DCB in queuecommand (2)!\n");
1302 cmd
->scsi_done
= done
;
1305 dc390_Query_to_Waiting (pACB
);
1307 if( pACB
->QueryCnt
) /* Unsent commands ? */
1309 DEBUG0(printk ("DC390: QueryCnt != 0\n");)
1310 dc390_Query_append ( cmd
, pACB
);
1311 dc390_Waiting_process (pACB
);
1313 else if (pDCB
->pWaitingSRB
)
1315 pSRB
= dc390_Free_get ( pACB
);
1316 DEBUG0(if (!pSRB
) printk ("DC390: No free SRB but Waiting\n"); else printk ("DC390: Free SRB w/ Waiting\n");)
1317 if (!pSRB
) dc390_Query_append (cmd
, pACB
);
1320 dc390_BuildSRB (cmd
, pDCB
, pSRB
);
1321 dc390_Waiting_append (pDCB
, pSRB
);
1323 dc390_Waiting_process (pACB
);
1327 pSRB
= dc390_Free_get ( pACB
);
1328 DEBUG0(if (!pSRB
) printk ("DC390: No free SRB w/o Waiting\n"); else printk ("DC390: Free SRB w/o Waiting\n");)
1331 dc390_Query_append (cmd
, pACB
);
1332 dc390_Waiting_process (pACB
);
1336 dc390_BuildSRB (cmd
, pDCB
, pSRB
);
1337 dc390_SendSRB (pACB
, pSRB
);
1342 DEBUG1(printk (KERN_DEBUG
" ... command (pid %li) queued successfully.\n", cmd
->pid
);)
1346 /* We ignore mapping problems, as we expect everybody to respect
1347 * valid partition tables. Waiting for complaints ;-) */
1349 #ifdef CONFIG_SCSI_DC390T_TRADMAP
1351 * The next function, partsize(), is copied from scsicam.c.
1353 * This is ugly code duplication, but I didn't find another way to solve it:
1354 * We want to respect the partition table and if it fails, we apply the
1355 * DC390 BIOS heuristic. Too bad, just calling scsicam_bios_param() doesn't do
1356 * the job, because we don't know, whether the values returned are from
1357 * the part. table or determined by setsize(). Unfortunately the setsize()
1358 * values differ from the ones chosen by the DC390 BIOS.
1360 * Looking forward to seeing suggestions for a better solution! KG, 98/10/14
1362 #include <asm/unaligned.h>
1365 * Function : static int partsize(struct buffer_head *bh, unsigned long
1366 * capacity,unsigned int *cyls, unsigned int *hds, unsigned int *secs);
1368 * Purpose : to determine the BIOS mapping used to create the partition
1369 * table, storing the results in *cyls, *hds, and *secs
1371 * Returns : -1 on failure, 0 on success.
1375 static int partsize(struct buffer_head
*bh
, unsigned long capacity
,
1376 unsigned int *cyls
, unsigned int *hds
, unsigned int *secs
) {
1377 struct partition
*p
, *largest
= NULL
;
1379 int cyl
, ext_cyl
, end_head
, end_cyl
, end_sector
;
1380 unsigned int logical_end
, physical_end
, ext_physical_end
;
1383 if (*(unsigned short *) (bh
->b_data
+510) == 0xAA55) {
1384 for (largest_cyl
= -1, p
= (struct partition
*)
1385 (0x1BE + bh
->b_data
), i
= 0; i
< 4; ++i
, ++p
) {
1388 cyl
= p
->cyl
+ ((p
->sector
& 0xc0) << 2);
1389 if (cyl
> largest_cyl
) {
1397 end_cyl
= largest
->end_cyl
+ ((largest
->end_sector
& 0xc0) << 2);
1398 end_head
= largest
->end_head
;
1399 end_sector
= largest
->end_sector
& 0x3f;
1401 physical_end
= end_cyl
* (end_head
+ 1) * end_sector
+
1402 end_head
* end_sector
+ end_sector
;
1404 /* This is the actual _sector_ number at the end */
1405 logical_end
= get_unaligned(&largest
->start_sect
)
1406 + get_unaligned(&largest
->nr_sects
);
1408 /* This is for >1023 cylinders */
1409 ext_cyl
= (logical_end
-(end_head
* end_sector
+ end_sector
))
1410 /(end_head
+ 1) / end_sector
;
1411 ext_physical_end
= ext_cyl
* (end_head
+ 1) * end_sector
+
1412 end_head
* end_sector
+ end_sector
;
1414 if ((logical_end
== physical_end
) ||
1415 (end_cyl
==1023 && ext_physical_end
==logical_end
)) {
1417 *hds
= end_head
+ 1;
1418 *cyls
= capacity
/ ((end_head
+ 1) * end_sector
);
1425 /***********************************************************************
1430 * Return the disk geometry for the given SCSI device.
1431 * Respect the partition table, otherwise try own heuristic
1434 * In contrary to other externally callable funcs (DC390_), we don't lock
1435 ***********************************************************************/
1436 int DC390_bios_param (Disk
*disk
, kdev_t devno
, int geom
[])
1438 int heads
, sectors
, cylinders
;
1439 PACB pACB
= (PACB
) disk
->device
->host
->hostdata
;
1440 struct buffer_head
*bh
;
1442 int size
= disk
->capacity
;
1444 if ((bh
= bread(MKDEV(MAJOR(devno
), MINOR(devno
)&~0xf), 0, 1024)))
1446 /* try to infer mapping from partition table */
1447 ret_code
= partsize (bh
, (unsigned long) size
, (unsigned int *) geom
+ 2,
1448 (unsigned int *) geom
+ 0, (unsigned int *) geom
+ 1);
1455 cylinders
= size
/ (heads
* sectors
);
1457 if ( (pACB
->Gmode2
& GREATER_1G
) && (cylinders
> 1024) )
1461 cylinders
= size
/ (heads
* sectors
);
1466 geom
[2] = cylinders
;
1472 int DC390_bios_param (Disk
*disk
, kdev_t devno
, int geom
[])
1474 return scsicam_bios_param (disk
, devno
, geom
);
1479 void dc390_dumpinfo (PACB pACB
, PDCB pDCB
, PSRB pSRB
)
1481 USHORT pstat
; PDEVDECL1
;
1482 if (!pDCB
) pDCB
= pACB
->pActiveDCB
;
1483 if (!pSRB
&& pDCB
) pSRB
= pDCB
->pActiveSRB
;
1487 printk ("DC390: SRB: Xferred %08lx, Remain %08lx, State %08x, Phase %02x\n",
1488 pSRB
->TotalXferredLen
, pSRB
->SGToBeXferLen
, pSRB
->SRBState
,
1490 printk ("DC390: AdpaterStatus: %02x, SRB Status %02x\n", pSRB
->AdaptStatus
, pSRB
->SRBStatus
);
1492 printk ("DC390: Status of last IRQ (DMA/SC/Int/IRQ): %08x\n", dc390_laststatus
);
1493 printk ("DC390: Register dump: SCSI block:\n");
1494 printk ("DC390: XferCnt Cmd Stat IntS IRQS FFIS Ctl1 Ctl2 Ctl3 Ctl4\n");
1495 printk ("DC390: %06x %02x %02x %02x",
1496 DC390_read8(CtcReg_Low
) + (DC390_read8(CtcReg_Mid
) << 8) + (DC390_read8(CtcReg_High
) << 16),
1497 DC390_read8(ScsiCmd
), DC390_read8(Scsi_Status
), DC390_read8(Intern_State
));
1498 printk (" %02x %02x %02x %02x %02x %02x\n",
1499 DC390_read8(INT_Status
), DC390_read8(Current_Fifo
), DC390_read8(CtrlReg1
),
1500 DC390_read8(CtrlReg2
), DC390_read8(CtrlReg3
), DC390_read8(CtrlReg4
));
1501 DC390_write32 (DMA_ScsiBusCtrl
, WRT_ERASE_DMA_STAT
| EN_INT_ON_PCI_ABORT
);
1502 if (DC390_read8(Current_Fifo
) & 0x1f)
1504 printk ("DC390: FIFO:");
1505 while (DC390_read8(Current_Fifo
) & 0x1f) printk (" %02x", DC390_read8(ScsiFifo
));
1508 printk ("DC390: Register dump: DMA engine:\n");
1509 printk ("DC390: Cmd STrCnt SBusA WrkBC WrkAC Stat SBusCtrl\n");
1510 printk ("DC390: %02x %08x %08x %08x %08x %02x %08x\n",
1511 DC390_read8(DMA_Cmd
), DC390_read32(DMA_XferCnt
), DC390_read32(DMA_XferAddr
),
1512 DC390_read32(DMA_Wk_ByteCntr
), DC390_read32(DMA_Wk_AddrCntr
),
1513 DC390_read8(DMA_Status
), DC390_read32(DMA_ScsiBusCtrl
));
1514 DC390_write32 (DMA_ScsiBusCtrl
, EN_INT_ON_PCI_ABORT
);
1515 PDEVSET1
; PCI_READ_CONFIG_WORD(PDEV
, PCI_STATUS
, &pstat
);
1516 printk ("DC390: Register dump: PCI Status: %04x\n", pstat
);
1517 printk ("DC390: In case of driver trouble read linux/drivers/scsi/README.tmscsim\n");
1521 /***********************************************************************
1522 * Function : int DC390_abort (Scsi_Cmnd *cmd)
1524 * Purpose : Abort an errant SCSI command
1526 * Inputs : cmd - command to abort
1528 * Returns : 0 on success, -1 on failure.
1531 ***********************************************************************/
1533 int DC390_abort (Scsi_Cmnd
*cmd
)
1542 PACB pACB
= (PACB
) cmd
->host
->hostdata
;
1546 printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n",
1547 cmd
->pid
, cmd
->target
, cmd
->lun
);
1549 /* First scan Query list */
1550 if( pACB
->QueryCnt
)
1552 pcmd
= pACB
->pQueryHead
;
1555 /* Found: Dequeue */
1556 pACB
->pQueryHead
= pcmd
->next
;
1558 if (cmd
== pACB
->pQueryTail
) pACB
->pQueryTail
= NULL
;
1560 status
= SCSI_ABORT_SUCCESS
;
1563 for( count
= pACB
->QueryCnt
, i
=0; i
<count
-1; i
++)
1565 if( pcmd
->next
== cmd
)
1567 pcmd
->next
= cmd
->next
;
1569 if (cmd
== pACB
->pQueryTail
) pACB
->pQueryTail
= NULL
;
1571 status
= SCSI_ABORT_SUCCESS
;
1581 pDCB
= dc390_findDCB (pACB
, cmd
->target
, cmd
->lun
);
1582 if( !pDCB
) goto NOT_RUN
;
1584 /* Added 98/07/02 KG */
1586 pSRB = pDCB->pActiveSRB;
1587 if (pSRB && pSRB->pcmd == cmd )
1591 pSRB
= pDCB
->pWaitingSRB
;
1595 /* Now scan Waiting queue */
1596 if( pSRB
->pcmd
== cmd
)
1598 pDCB
->pWaitingSRB
= pSRB
->pNextSRB
;
1604 if( !(psrb
->pNextSRB
) )
1606 while( psrb
->pNextSRB
->pcmd
!= cmd
)
1608 psrb
= psrb
->pNextSRB
;
1609 if( !(psrb
->pNextSRB
) || psrb
== pSRB
)
1612 pSRB
= psrb
->pNextSRB
;
1613 psrb
->pNextSRB
= pSRB
->pNextSRB
;
1614 if( pSRB
== pDCB
->pWaitLast
)
1615 pDCB
->pWaitLast
= psrb
;
1617 dc390_Free_insert (pACB
, pSRB
);
1620 status
= SCSI_ABORT_SUCCESS
;
1624 /* SRB has already been sent ! */
1626 /* abort() is too stupid for already sent commands at the moment.
1627 * If it's called we are in trouble anyway, so let's dump some info
1628 * into the syslog at least. (KG, 98/08/20,99/06/20) */
1629 dc390_dumpinfo (pACB
, pDCB
, pSRB
);
1630 pSRB
= pDCB
->pGoingSRB
;
1631 pDCB
->DCBFlag
|= ABORT_DEV_
;
1632 /* Now for the hard part: The command is currently processed */
1633 for( count
= pDCB
->GoingSRBCnt
, i
=0; i
<count
; i
++)
1635 if( pSRB
->pcmd
!= cmd
)
1636 pSRB
= pSRB
->pNextSRB
;
1639 if( (pACB
->pActiveDCB
== pDCB
) && (pDCB
->pActiveSRB
== pSRB
) )
1641 status
= SCSI_ABORT_BUSY
;
1642 printk ("DC390: Abort current command (pid %li, SRB %p)\n",
1648 status
= SCSI_ABORT_SNOOZE
;
1655 status
= SCSI_ABORT_NOT_RUNNING
;
1658 cmd
->result
= DID_ABORT
<< 16;
1659 printk(KERN_INFO
"DC390: Aborted pid %li with status %i\n", cmd
->pid
, status
);
1661 if (cmd
->pid
== dc390_lastabortedpid
) /* repeated failure ? */
1663 /* Let's do something to help the bus getting clean again */
1664 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
1665 DC390_write8 (ScsiCmd
, DMA_COMMAND
);
1666 //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1667 //DC390_write8 (ScsiCmd, RESET_ATN_CMD);
1668 DC390_write8 (ScsiCmd
, NOP_CMD
);
1670 //DC390_read8 (INT_Status);
1671 //DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1673 sbac
= DC390_read32 (DMA_ScsiBusCtrl
);
1674 if (sbac
& SCSI_BUSY
)
1675 { /* clear BSY, SEL and ATN */
1676 printk (KERN_WARNING
"DC390: Reset SCSI device: ");
1677 //DC390_write32 (DMA_ScsiBusCtrl, (sbac | SCAM) & ~SCSI_LINES);
1679 //sbac = DC390_read32 (DMA_ScsiBusCtrl);
1680 //printk ("%08lx ", sbac);
1681 //DC390_write32 (DMA_ScsiBusCtrl, sbac & ~(SCSI_LINES | SCAM));
1683 //sbac = DC390_read32 (DMA_ScsiBusCtrl);
1684 //printk ("%08lx ", sbac);
1685 DC390_write8 (ScsiCmd
, RST_DEVICE_CMD
);
1687 DC390_write8 (ScsiCmd
, NOP_CMD
);
1688 sbac
= DC390_read32 (DMA_ScsiBusCtrl
);
1689 printk ("%08lx\n", sbac
);
1692 dc390_lastabortedpid
= cmd
->pid
;
1694 //do_DC390_Interrupt (pACB->IRQLevel, 0, 0);
1696 if (status
== SCSI_ABORT_SUCCESS
) cmd
->scsi_done(cmd
);
1702 static void dc390_ResetDevParam( PACB pACB
)
1706 pDCB
= pACB
->pLinkDCB
;
1711 pDCB
->SyncMode
&= ~SYNC_NEGO_DONE
;
1712 pDCB
->SyncPeriod
= 0;
1713 pDCB
->SyncOffset
= 0;
1715 pDCB
->CtrlR3
= FAST_CLK
;
1716 pDCB
->CtrlR4
&= NEGATE_REQACKDATA
| CTRL4_RESERVED
| NEGATE_REQACK
;
1717 pDCB
->CtrlR4
|= pACB
->glitch_cfg
;
1718 pDCB
= pDCB
->pNextDCB
;
1720 while( pdcb
!= pDCB
);
1721 pACB
->ACBFlag
&= ~(RESET_DEV
| RESET_DONE
| RESET_DETECT
);
1726 /* Moves all SRBs from Going to Waiting for all DCBs */
1727 static void dc390_RecoverSRB( PACB pACB
)
1733 pDCB
= pACB
->pLinkDCB
;
1738 cnt
= pdcb
->GoingSRBCnt
;
1739 psrb
= pdcb
->pGoingSRB
;
1740 for (i
=0; i
<cnt
; i
++)
1743 psrb
= psrb
->pNextSRB
;
1744 /* dc390_RewaitSRB( pDCB, psrb ); */
1745 if( pdcb
->pWaitingSRB
)
1747 psrb2
->pNextSRB
= pdcb
->pWaitingSRB
;
1748 pdcb
->pWaitingSRB
= psrb2
;
1752 pdcb
->pWaitingSRB
= psrb2
;
1753 pdcb
->pWaitLast
= psrb2
;
1754 psrb2
->pNextSRB
= NULL
;
1757 pdcb
->GoingSRBCnt
= 0;
1758 pdcb
->pGoingSRB
= NULL
;
1760 pdcb
= pdcb
->pNextDCB
;
1761 } while( pdcb
!= pDCB
);
1765 /***********************************************************************
1766 * Function : int DC390_reset (Scsi_Cmnd *cmd, ...)
1768 * Purpose : perform a hard reset on the SCSI bus
1770 * Inputs : cmd - command which caused the SCSI RESET
1771 * resetFlags - how hard to try
1773 * Returns : 0 on success.
1774 ***********************************************************************/
1776 int DC390_reset (Scsi_Cmnd
*cmd
, unsigned int resetFlags
)
1780 PACB pACB
= (PACB
) cmd
->host
->hostdata
;
1782 printk(KERN_INFO
"DC390: RESET ... ");
1785 if (timer_pending (&pACB
->Waiting_Timer
)) del_timer (&pACB
->Waiting_Timer
);
1786 bval
= DC390_read8 (CtrlReg1
);
1787 bval
|= DIS_INT_ON_SCSI_RST
;
1788 DC390_write8 (CtrlReg1
, bval
); /* disable IRQ on bus reset */
1790 pACB
->ACBFlag
|= RESET_DEV
;
1791 dc390_ResetSCSIBus( pACB
);
1793 dc390_ResetDevParam( pACB
);
1795 pACB
->pScsiHost
->last_reset
= jiffies
+ 3*HZ
/2
1796 + HZ
* dc390_eepromBuf
[pACB
->AdapterIndex
][EE_DELAY
];
1798 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1799 DC390_read8 (INT_Status
); /* Reset Pending INT */
1801 dc390_DoingSRB_Done( pACB
, cmd
);
1802 /* dc390_RecoverSRB (pACB); */
1803 pACB
->pActiveDCB
= NULL
;
1806 bval
= DC390_read8 (CtrlReg1
);
1807 bval
&= ~DIS_INT_ON_SCSI_RST
;
1808 DC390_write8 (CtrlReg1
, bval
); /* re-enable interrupt */
1810 dc390_Waiting_process( pACB
);
1814 return( SCSI_RESET_SUCCESS
);
1817 #include "scsiiom.c"
1820 /***********************************************************************
1821 * Function : static void dc390_initDCB()
1823 * Purpose : initialize the internal structures for a DCB (to be malloced)
1825 * Inputs : SCSI id and lun
1826 ***********************************************************************/
1828 void dc390_initDCB( PACB pACB
, PDCB
*ppDCB
, UCHAR id
, UCHAR lun
)
1834 pDCB
= kmalloc (sizeof(DC390_DCB
), GFP_ATOMIC
);
1835 DCBDEBUG(printk (KERN_INFO
"DC390: alloc mem for DCB (ID %i, LUN %i): %p\n" \
1838 *ppDCB
= pDCB
; pDCB2
= 0;
1840 if( pACB
->DCBCnt
== 0 )
1842 pACB
->pLinkDCB
= pDCB
;
1843 pACB
->pDCBRunRobin
= pDCB
;
1847 pACB
->pLastDCB
->pNextDCB
= pDCB
;
1852 pDCB
->pNextDCB
= pACB
->pLinkDCB
;
1853 pACB
->pLastDCB
= pDCB
;
1855 pDCB
->pDCBACB
= pACB
;
1856 pDCB
->TargetID
= id
;
1857 pDCB
->TargetLUN
= lun
;
1858 pDCB
->pWaitingSRB
= NULL
;
1859 pDCB
->pGoingSRB
= NULL
;
1860 pDCB
->GoingSRBCnt
= 0;
1861 pDCB
->WaitSRBCnt
= 0;
1862 pDCB
->pActiveSRB
= NULL
;
1864 pDCB
->MaxCommand
= 1;
1865 index
= pACB
->AdapterIndex
;
1868 /* Is there a corresp. LUN==0 device ? */
1870 pDCB2
= dc390_findDCB (pACB
, id
, 0);
1871 prom
= (PEEprom
) &dc390_eepromBuf
[index
][id
<< 2];
1872 /* Some values are for all LUNs: Copy them */
1873 /* In a clean way: We would have an own structure for a SCSI-ID */
1876 pDCB
->DevMode
= pDCB2
->DevMode
;
1877 pDCB
->SyncMode
= pDCB2
->SyncMode
;
1878 pDCB
->SyncPeriod
= pDCB2
->SyncPeriod
;
1879 pDCB
->SyncOffset
= pDCB2
->SyncOffset
;
1880 pDCB
->NegoPeriod
= pDCB2
->NegoPeriod
;
1882 pDCB
->CtrlR3
= pDCB2
->CtrlR3
;
1883 pDCB
->CtrlR4
= pDCB2
->CtrlR4
;
1884 pDCB
->Inquiry7
= pDCB2
->Inquiry7
;
1888 pDCB
->DevMode
= prom
->EE_MODE1
;
1890 pDCB
->SyncPeriod
= 0;
1891 pDCB
->SyncOffset
= 0;
1892 pDCB
->NegoPeriod
= (dc390_clock_period1
[prom
->EE_SPEED
] * 25) >> 2;
1894 pDCB
->CtrlR3
= FAST_CLK
;
1896 pDCB
->CtrlR4
= pACB
->glitch_cfg
| CTRL4_RESERVED
;
1897 if( dc390_eepromBuf
[index
][EE_MODE2
] & ACTIVE_NEGATION
)
1898 pDCB
->CtrlR4
|= NEGATE_REQACKDATA
| NEGATE_REQACK
;
1902 pACB
->DCBmap
[id
] |= (1 << lun
);
1903 dc390_updateDCB(pACB
, pDCB
);
1906 /***********************************************************************
1907 * Function : static void dc390_updateDCB()
1909 * Purpose : Set the configuration dependent DCB parameters
1910 ***********************************************************************/
1912 void dc390_updateDCB (PACB pACB
, PDCB pDCB
)
1914 pDCB
->SyncMode
&= EN_TAG_QUEUEING
| SYNC_NEGO_DONE
/*| EN_ATN_STOP*/;
1915 if (pDCB
->DevMode
& TAG_QUEUEING_
) {
1916 //if (pDCB->SyncMode & EN_TAG_QUEUEING) pDCB->MaxCommand = pACB->TagMaxNum;
1918 pDCB
->SyncMode
&= ~EN_TAG_QUEUEING
;
1919 pDCB
->MaxCommand
= 1;
1922 if( pDCB
->DevMode
& SYNC_NEGO_
)
1923 pDCB
->SyncMode
|= SYNC_ENABLE
;
1925 pDCB
->SyncMode
&= ~(SYNC_NEGO_DONE
| SYNC_ENABLE
);
1926 pDCB
->SyncOffset
&= ~0x0f;
1929 //if (! (pDCB->DevMode & EN_DISCONNECT_)) pDCB->SyncMode &= ~EN_ATN_STOP;
1931 pDCB
->CtrlR1
= pACB
->pScsiHost
->this_id
;
1932 if( pDCB
->DevMode
& PARITY_CHK_
)
1933 pDCB
->CtrlR1
|= PARITY_ERR_REPO
;
1937 /***********************************************************************
1938 * Function : static void dc390_updateDCBs ()
1940 * Purpose : Set the configuration dependent DCB params for all DCBs
1941 ***********************************************************************/
1943 static void dc390_updateDCBs (PACB pACB
)
1946 PDCB pDCB
= pACB
->pLinkDCB
;
1947 for (i
= 0; i
< pACB
->DCBCnt
; i
++)
1949 dc390_updateDCB (pACB
, pDCB
);
1950 pDCB
= pDCB
->pNextDCB
;
1955 /***********************************************************************
1956 * Function : static void dc390_initSRB()
1958 * Purpose : initialize the internal structures for a given SRB
1960 * Inputs : psrb - pointer to this scsi request block structure
1961 ***********************************************************************/
1963 static void __inline__
dc390_initSRB( PSRB psrb
)
1965 /* psrb->PhysSRB = virt_to_phys( psrb ); */
1969 void dc390_linkSRB( PACB pACB
)
1973 count
= pACB
->SRBCount
;
1974 for( i
=0; i
<count
; i
++)
1977 pACB
->SRB_array
[i
].pNextSRB
= &pACB
->SRB_array
[i
+1];
1979 pACB
->SRB_array
[i
].pNextSRB
= NULL
;
1980 dc390_initSRB( &pACB
->SRB_array
[i
] );
1985 /***********************************************************************
1986 * Function : static void dc390_initACB ()
1988 * Purpose : initialize the internal structures for a given SCSI host
1990 * Inputs : psh - pointer to this host adapter's structure
1991 * io_port, Irq, index: Resources and adapter index
1992 ***********************************************************************/
1994 void __init
dc390_initACB (PSH psh
, ULONG io_port
, UCHAR Irq
, UCHAR index
)
2000 psh
->can_queue
= MAX_CMD_QUEUE
;
2001 psh
->cmd_per_lun
= MAX_CMD_PER_LUN
;
2002 psh
->this_id
= (int) dc390_eepromBuf
[index
][EE_ADAPT_SCSI_ID
];
2003 psh
->io_port
= io_port
;
2004 psh
->n_io_port
= 0x80;
2006 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,50)
2007 psh
->base
= io_port
;
2009 psh
->base
= (char*)io_port
;
2011 psh
->unique_id
= io_port
;
2012 psh
->dma_channel
= -1;
2013 psh
->last_reset
= jiffies
;
2015 pACB
= (PACB
) psh
->hostdata
;
2019 pACB
->pScsiHost
= psh
;
2020 pACB
->IOPortBase
= (USHORT
) io_port
;
2021 pACB
->IRQLevel
= Irq
;
2023 DEBUG0(printk (KERN_INFO
"DC390: Adapter index %i, ID %i, IO 0x%08x, IRQ 0x%02x\n", \
2024 index
, psh
->this_id
, (int)io_port
, Irq
);)
2028 if( psh
->max_id
- 1 == dc390_eepromBuf
[index
][EE_ADAPT_SCSI_ID
] )
2031 if( dc390_eepromBuf
[index
][EE_MODE2
] & LUN_CHECK
)
2034 pACB
->pLinkDCB
= NULL
;
2035 pACB
->pDCBRunRobin
= NULL
;
2036 pACB
->pActiveDCB
= NULL
;
2037 pACB
->pFreeSRB
= pACB
->SRB_array
;
2038 pACB
->SRBCount
= MAX_SRB_CNT
;
2040 pACB
->pQueryHead
= NULL
;
2041 pACB
->AdapterIndex
= index
;
2043 psh
->this_id
= dc390_eepromBuf
[index
][EE_ADAPT_SCSI_ID
];
2044 pACB
->DeviceCnt
= 0;
2046 pACB
->TagMaxNum
= 2 << dc390_eepromBuf
[index
][EE_TAG_CMD_NUM
];
2048 pACB
->scan_devices
= 1;
2050 pACB
->Ignore_IRQ
= 0;
2051 pACB
->Gmode2
= dc390_eepromBuf
[index
][EE_MODE2
];
2052 dc390_linkSRB( pACB
);
2053 pACB
->pTmpSRB
= &pACB
->TmpSRB
;
2054 dc390_initSRB( pACB
->pTmpSRB
);
2055 for(i
=0; i
<MAX_SCSI_ID
; i
++)
2056 pACB
->DCBmap
[i
] = 0;
2057 pACB
->sel_timeout
= SEL_TIMEOUT
;
2058 pACB
->glitch_cfg
= EATER_25NS
;
2059 pACB
->Cmds
= pACB
->CmdInQ
= pACB
->CmdOutOfSRB
= 0;
2060 pACB
->SelLost
= pACB
->SelConn
= 0;
2061 init_timer (&pACB
->Waiting_Timer
);
2065 /***********************************************************************
2066 * Function : static int dc390_initAdapter ()
2068 * Purpose : initialize the SCSI chip ctrl registers
2070 * Inputs : psh - pointer to this host adapter's structure
2071 * io_port, Irq, index: Resources
2073 * Outputs: 0 on success, -1 on error
2074 ***********************************************************************/
2076 int __init
dc390_initAdapter (PSH psh
, ULONG io_port
, UCHAR Irq
, UCHAR index
)
2082 pACB
= (PACB
) psh
->hostdata
;
2084 if (check_region (io_port
, psh
->n_io_port
))
2086 printk(KERN_ERR
"DC390: register IO ports error!\n");
2090 request_region (io_port
, psh
->n_io_port
, "tmscsim");
2092 DC390_read8_ (INT_Status
, io_port
); /* Reset Pending INT */
2094 if( (i
= request_irq(Irq
, do_DC390_Interrupt
, DC390_IRQ
, "tmscsim", pACB
) ))
2096 printk(KERN_ERR
"DC390: register IRQ error!\n");
2097 release_region (io_port
, psh
->n_io_port
);
2101 if( !dc390_pACB_start
)
2104 dc390_pACB_start
= pACB
;
2105 dc390_pACB_current
= pACB
;
2106 pACB
->pNextACB
= NULL
;
2110 pACB2
= dc390_pACB_current
;
2111 dc390_pACB_current
->pNextACB
= pACB
;
2112 dc390_pACB_current
= pACB
;
2113 pACB
->pNextACB
= NULL
;
2116 DC390_write8 (CtrlReg1
, DIS_INT_ON_SCSI_RST
| psh
->this_id
); /* Disable SCSI bus reset interrupt */
2118 if (pACB
->Gmode2
& RST_SCSI_BUS
)
2120 dc390_ResetSCSIBus( pACB
);
2122 pACB
->pScsiHost
->last_reset
= jiffies
+ HZ
/2
2123 + HZ
* dc390_eepromBuf
[pACB
->AdapterIndex
][EE_DELAY
];
2125 for( i=0; i<(500 + 1000*dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]); i++ )
2130 DC390_read8 (INT_Status
); /* Reset Pending INT */
2132 DC390_write8 (Scsi_TimeOut
, SEL_TIMEOUT
); /* 250ms selection timeout */
2133 DC390_write8 (Clk_Factor
, CLK_FREQ_40MHZ
); /* Conversion factor = 0 , 40MHz clock */
2134 DC390_write8 (ScsiCmd
, NOP_CMD
); /* NOP cmd - clear command register */
2135 DC390_write8 (CtrlReg2
, EN_FEATURE
+EN_SCSI2_CMD
); /* Enable Feature and SCSI-2 */
2136 DC390_write8 (CtrlReg3
, FAST_CLK
); /* fast clock */
2137 DC390_write8 (CtrlReg4
, pACB
->glitch_cfg
| /* glitch eater */
2138 (dc390_eepromBuf
[index
][EE_MODE2
] & ACTIVE_NEGATION
) ? NEGATE_REQACKDATA
: 0); /* Negation */
2139 DC390_write8 (CtcReg_High
, 0); /* Clear Transfer Count High: ID */
2140 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
2141 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
2142 DC390_write32 (DMA_ScsiBusCtrl
, EN_INT_ON_PCI_ABORT
);
2143 dstate
= DC390_read8 (DMA_Status
);
2144 DC390_write8 (DMA_Status
, dstate
); /* clear */
2150 /***********************************************************************
2151 * Function : static int DC390_init (struct Scsi_Host *host, ...)
2153 * Purpose : initialize the internal structures for a given SCSI host
2155 * Inputs : host - pointer to this host adapter's structure
2156 * io_port - IO ports mapped to this adapter
2157 * Irq - IRQ assigned to this adpater
2158 * PDEVDECL - PCI access handle
2159 * index - Adapter index
2161 * Outputs: 0 on success, -1 on error
2163 * Note: written in capitals, because the locking is only done here,
2164 * not in DC390_detect, called from outside
2165 ***********************************************************************/
2167 static int __init
DC390_init (PSHT psht
, ULONG io_port
, UCHAR Irq
, PDEVDECL
, UCHAR index
)
2173 if (dc390_CheckEEpromCheckSum (PDEV
, index
))
2175 #ifdef CONFIG_SCSI_DC390T_NOGENSUPP
2176 printk (KERN_ERR
"DC390_init: No EEPROM found!\n");
2180 dc390_adapname
= "AM53C974";
2181 printk (KERN_INFO
"DC390_init: No EEPROM found! Trying default settings ...\n");
2182 dc390_check_for_safe_settings ();
2183 dc390_fill_with_defaults ();
2184 dc390_EEprom_Override (index
);
2185 speed
= dc390_clock_speed
[tmscsim
[1]];
2186 printk (KERN_INFO
"DC390: Used defaults: AdaptID=%i, SpeedIdx=%i (%i.%i MHz),"
2187 " DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i), DelayReset=%is\n",
2188 tmscsim
[0], tmscsim
[1], speed
/10, speed
%10,
2189 (UCHAR
)tmscsim
[2], (UCHAR
)tmscsim
[3], tmscsim
[4], 2 << (tmscsim
[4]), tmscsim
[5]);
2194 dc390_check_for_safe_settings ();
2195 dc390_EEprom_Override (index
);
2198 psh
= scsi_register( psht
, sizeof(DC390_ACB
) );
2199 if( !psh
) return( -1 );
2201 pACB
= (PACB
) psh
->hostdata
;
2206 if( !dc390_pSH_start
)
2208 dc390_pSH_start
= psh
;
2209 dc390_pSH_current
= psh
;
2213 dc390_pSH_current
->next
= psh
;
2214 dc390_pSH_current
= psh
;
2218 DEBUG0(printk(KERN_INFO
"DC390: pSH = %8x,", (UINT
) psh
);)
2219 DEBUG0(printk(" Index %02i,", index
);)
2221 dc390_initACB( psh
, io_port
, Irq
, index
);
2222 pACB
= (PACB
) psh
->hostdata
;
2226 if( !dc390_initAdapter( psh
, io_port
, Irq
, index
) )
2228 DEBUG0(printk("\nDC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
2229 (UINT
) pACB
, (UINT
) pACB
->DCBmap
, (UINT
) pACB
->SRB_array
);)
2230 DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\
2231 sizeof(DC390_ACB
), sizeof(DC390_DCB
), sizeof(DC390_SRB
) );)
2238 //dc390_pSH_start = NULL;
2239 scsi_unregister( psh
);
2246 /***********************************************************************
2247 * Function : int DC390_detect(Scsi_Host_Template *psht)
2249 * Purpose : detects and initializes AMD53C974 SCSI chips
2250 * that were autoprobed, overridden on the LILO command line,
2251 * or specified at compile time.
2253 * Inputs : psht - template for this SCSI adapter
2255 * Returns : number of host adapters detected
2257 ***********************************************************************/
2260 /* Acc. to PCI 2.1 spec it's up to the driver to enable Bus mastering:
2261 * We use pci_set_master () for 2.1.x and this func for 2.0.x: */
2262 static void __init
dc390_set_master (PDEVDECL
)
2267 PCI_READ_CONFIG_WORD (PDEV
, PCI_COMMAND
, &cmd
);
2269 if (! (cmd
& PCI_COMMAND_MASTER
)) {
2270 printk("PCI: Enabling bus mastering for device %02x:%02x\n",
2272 cmd
|= PCI_COMMAND_MASTER
;
2273 PCI_WRITE_CONFIG_WORD(PDEV
, PCI_COMMAND
, cmd
);
2275 PCI_READ_CONFIG_BYTE (PDEV
, PCI_LATENCY_TIMER
, &lat
);
2276 if (lat
< 16 /* || lat == 255 */) {
2277 printk("PCI: Setting latency timer of device %02x:%02x from %i to 64\n",
2279 PCI_WRITE_CONFIG_BYTE(PDEV
, PCI_LATENCY_TIMER
, 64);
2283 #endif /* ! NEW_PCI */
2285 static void __init
dc390_set_pci_cfg (PDEVDECL
)
2288 PCI_READ_CONFIG_WORD (PDEV
, PCI_COMMAND
, &cmd
);
2289 cmd
|= PCI_COMMAND_SERR
| PCI_COMMAND_PARITY
| PCI_COMMAND_IO
;
2290 PCI_WRITE_CONFIG_WORD (PDEV
, PCI_COMMAND
, cmd
);
2291 PCI_WRITE_CONFIG_WORD (PDEV
, PCI_STATUS
, (PCI_STATUS_SIG_SYSTEM_ERROR
| PCI_STATUS_DETECTED_PARITY
));
2295 int __init
DC390_detect (Scsi_Host_Template
*psht
)
2304 //dc390_pSHT_start = psht;
2305 dc390_pACB_start
= NULL
;
2308 while (PCI_FIND_DEVICE (PCI_VENDOR_ID_AMD
, PCI_DEVICE_ID_AMD53C974
))
2310 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,30)
2311 if (pci_enable_device (pdev
))
2314 //DC390_LOCK_IO; /* Remove this when going to new eh */
2316 DEBUG0(printk(KERN_INFO
"DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt
, (UINT
) io_port
, irq
);)
2318 if( !DC390_init(psht
, io_port
, irq
, PDEV
, dc390_adapterCnt
))
2321 dc390_set_pci_cfg (PDEV
);
2324 //DC390_UNLOCK_IO; /* Remove when going to new eh */
2327 printk (KERN_ERR
"DC390: No PCI BIOS found!\n");
2329 if (dc390_adapterCnt
)
2330 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
2331 psht
->proc_name
= "tmscsim";
2333 psht
->proc_dir
= &DC390_proc_scsi_tmscsim
;
2335 printk(KERN_INFO
"DC390: %i adapters found\n", dc390_adapterCnt
);
2337 return( dc390_adapterCnt
);
2341 /***********************************************************************
2342 * Functions: dc390_inquiry(), dc390_inquiry_done()
2344 * Purpose: When changing speed etc., we have to issue an INQUIRY
2345 * command to make sure, we agree upon the nego parameters
2347 ***********************************************************************/
2349 static void dc390_inquiry_done (Scsi_Cmnd
* cmd
)
2351 printk (KERN_INFO
"DC390: INQUIRY (ID %02x LUN %02x) returned %08x\n",
2352 cmd
->target
, cmd
->lun
, cmd
->result
);
2355 PACB pACB
= (PACB
)cmd
->host
->hostdata
;
2356 PDCB pDCB
= dc390_findDCB (pACB
, cmd
->target
, cmd
->lun
);
2357 printk ("DC390: Unsetting DsCn, Sync and TagQ!\n");
2360 pDCB
->DevMode
&= ~(SYNC_NEGO_
| TAG_QUEUEING_
| EN_DISCONNECT_
);
2361 dc390_updateDCB (pACB
, pDCB
);
2367 void dc390_inquiry (PACB pACB
, PDCB pDCB
)
2371 cmd
= kmalloc (sizeof(Scsi_Cmnd
) + 256, GFP_ATOMIC
);
2372 if (!cmd
) { printk ("DC390: kmalloc failed in inquiry!\n"); return; };
2373 buffer
= (char*)cmd
+ sizeof(Scsi_Cmnd
);
2375 memset (cmd
, 0, sizeof(Scsi_Cmnd
) + 256);
2376 cmd
->cmnd
[0] = INQUIRY
;
2377 cmd
->cmnd
[1] = (pDCB
->TargetLUN
<< 5) & 0xe0;
2378 cmd
->cmnd
[4] = 0xff;
2380 cmd
->cmd_len
= 6; cmd
->old_cmd_len
= 6;
2381 cmd
->host
= pACB
->pScsiHost
;
2382 cmd
->target
= pDCB
->TargetID
;
2383 cmd
->lun
= pDCB
->TargetLUN
;
2384 cmd
->serial_number
= 1;
2387 cmd
->buffer
= buffer
;
2388 cmd
->request_bufflen
= 128;
2389 cmd
->request_buffer
= &buffer
[128];
2390 cmd
->done
= dc390_inquiry_done
;
2391 cmd
->scsi_done
= dc390_inquiry_done
;
2392 cmd
->timeout_per_command
= HZ
;
2394 cmd
->request
.rq_status
= RQ_SCSI_BUSY
;
2396 pDCB
->SyncMode
&= ~SYNC_NEGO_DONE
;
2397 printk (KERN_INFO
"DC390: Queue INQUIRY command to dev ID %02x LUN %02x\n",
2398 pDCB
->TargetID
, pDCB
->TargetLUN
);
2399 DC390_queue_command (cmd
, dc390_inquiry_done
);
2402 /***********************************************************************
2403 * Functions: dc390_sendstart(), dc390_sendstart_done()
2405 * Purpose: When changing speed etc., we have to issue an INQUIRY
2406 * command to make sure, we agree upon the nego parameters
2408 ***********************************************************************/
2410 static void dc390_sendstart_done (Scsi_Cmnd
* cmd
)
2412 printk (KERN_INFO
"DC390: SENDSTART (ID %02x LUN %02x) returned %08x\n",
2413 cmd
->target
, cmd
->lun
, cmd
->result
);
2417 void dc390_sendstart (PACB pACB
, PDCB pDCB
)
2421 cmd
= kmalloc (sizeof(Scsi_Cmnd
) + 256, GFP_ATOMIC
);
2422 if (!cmd
) { printk ("DC390: kmalloc failed in sendstart!\n"); return; };
2423 buffer
= (char*)cmd
+ sizeof(Scsi_Cmnd
);
2425 memset (cmd
, 0, sizeof(Scsi_Cmnd
) + 256);
2426 cmd
->cmnd
[0] = 0x1b; /* START_STOP_UNIT */
2427 cmd
->cmnd
[1] = (pDCB
->TargetLUN
<< 5) & 0xe0;
2428 cmd
->cmnd
[4] = 0x01; /* START */
2430 cmd
->cmd_len
= 6; cmd
->old_cmd_len
= 6;
2431 cmd
->host
= pACB
->pScsiHost
;
2432 cmd
->target
= pDCB
->TargetID
;
2433 cmd
->lun
= pDCB
->TargetLUN
;
2434 cmd
->serial_number
= 1;
2437 cmd
->buffer
= buffer
;
2438 cmd
->request_bufflen
= 128;
2439 cmd
->request_buffer
= &buffer
[128];
2440 cmd
->done
= dc390_sendstart_done
;
2441 cmd
->scsi_done
= dc390_sendstart_done
;
2442 cmd
->timeout_per_command
= 5*HZ
;
2444 cmd
->request
.rq_status
= RQ_SCSI_BUSY
;
2446 pDCB
->SyncMode
&= ~SYNC_NEGO_DONE
;
2447 printk (KERN_INFO
"DC390: Queue SEND_START command to dev ID %02x LUN %02x\n",
2448 pDCB
->TargetID
, pDCB
->TargetLUN
);
2449 DC390_queue_command (cmd
, dc390_sendstart_done
);
2452 /********************************************************************
2453 * Function: dc390_set_info()
2455 * Purpose: Change adapter config
2457 * Strings are parsed similar to the output of tmscsim_proc_info ()
2458 * '-' means no change
2459 *******************************************************************/
2461 static int dc390_scanf (char** p1
, char** p2
, int* var
)
2464 *var
= simple_strtoul (*p2
, p1
, 10);
2465 if (*p2
== *p1
) return -1;
2466 *p1
= strtok (0, " \t\n:=,;.");
2470 #define SCANF(p1, p2, var, min, max) \
2471 if (dc390_scanf (&p1, &p2, &var)) goto einv; \
2472 else if (var<min || var>max) goto einv2
2474 static int dc390_yesno (char** p
, char* var
, char bmask
)
2478 case 'Y': *var
|= bmask
; break;
2479 case 'N': *var
&= ~bmask
; break;
2483 *p
= strtok (0, " \t\n:=,;");
2487 #define YESNO(p, var, bmask) \
2488 if (dc390_yesno (&p, &var, bmask)) goto einv; \
2489 else dc390_updateDCB (pACB, pDCB); \
2492 static int dc390_search (char **p1
, char **p2
, char *var
, char* txt
, int max
, int scale
, char* ign
)
2495 if (! memcmp (*p1
, txt
, strlen(txt
)))
2497 *p2
= strtok (0, " \t\n:=,;");
2498 if (!*p2
) return -1;
2499 dum
= simple_strtoul (*p2
, p1
, 10);
2500 if (*p2
== *p1
) return -1;
2501 if (dum
>= 0 && dum
<= max
)
2502 { *var
= (dum
* 100) / scale
; }
2504 *p1
= strtok (0, " \t\n:=,;");
2505 if (*ign
&& *p1
&& strlen(*p1
) >= strlen(ign
) &&
2506 !(memcmp (*p1
, ign
, strlen(ign
))))
2507 *p1
= strtok (0, " \t\n:=,;");
2513 #define SEARCH(p1, p2, var, txt, max) \
2514 if (dc390_search (&p1, &p2, (PUCHAR)(&var), txt, max, 100, "")) goto einv2; \
2515 else if (!p1) goto ok2
2517 #define SEARCH2(p1, p2, var, txt, max, scale) \
2518 if (dc390_search (&p1, &p2, &var, txt, max, scale, "")) goto einv2; \
2519 else if (!p1) goto ok2
2521 #define SEARCH3(p1, p2, var, txt, max, scale, ign) \
2522 if (dc390_search (&p1, &p2, &var, txt, max, scale, ign)) goto einv2; \
2523 else if (!p1) goto ok2
2526 #ifdef DC390_PARSEDEBUG
2527 static char _prstr
[256];
2528 char* prstr (char* p
, char* e
)
2532 if (*p
== 0) { *c
++ = ':'; p
++; }
2533 else if (*p
== 10) { *c
++ = '\\'; *c
++ = 'n'; p
++; }
2540 int dc390_set_info (char *buffer
, int length
, PACB pACB
)
2542 char *pos
= buffer
, *p0
= buffer
;
2543 char needs_inquiry
= 0;
2546 PDCB pDCB
= pACB
->pLinkDCB
;
2554 /* Don't use kernel toupper, because of 2.0.x bug: ctmp unexported */
2556 { if (*pos
>='a' && *pos
<= 'z') *pos
= *pos
+ 'A' - 'a'; pos
++; };
2558 /* We should protect __strtok ! */
2559 /* spin_lock (strtok_lock); */
2562 pos
= strtok (buffer
, " \t:\n=,;");
2566 if (!memcmp (pos
, "RESET", 5)) goto reset
;
2567 else if (!memcmp (pos
, "INQUIRY", 7)) goto inquiry
;
2568 else if (!memcmp (pos
, "REMOVE", 6)) goto remove
;
2569 else if (!memcmp (pos
, "ADD", 3)) goto add
;
2570 else if (!memcmp (pos
, "START", 5)) goto start
;
2571 else if (!memcmp (pos
, "DUMP", 4)) goto dump
;
2575 /* Device config line */
2576 int dev
, id
, lun
; char* pdec
;
2579 SCANF (pos
, p0
, dev
, 0, pACB
->DCBCnt
-1);
2580 if (pos
) { SCANF (pos
, p0
, id
, 0, 7); } else goto einv
;
2581 if (pos
) { SCANF (pos
, p0
, lun
, 0, 7); } else goto einv
;
2582 if (!pos
) goto einv
;
2584 PARSEDEBUG(printk (KERN_INFO
"DC390: config line %i %i %i:\"%s\"\n", dev
, id
, lun
, prstr (pos
, &buffer
[length
]));)
2585 pDCB
= pACB
->pLinkDCB
;
2586 for (dum
= 0; dum
< dev
; dum
++) pDCB
= pDCB
->pNextDCB
;
2588 if (pDCB
->TargetID
!= id
|| pDCB
->TargetLUN
!= lun
)
2590 printk (KERN_ERR
"DC390: no such device: Idx=%02i ID=%02i LUN=%02i\n",
2595 if (pDCB
->pWaitingSRB
|| pDCB
->pGoingSRB
)
2597 printk ("DC390: Cannot change dev (%i-%i) cfg: Pending requests\n",
2598 pDCB
->TargetID
, pDCB
->TargetLUN
);
2602 olddevmode
= pDCB
->DevMode
;
2603 YESNO (pos
, pDCB
->DevMode
, PARITY_CHK_
);
2605 YESNO (pos
, pDCB
->DevMode
, SYNC_NEGO_
);
2606 if ((olddevmode
& SYNC_NEGO_
) == (pDCB
->DevMode
& SYNC_NEGO_
)) needs_inquiry
--;
2608 YESNO (pos
, pDCB
->DevMode
, EN_DISCONNECT_
);
2609 if ((olddevmode
& EN_DISCONNECT_
) == (pDCB
->DevMode
& EN_DISCONNECT_
)) needs_inquiry
--;
2610 YESNO (pos
, pDCB
->DevMode
, SEND_START_
);
2612 YESNO (pos
, pDCB
->DevMode
, TAG_QUEUEING_
);
2613 if ((olddevmode
& TAG_QUEUEING_
) == (pDCB
->DevMode
& TAG_QUEUEING_
)) needs_inquiry
--;
2615 dc390_updateDCB (pACB
, pDCB
);
2618 olddevmode
= pDCB
->NegoPeriod
;
2619 /* Look for decimal point (Speed) */
2621 while (pdec
++ < &buffer
[length
]) if (*pdec
== '.') break;
2625 SCANF (pos
, p0
, dum
, 72, 800);
2626 pDCB
->NegoPeriod
= dum
>> 2;
2627 if (pDCB
->NegoPeriod
!= olddevmode
) needs_inquiry
++;
2629 if (memcmp (pos
, "NS", 2) == 0) pos
= strtok (0, " \t\n:=,;.");
2631 else pos
= strtok (0, " \t\n:=,;.");
2634 /* Sync Speed in MHz */
2637 SCANF (pos
, p0
, dum
, 1, 13);
2638 pDCB
->NegoPeriod
= (1000/dum
) >> 2;
2639 if (pDCB
->NegoPeriod
!= olddevmode
&& !pos
) needs_inquiry
++;
2645 dum
= simple_strtoul (pos
, &p0
, 10) * 10;
2646 for (; p0
-pos
> 1; p0
--) dum
/= 10;
2647 pDCB
->NegoPeriod
= (100000/(100*dumold
+ dum
)) >> 2;
2648 if (pDCB
->NegoPeriod
< 19) pDCB
->NegoPeriod
= 19;
2649 pos
= strtok (0, " \t\n:=,;");
2652 if (*pos
== 'M') pos
= strtok (0, " \t\n:=,;");
2653 if (pDCB
->NegoPeriod
!= olddevmode
) needs_inquiry
++;
2655 else pos
= strtok (0, " \t\n:=,;");
2656 /* dc390_updateDCB (pACB, pDCB); */
2659 olddevmode
= pDCB
->SyncOffset
;
2663 SCANF (pos
, p0
, dum
, 0, 0x0f);
2664 pDCB
->SyncOffset
= dum
;
2665 if (pDCB
->SyncOffset
> olddevmode
) needs_inquiry
++;
2667 else pos
= strtok (0, " \t\n:=,;");
2669 dc390_updateDCB (pACB
, pDCB
);
2671 //olddevmode = pDCB->MaxCommand;
2672 /* MaxCommand (Tags) */
2675 SCANF (pos
, p0
, dum
, 1, 32 /*pACB->TagMaxNum*/);
2676 if (pDCB
->SyncMode
& EN_TAG_QUEUEING
)
2677 pDCB
->MaxCommand
= dum
;
2678 else printk (KERN_INFO
"DC390: Can't set MaxCmd larger than one without Tag Queueing!\n");
2680 else pos
= strtok (0, " \t\n:=,;");
2685 char* p1
= pos
; UCHAR dum
, newadaptid
;
2686 PARSEDEBUG(printk (KERN_INFO
"DC390: chg adapt cfg \"%s\"\n", prstr (pos
, &buffer
[length
]));)
2687 dum
= GLITCH_TO_NS (pACB
->glitch_cfg
);
2688 /* Adapter setting */
2689 SEARCH (pos
, p0
, pACB
->pScsiHost
->max_id
, "MAXID", 8);
2690 SEARCH (pos
, p0
, pACB
->pScsiHost
->max_lun
, "MAXLUN", 8);
2691 SEARCH (pos
, p0
, newadaptid
, "ADAPTERID", 7);
2692 SEARCH (pos
, p0
, pACB
->TagMaxNum
, "TAGMAXNUM", 32);
2693 SEARCH (pos
, p0
, pACB
->ACBFlag
, "ACBFLAG", 255);
2694 SEARCH3 (pos
, p0
, dum
, "GLITCHEATER", 40, 1000, "NS");
2695 SEARCH3 (pos
, p0
, pACB
->sel_timeout
, "SELTIMEOUT", 400, 163, "MS");
2696 SEARCH3 (pos
, p0
, dc390_eepromBuf
[pACB
->AdapterIndex
][EE_DELAY
], "DELAYRESET", 180, 100, "S");
2698 pACB
->glitch_cfg
= NS_TO_GLITCH (dum
);
2699 if (pACB
->sel_timeout
< 60) pACB
->sel_timeout
= 60;
2700 DC390_write8 (Scsi_TimeOut
, pACB
->sel_timeout
);
2701 if (newadaptid
!= pACB
->pScsiHost
->this_id
)
2703 pACB
->pScsiHost
->this_id
= newadaptid
;
2704 dc390_ResetDevParam (pACB
);
2706 //dum = 0; while (1 << dum <= pACB->TagMaxNum) dum ++;
2707 //pACB->TagMaxNum &= (1 << --dum);
2708 dc390_updateDCBs (pACB
);
2709 // All devs should be INQUIRED now
2710 if (pos
== p1
) goto einv
;
2715 /* spin_unlock (strtok_lock); */
2718 { dc390_updateDCB (pACB
, pDCB
); dc390_inquiry (pACB
, pDCB
); };
2725 /* spin_unlock (strtok_lock); */
2728 printk (KERN_WARNING
"DC390: parse error near \"%s\"\n", (pos
? pos
: "NULL"));
2733 Scsi_Cmnd cmd
; cmd
.host
= pACB
->pScsiHost
;
2734 printk (KERN_WARNING
"DC390: Driver reset requested!\n");
2736 DC390_reset (&cmd
, 0);
2743 dc390_dumpinfo (pACB
, 0, 0);
2751 pos
= strtok (0, " \t\n.:;="); if (!pos
) goto einv
;
2752 dev
= simple_strtoul (pos
, &p0
, 10);
2753 if (dev
>= pACB
->DCBCnt
) goto einv_dev
;
2754 for (dum
= 0; dum
< dev
; dum
++) pDCB
= pDCB
->pNextDCB
;
2755 printk (KERN_NOTICE
" DC390: Issue INQUIRY command to Dev(Idx) %i SCSI ID %i LUN %i\n",
2756 dev
, pDCB
->TargetID
, pDCB
->TargetLUN
);
2758 dc390_inquiry (pACB
, pDCB
);
2765 pos
= strtok (0, " \t\n.:;="); if (!pos
) goto einv
;
2766 dev
= simple_strtoul (pos
, &p0
, 10);
2767 if (dev
>= pACB
->DCBCnt
) goto einv_dev
;
2768 for (dum
= 0; dum
< dev
; dum
++) pDCB
= pDCB
->pNextDCB
;
2769 printk (KERN_NOTICE
" DC390: Remove DCB for Dev(Idx) %i SCSI ID %i LUN %i\n",
2770 dev
, pDCB
->TargetID
, pDCB
->TargetLUN
);
2771 /* TO DO: We should make sure no pending commands are left */
2772 dc390_remove_dev (pACB
, pDCB
);
2781 pos
= strtok (0, " \t\n.:;=");
2782 if (pos
) { SCANF (pos
, p0
, id
, 0, 7); } else goto einv
;
2783 if (pos
) { SCANF (pos
, p0
, lun
, 0, 7); } else goto einv
;
2784 pDCB
= dc390_findDCB (pACB
, id
, lun
);
2785 if (pDCB
) { printk ("DC390: ADD: Device already existing\n"); goto einv
; };
2786 dc390_initDCB (pACB
, &pDCB
, id
, lun
);
2788 dc390_inquiry (pACB
, pDCB
);
2796 pos
= strtok (0, " \t\n.:;=");
2797 if (pos
) { SCANF (pos
, p0
, id
, 0, 7); } else goto einv
;
2798 if (pos
) { SCANF (pos
, p0
, lun
, 0, 7); } else goto einv
;
2799 pDCB
= dc390_findDCB (pACB
, id
, lun
);
2800 if (pDCB
) printk ("DC390: SendStart: Device already existing ...\n");
2801 else dc390_initDCB (pACB
, &pDCB
, id
, lun
);
2803 dc390_sendstart (pACB
, pDCB
);
2804 dc390_inquiry (pACB
, pDCB
);
2810 printk (KERN_WARNING
"DC390: Ignore cmnd to illegal Dev(Idx) %i. Valid range: 0 - %i.\n",
2811 dev
, pACB
->DCBCnt
- 1);
2823 /********************************************************************
2824 * Function: DC390_proc_info(char* buffer, char **start,
2825 * off_t offset, int length, int hostno, int inout)
2827 * Purpose: return SCSI Adapter/Device Info
2829 * Input: buffer: Pointer to a buffer where to write info
2832 * hostno: Host adapter index
2833 * inout : Read (=0) or set(!=0) info
2835 * Output: buffer: contains info
2836 * length; length of info in buffer
2838 * return value: length
2840 ********************************************************************/
2843 #define SPRINTF(args...) pos += sprintf(pos, ## args)
2846 if (YN) SPRINTF(" Yes "); \
2847 else SPRINTF(" No ")
2850 int DC390_proc_info (char *buffer
, char **start
,
2851 off_t offset
, int length
, int hostno
, int inout
)
2861 pACB
= dc390_pACB_start
;
2863 while(pACB
!= (PACB
)-1)
2865 shpnt
= pACB
->pScsiHost
;
2866 if (shpnt
->host_no
== hostno
) break;
2867 pACB
= pACB
->pNextACB
;
2870 if (pACB
== (PACB
)-1) return(-ESRCH
);
2871 if(!shpnt
) return(-ESRCH
);
2873 if(inout
) /* Has data been written to the file ? */
2874 return dc390_set_info(buffer
, length
, pACB
);
2876 SPRINTF("Tekram DC390/AM53C974 PCI SCSI Host Adapter, ");
2877 SPRINTF("Driver Version %s\n", DC390_VERSION
);
2881 SPRINTF("SCSI Host Nr %i, ", shpnt
->host_no
);
2882 SPRINTF("%s Adapter Nr %i\n", dc390_adapname
, pACB
->AdapterIndex
);
2883 SPRINTF("IOPortBase 0x%04x, ", pACB
->IOPortBase
);
2884 SPRINTF("IRQ %02i\n", pACB
->IRQLevel
);
2886 SPRINTF("MaxID %i, MaxLUN %i, ", shpnt
->max_id
, shpnt
->max_lun
);
2887 SPRINTF("AdapterID %i, SelTimeout %i ms, DelayReset %i s\n",
2888 shpnt
->this_id
, (pACB
->sel_timeout
*164)/100,
2889 dc390_eepromBuf
[pACB
->AdapterIndex
][EE_DELAY
]);
2891 SPRINTF("TagMaxNum %i, Status 0x%02x, ACBFlag 0x%02x, GlitchEater %i ns\n",
2892 pACB
->TagMaxNum
, pACB
->status
, pACB
->ACBFlag
, GLITCH_TO_NS(pACB
->glitch_cfg
)*12);
2894 SPRINTF("Statistics: Cmnds %li, Cmnds not sent directly %i, Out of SRB conds %i\n",
2895 pACB
->Cmds
, pACB
->CmdInQ
, pACB
->CmdOutOfSRB
);
2896 SPRINTF(" Lost arbitrations %i, Sel. connected %i, Connected: %s\n",
2897 pACB
->SelLost
, pACB
->SelConn
, pACB
->Connected
? "Yes": "No");
2899 SPRINTF("Nr of attached devices: %i, Nr of DCBs: %i\n", pACB
->DeviceCnt
, pACB
->DCBCnt
);
2900 SPRINTF("Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x\n",
2901 pACB
->DCBmap
[0], pACB
->DCBmap
[1], pACB
->DCBmap
[2], pACB
->DCBmap
[3],
2902 pACB
->DCBmap
[4], pACB
->DCBmap
[5], pACB
->DCBmap
[6], pACB
->DCBmap
[7]);
2904 SPRINTF("Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs MaxCmd\n");
2906 pDCB
= pACB
->pLinkDCB
;
2907 for (dev
= 0; dev
< pACB
->DCBCnt
; dev
++)
2909 SPRINTF("%02i %02i %02i ", dev
, pDCB
->TargetID
, pDCB
->TargetLUN
);
2910 YESNO(pDCB
->DevMode
& PARITY_CHK_
);
2911 YESNO(pDCB
->SyncMode
& SYNC_NEGO_DONE
);
2912 YESNO(pDCB
->DevMode
& EN_DISCONNECT_
);
2913 YESNO(pDCB
->DevMode
& SEND_START_
);
2914 YESNO(pDCB
->SyncMode
& EN_TAG_QUEUEING
);
2915 if (pDCB
->SyncOffset
& 0x0f)
2917 int sp
= pDCB
->SyncPeriod
; if (! (pDCB
->CtrlR3
& FAST_SCSI
)) sp
++;
2918 SPRINTF(" %03i ns ", (pDCB
->NegoPeriod
) << 2);
2919 spd
= 40/(sp
); spd1
= 40%(sp
);
2920 spd1
= (spd1
* 10 + sp
/2) / (sp
);
2921 SPRINTF(" %2i.%1i M %02i", spd
, spd1
, (pDCB
->SyncOffset
& 0x0f));
2923 else SPRINTF(" (%03i ns) ", (pDCB
->NegoPeriod
) << 2);
2924 /* Add more info ...*/
2925 SPRINTF (" %02i\n", pDCB
->MaxCommand
);
2926 pDCB
= pDCB
->pNextDCB
;
2928 SPRINTF ("Commands in Queues: Query: %li:", pACB
->QueryCnt
);
2929 for (pcmd
= pACB
->pQueryHead
; pcmd
; pcmd
= pcmd
->next
)
2930 SPRINTF (" %li", pcmd
->pid
);
2931 if (timer_pending(&pACB
->Waiting_Timer
)) SPRINTF ("Waiting queue timer running\n");
2932 else SPRINTF ("\n");
2933 pDCB
= pACB
->pLinkDCB
;
2935 for (dev
= 0; dev
< pACB
->DCBCnt
; dev
++)
2938 if (pDCB
->WaitSRBCnt
)
2939 SPRINTF ("DCB (%02i-%i): Waiting: %i:", pDCB
->TargetID
, pDCB
->TargetLUN
,
2941 for (pSRB
= pDCB
->pWaitingSRB
; pSRB
; pSRB
= pSRB
->pNextSRB
)
2942 SPRINTF(" %li", pSRB
->pcmd
->pid
);
2943 if (pDCB
->GoingSRBCnt
)
2944 SPRINTF ("\nDCB (%02i-%i): Going : %i:", pDCB
->TargetID
, pDCB
->TargetLUN
,
2946 for (pSRB
= pDCB
->pGoingSRB
; pSRB
; pSRB
= pSRB
->pNextSRB
)
2947 #if 0 //def DC390_DEBUGTRACE
2948 SPRINTF(" %s\n ", pSRB
->debugtrace
);
2950 SPRINTF(" %li", pSRB
->pcmd
->pid
);
2952 if (pDCB
->WaitSRBCnt
|| pDCB
->GoingSRBCnt
) SPRINTF ("\n");
2953 pDCB
= pDCB
->pNextDCB
;
2956 #ifdef DC390_DEBUGDCB
2957 SPRINTF ("DCB list for ACB %p:\n", pACB
);
2958 pDCB
= pACB
->pLinkDCB
;
2959 SPRINTF ("%p", pDCB
);
2960 for (dev
= 0; dev
< pACB
->DCBCnt
; dev
++, pDCB
=pDCB
->pNextDCB
)
2961 SPRINTF ("->%p", pDCB
->pNextDCB
);
2967 *start
= buffer
+ offset
;
2969 if (pos
- buffer
< offset
)
2971 else if (pos
- buffer
- offset
< length
)
2972 return pos
- buffer
- offset
;
2982 /***********************************************************************
2983 * Function : static int dc390_shutdown (struct Scsi_Host *host)
2985 * Purpose : does a clean (we hope) shutdown of the SCSI chip.
2986 * Use prior to dumping core, unloading the driver, etc.
2988 * Returns : 0 on success
2989 ***********************************************************************/
2990 static int dc390_shutdown (struct Scsi_Host
*host
)
2993 PACB pACB
= (PACB
)(host
->hostdata
);
2995 /* pACB->soft_reset(host); */
2997 printk(KERN_INFO
"DC390: shutdown\n");
2999 pACB
->ACBFlag
= RESET_DEV
;
3000 bval
= DC390_read8 (CtrlReg1
);
3001 bval
|= DIS_INT_ON_SCSI_RST
;
3002 DC390_write8 (CtrlReg1
, bval
); /* disable interrupt */
3003 if (pACB
->Gmode2
& RST_SCSI_BUS
)
3004 dc390_ResetSCSIBus (pACB
);
3006 if (timer_pending (&pACB
->Waiting_Timer
)) del_timer (&pACB
->Waiting_Timer
);
3010 void dc390_freeDCBs (struct Scsi_Host
*host
)
3013 PACB pACB
= (PACB
)(host
->hostdata
);
3015 pDCB
= pACB
->pLinkDCB
;
3019 nDCB
= pDCB
->pNextDCB
;
3020 DCBDEBUG(printk (KERN_INFO
"DC390: Free DCB (ID %i, LUN %i): %p\n",\
3021 pDCB
->TargetID
, pDCB
->TargetLUN
, pDCB
);)
3023 dc390_remove_dev (pACB
, pDCB
);
3025 } while (pDCB
&& pACB
->pLinkDCB
);
3029 int DC390_release (struct Scsi_Host
*host
)
3031 DC390_AFLAGS DC390_IFLAGS
3032 PACB pACB
= (PACB
)(host
->hostdata
);
3037 /* TO DO: We should check for outstanding commands first. */
3038 dc390_shutdown (host
);
3040 if (host
->irq
!= IRQ_NONE
)
3042 DEBUG0(printk(KERN_INFO
"DC390: Free IRQ %i\n",host
->irq
);)
3043 free_irq (host
->irq
, pACB
);
3046 release_region(host
->io_port
,host
->n_io_port
);
3047 dc390_freeDCBs (host
);
3052 #endif /* def MODULE */
3054 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,99)
3055 static Scsi_Host_Template driver_template
= DC390_T
;
3056 #include "scsi_module.c"
3057 #elif defined(MODULE)
3058 Scsi_Host_Template driver_template
= DC390_T
;
3059 #include "scsi_module.c"