Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / scsi / tmscsim.c
blob5d2c5c46759d9f4eaaaee165718a6d32088ff933
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 ***********************************************************************/
14 /* HISTORY: *
15 * *
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 *
31 * than 1GB *
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)*
42 * reworked locking *
43 * 1.20b 98/05/12 KG bugs: version, kfree, _ctmp *
44 * debug output *
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 *
75 * functional (!) *
76 * 1.20r 98/06/30 KG Debug macros, allow disabling DsCn, set *
77 * BIT4 in CtrlR4, EN_PAGE_INT, 2.0 module *
78 * param -1 fixed. *
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 *
110 * when connected. *
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*
122 * cleaned. *
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 *
128 * appropriate *
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 */
172 /* DEBUG options */
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 */
181 #ifdef DC390_DEBUG0
182 # define DEBUG0(x) x;
183 #else
184 # define DEBUG0(x)
185 #endif
186 #ifdef DC390_DEBUG1
187 # define DEBUG1(x) x;
188 #else
189 # define DEBUG1(x)
190 #endif
191 #ifdef DC390_DCBDEBUG
192 # define DCBDEBUG(x) x;
193 #else
194 # define DCBDEBUG(x)
195 #endif
196 #ifdef DC390_PARSEDEBUG
197 # define PARSEDEBUG(x) x;
198 #else
199 # define PARSEDEBUG(x)
200 #endif
201 #ifdef DC390_REMOVABLEDEBUG
202 # define REMOVABLEDEBUG(x) x;
203 #else
204 # define REMOVABLEDEBUG(x)
205 #endif
206 #define DCBDEBUG1(x)
208 /* Includes */
209 #ifdef MODULE
210 # include <linux/module.h>
211 #endif
213 #include <asm/dma.h>
214 #include <asm/io.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>
232 #include "scsi.h"
233 #include "hosts.h"
234 #include "constants.h"
235 #include "sd.h"
236 #include <linux/stat.h>
237 #include <scsi/scsicam.h>
239 #include "dc390.h"
241 #define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI
243 /* Locking */
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.
253 /* spinlock things
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>
266 #else
267 # include <asm/spinlock.h>
268 #endif
269 #endif
272 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
273 # define USE_SPINLOCKS 1
274 # define NEW_PCI 1
275 #else
276 # undef NEW_PCI
277 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30)
278 # define USE_SPINLOCKS 2
279 # endif
280 #endif
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);
293 #endif
295 #ifdef USE_SPINLOCKS
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; };
301 # else
302 # define DC390_LOCKA_INIT
303 # endif
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))
324 # else
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; };
330 # else
331 # define DC390_LOCKA_INIT
332 # endif
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 */
367 # endif /* 2 */
368 # endif /* 3 */
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
386 #endif /* def */
389 /* These macros are used for uniform access to 2.0.x and 2.1.x PCI config space*/
391 #ifdef NEW_PCI
392 # define PDEV pdev
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
408 #else
409 # define PCI_GET_IO_AND_IRQ io_port = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; irq = pdev->irq
410 #endif
411 #else
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); \
429 io_port &= 0xfffe; \
430 if (error) { printk (KERN_ERR "DC390_detect: Error reading PCI config registers!\n"); continue; }
431 #endif
433 #include "tmscsim.h"
435 #ifndef __init
436 # define __init
437 #endif
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);
472 #ifdef MODULE
473 static int DC390_release(struct Scsi_Host *host);
474 static int dc390_shutdown (struct Scsi_Host *host);
475 #endif
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)");
493 # endif
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");
499 #endif
501 static PVOID dc390_phase0[]={
502 dc390_DataOut_0,
503 dc390_DataIn_0,
504 dc390_Command_0,
505 dc390_Status_0,
506 dc390_Nop_0,
507 dc390_Nop_0,
508 dc390_MsgOut_0,
509 dc390_MsgIn_0,
510 dc390_Nop_1
513 static PVOID dc390_phase1[]={
514 dc390_DataOutPhase,
515 dc390_DataInPhase,
516 dc390_CommandPhase,
517 dc390_StatusPhase,
518 dc390_Nop_0,
519 dc390_Nop_0,
520 dc390_MsgOutPhase,
521 dc390_MsgInPhase,
522 dc390_Nop_1
525 #ifdef DC390_DEBUG1
526 static char* dc390_p0_str[] = {
527 "dc390_DataOut_0",
528 "dc390_DataIn_0",
529 "dc390_Command_0",
530 "dc390_Status_0",
531 "dc390_Nop_0",
532 "dc390_Nop_0",
533 "dc390_MsgOut_0",
534 "dc390_MsgIn_0",
535 "dc390_Nop_1"
538 static char* dc390_p1_str[] = {
539 "dc390_DataOutPhase",
540 "dc390_DataInPhase",
541 "dc390_CommandPhase",
542 "dc390_StatusPhase",
543 "dc390_Nop_0",
544 "dc390_Nop_0",
545 "dc390_MsgOutPhase",
546 "dc390_MsgInPhase",
547 "dc390_Nop_1"
549 #endif
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"};
555 #define BADDEVCNT 2
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
567 #endif
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 )
578 UCHAR bval;
580 bval = 0;
581 if(mode == ENABLE_CE)
582 *regval = 0xc0;
583 else
584 *regval = 0x80;
585 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
586 if(mode == DISABLE_CE)
587 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
588 udelay(160);
592 /* Override EEprom values with explicitly set values */
593 static void __init dc390_EEprom_Override (UCHAR index)
595 PUCHAR ptr;
596 UCHAR id;
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
637 /* | NO_SEEK */
638 # ifdef CONFIG_SCSI_MULTI_LUN
639 | LUN_CHECK
640 # endif
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)
646 int i;
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];
654 /* Sanity checks */
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;
660 #endif
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)
668 int ints[8];
669 int i, im;
670 (void)get_options (str, ARRAY_SIZE(ints), ints);
671 #else
672 void __init dc390_setup (char *str, int *ints)
674 int i, im;
675 #endif
676 im = ints[0];
677 if (im > 6)
679 printk (KERN_NOTICE "DC390: ignore extra params!\n");
680 im = 6;
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)
688 #ifndef MODULE
689 __setup("tmscsim=", dc390_setup);
690 #endif
691 #endif
694 static void __init dc390_EEpromOutDI( PDEVDECL, PUCHAR regval, UCHAR Carry )
696 UCHAR bval;
698 bval = 0;
699 if(Carry)
701 bval = 0x40;
702 *regval = 0x80;
703 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
705 udelay(160);
706 bval |= 0x80;
707 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
708 udelay(160);
709 bval = 0;
710 PCI_WRITE_CONFIG_BYTE(PDEV, *regval, bval);
711 udelay(160);
715 static UCHAR __init dc390_EEpromInDO( PDEVDECL )
717 UCHAR bval;
719 PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x80);
720 udelay(160);
721 PCI_WRITE_CONFIG_BYTE(PDEV, 0x80, 0x40);
722 udelay(160);
723 PCI_READ_CONFIG_BYTE(PDEV, 0x00, &bval);
724 if(bval == 0x22)
725 return(1);
726 else
727 return(0);
731 static USHORT __init dc390_EEpromGetData1( PDEVDECL )
733 UCHAR i;
734 UCHAR carryFlag;
735 USHORT wval;
737 wval = 0;
738 for(i=0; i<16; i++)
740 wval <<= 1;
741 carryFlag = dc390_EEpromInDO(PDEV);
742 wval |= carryFlag;
744 return(wval);
748 static void __init dc390_Prepare( PDEVDECL, PUCHAR regval, UCHAR EEpromCmd )
750 UCHAR i,j;
751 UCHAR carryFlag;
753 carryFlag = 1;
754 j = 0x80;
755 for(i=0; i<9; i++)
757 dc390_EEpromOutDI(PDEV,regval,carryFlag);
758 carryFlag = (EEpromCmd & j) ? 1 : 0;
759 j >>= 1;
764 static void __init dc390_ReadEEprom( PDEVDECL, PUSHORT ptr)
766 UCHAR regval,cmd;
767 UCHAR i;
769 cmd = EEPROM_READ;
770 for(i=0; i<0x40; i++)
772 dc390_EnDisableCE(ENABLE_CE, PDEV, &regval);
773 dc390_Prepare(PDEV, &regval, cmd++);
774 *ptr++ = dc390_EEpromGetData1(PDEV);
775 dc390_EnDisableCE(DISABLE_CE, PDEV, &regval);
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 )
788 UCHAR i;
789 char EEbuf[128];
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);
798 wval = 0;
799 for(i=0; i<0x40; i++, ptr++)
800 wval += *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]);)
820 return 0;
823 DCBDEBUG1( printk (KERN_DEBUG "DCB %p (%02x,%02x) found.\n", \
824 pDCB, pDCB->TargetID, pDCB->TargetLUN);)
825 return pDCB;
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
843 #if 0
844 /* Look for a SCSI cmd in a SRB queue */
845 static PSRB dc390_find_cmd_in_SRBq (PSCSICMD cmd, PSRB queue)
847 PSRB q = queue;
848 while (q)
850 if (q->pcmd == cmd) return q;
851 q = q->pNextSRB;
852 if (q == queue) return 0;
854 return q;
856 #endif
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;
865 else
866 pACB->pQueryTail->next = cmd;
868 pACB->pQueryTail = cmd;
869 pACB->QueryCnt++;
870 pACB->CmdOutOfSRB++;
871 cmd->next = NULL;
875 /* Return next cmd from Query list */
876 static PSCSICMD dc390_Query_get ( PACB pACB )
878 PSCSICMD pcmd;
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;
884 pcmd->next = NULL;
885 if (!pACB->pQueryHead) pACB->pQueryTail = NULL;
886 pACB->QueryCnt--;
887 return( pcmd );
891 /* Return next free SRB */
892 static __inline__ PSRB dc390_Free_get ( PACB pACB )
894 PSRB pSRB;
896 pSRB = pACB->pFreeSRB;
897 DEBUG0(printk ("DC390: Get Free SRB %p\n", pSRB);)
898 if( pSRB )
900 pACB->pFreeSRB = pSRB->pNextSRB;
901 pSRB->pNextSRB = NULL;
904 return( pSRB );
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;
924 pDCB->WaitSRBCnt++;
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;
934 else
935 pDCB->pWaitingSRB = pSRB;
937 pDCB->pWaitLast = pSRB;
938 pSRB->pNextSRB = NULL;
939 pDCB->WaitSRBCnt++;
940 pDCB->pDCBACB->CmdInQ++;
943 static __inline__ void dc390_Going_append (PDCB pDCB, PSRB pSRB)
945 pDCB->GoingSRBCnt++;
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;
950 else
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;
963 else
965 PSRB psrb = pDCB->pGoingSRB;
966 while (psrb && psrb->pNextSRB != pSRB)
967 psrb = psrb->pNextSRB;
968 if (!psrb)
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;
974 pDCB->GoingSRBCnt--;
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;
995 pDCB->WaitSRBCnt--;
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)
1007 #endif
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;
1019 else
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 )
1028 PDCB ptr, ptr1;
1029 PSRB pSRB;
1031 if( (pACB->pActiveDCB) || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) )
1032 return;
1033 if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);
1034 ptr = pACB->pDCBRunRobin;
1035 if( !ptr )
1037 ptr = pACB->pLinkDCB;
1038 pACB->pDCBRunRobin = ptr;
1040 ptr1 = ptr;
1041 if (!ptr1) return;
1044 pACB->pDCBRunRobin = ptr1->pNextDCB;
1045 if( !( pSRB = ptr1->pWaitingSRB ) ||
1046 ( ptr1->MaxCommand <= ptr1->GoingSRBCnt ))
1047 ptr1 = ptr1->pNextDCB;
1048 else
1050 /* Try to send to the bus */
1051 if( !dc390_StartSCSI(pACB, ptr1, pSRB) )
1052 dc390_Waiting_to_Going (ptr1, pSRB);
1053 else
1054 dc390_waiting_timer (pACB, HZ/5);
1055 break;
1057 } while (ptr1 != ptr);
1058 return;
1061 /* Wake up waiting queue */
1062 void DC390_waiting_timed_out (unsigned long ptr)
1064 PACB pACB = (PACB)ptr;
1065 DC390_IFLAGS
1066 DC390_AFLAGS
1067 DEBUG0(printk ("DC390: Debug: Waiting queue woken up by timer!\n");)
1068 DC390_LOCK_IO;
1069 DC390_LOCK_ACB;
1070 dc390_Waiting_process (pACB);
1071 DC390_UNLOCK_ACB;
1072 DC390_UNLOCK_IO;
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 )
1084 PDCB pDCB;
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);
1092 return;
1095 #if 0
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;
1106 #endif
1108 if (!dc390_StartSCSI(pACB, pDCB, pSRB))
1109 dc390_Going_append (pDCB, pSRB);
1110 else {
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,
1118 * PSRB pSRB)
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;
1127 pSRB->pcmd = pcmd;
1128 //pSRB->ScsiCmdLen = pcmd->cmd_len;
1129 //memcpy (pSRB->CmdBlock, pcmd->cmnd, pcmd->cmd_len);
1131 if( pcmd->use_sg )
1133 pSRB->SGcount = (UCHAR) pcmd->use_sg;
1134 pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
1136 else if( pcmd->request_buffer )
1138 pSRB->SGcount = 1;
1139 pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
1140 pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
1141 pSRB->Segmentx.length = pcmd->request_bufflen;
1143 else
1144 pSRB->SGcount = 0;
1146 pSRB->SGIndex = 0;
1147 pSRB->AdaptStatus = 0;
1148 pSRB->TargetStatus = 0;
1149 pSRB->MsgCnt = 0;
1150 if( pDCB->DevType != TYPE_TAPE )
1151 pSRB->RetryCnt = 1;
1152 else
1153 pSRB->RetryCnt = 0;
1154 pSRB->SRBStatus = 0;
1155 pSRB->SRBFlag = 0;
1156 pSRB->SRBState = 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)
1168 Scsi_Cmnd *pcmd;
1169 PSRB pSRB;
1170 PDCB pDCB;
1172 if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) )
1173 return;
1175 while (pACB->QueryCnt)
1177 pSRB = dc390_Free_get ( pACB );
1178 if (!pSRB) return;
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);
1182 if (!pDCB)
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;
1188 pcmd->done (pcmd);
1189 DC390_LOCK_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
1208 * TO BE DONE:
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 *))
1217 PDCB pDCB;
1218 PSRB pSRB;
1219 DC390_AFLAGS
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);)
1227 DC390_LOCK_ACB;
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); */
1247 DC390_UNLOCK_ACB;
1248 //return (1);
1249 done (cmd);
1250 return (0);
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 );
1259 if (!pDCB)
1261 printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n",
1262 cmd->target, cmd->lun);
1263 DC390_UNLOCK_ACB;
1264 printk ("DC390: No DCB in queue_command!\n");
1265 #ifdef USE_NEW_EH
1266 return (1);
1267 #else
1268 done (cmd);
1269 return (0);
1270 #endif
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);
1278 DC390_UNLOCK_ACB;
1279 //return (1);
1280 done (cmd);
1281 return (0);
1283 else
1285 pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun);
1286 if (!pDCB)
1287 { /* should never happen */
1288 printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n",
1289 cmd->target, cmd->lun);
1290 DC390_UNLOCK_ACB;
1291 printk ("DC390: No DCB in queuecommand (2)!\n");
1292 #ifdef USE_NEW_EH
1293 return (1);
1294 #else
1295 done (cmd);
1296 return (0);
1297 #endif
1301 pACB->Cmds++;
1302 cmd->scsi_done = done;
1303 cmd->result = 0;
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);
1318 else
1320 dc390_BuildSRB (cmd, pDCB, pSRB);
1321 dc390_Waiting_append (pDCB, pSRB);
1323 dc390_Waiting_process (pACB);
1325 else
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");)
1329 if (!pSRB)
1331 dc390_Query_append (cmd, pACB);
1332 dc390_Waiting_process (pACB);
1334 else
1336 dc390_BuildSRB (cmd, pDCB, pSRB);
1337 dc390_SendSRB (pACB, pSRB);
1341 DC390_UNLOCK_ACB;
1342 DEBUG1(printk (KERN_DEBUG " ... command (pid %li) queued successfully.\n", cmd->pid);)
1343 return(0);
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;
1378 int i, largest_cyl;
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) {
1386 if (!p->sys_ind)
1387 continue;
1388 cyl = p->cyl + ((p->sector & 0xc0) << 2);
1389 if (cyl > largest_cyl) {
1390 largest_cyl = cyl;
1391 largest = p;
1396 if (largest) {
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)) {
1416 *secs = end_sector;
1417 *hds = end_head + 1;
1418 *cyls = capacity / ((end_head + 1) * end_sector);
1419 return 0;
1422 return -1;
1425 /***********************************************************************
1426 * Function:
1427 * DC390_bios_param
1429 * Description:
1430 * Return the disk geometry for the given SCSI device.
1431 * Respect the partition table, otherwise try own heuristic
1433 * Note:
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;
1441 int ret_code = -1;
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);
1449 brelse (bh);
1451 if (ret_code == -1)
1453 heads = 64;
1454 sectors = 32;
1455 cylinders = size / (heads * sectors);
1457 if ( (pACB->Gmode2 & GREATER_1G) && (cylinders > 1024) )
1459 heads = 255;
1460 sectors = 63;
1461 cylinders = size / (heads * sectors);
1464 geom[0] = heads;
1465 geom[1] = sectors;
1466 geom[2] = cylinders;
1469 return (0);
1471 #else
1472 int DC390_bios_param (Disk *disk, kdev_t devno, int geom[])
1474 return scsicam_bios_param (disk, devno, geom);
1476 #endif
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;
1485 if (pSRB)
1487 printk ("DC390: SRB: Xferred %08lx, Remain %08lx, State %08x, Phase %02x\n",
1488 pSRB->TotalXferredLen, pSRB->SGToBeXferLen, pSRB->SRBState,
1489 pSRB->ScsiPhase);
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));
1506 printk ("\n");
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.
1530 * Status: Buggy !
1531 ***********************************************************************/
1533 int DC390_abort (Scsi_Cmnd *cmd)
1535 PDCB pDCB;
1536 PSRB pSRB, psrb;
1537 UINT count, i;
1538 PSCSICMD pcmd;
1539 int status;
1540 //ULONG sbac;
1541 DC390_AFLAGS
1542 PACB pACB = (PACB) cmd->host->hostdata;
1544 DC390_LOCK_ACB;
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;
1553 if( pcmd == cmd )
1555 /* Found: Dequeue */
1556 pACB->pQueryHead = pcmd->next;
1557 pcmd->next = NULL;
1558 if (cmd == pACB->pQueryTail) pACB->pQueryTail = NULL;
1559 pACB->QueryCnt--;
1560 status = SCSI_ABORT_SUCCESS;
1561 goto ABO_X;
1563 for( count = pACB->QueryCnt, i=0; i<count-1; i++)
1565 if( pcmd->next == cmd )
1567 pcmd->next = cmd->next;
1568 cmd->next = NULL;
1569 if (cmd == pACB->pQueryTail) pACB->pQueryTail = NULL;
1570 pACB->QueryCnt--;
1571 status = SCSI_ABORT_SUCCESS;
1572 goto ABO_X;
1574 else
1576 pcmd = pcmd->next;
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 )
1588 goto ON_GOING;
1591 pSRB = pDCB->pWaitingSRB;
1592 if( !pSRB )
1593 goto ON_GOING;
1595 /* Now scan Waiting queue */
1596 if( pSRB->pcmd == cmd )
1598 pDCB->pWaitingSRB = pSRB->pNextSRB;
1599 goto IN_WAIT;
1601 else
1603 psrb = pSRB;
1604 if( !(psrb->pNextSRB) )
1605 goto ON_GOING;
1606 while( psrb->pNextSRB->pcmd != cmd )
1608 psrb = psrb->pNextSRB;
1609 if( !(psrb->pNextSRB) || psrb == pSRB)
1610 goto ON_GOING;
1612 pSRB = psrb->pNextSRB;
1613 psrb->pNextSRB = pSRB->pNextSRB;
1614 if( pSRB == pDCB->pWaitLast )
1615 pDCB->pWaitLast = psrb;
1616 IN_WAIT:
1617 dc390_Free_insert (pACB, pSRB);
1618 pDCB->WaitSRBCnt--;
1619 cmd->next = NULL;
1620 status = SCSI_ABORT_SUCCESS;
1621 goto ABO_X;
1624 /* SRB has already been sent ! */
1625 ON_GOING:
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;
1637 else
1639 if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) )
1641 status = SCSI_ABORT_BUSY;
1642 printk ("DC390: Abort current command (pid %li, SRB %p)\n",
1643 cmd->pid, pSRB);
1644 goto ABO_X;
1646 else
1648 status = SCSI_ABORT_SNOOZE;
1649 goto ABO_X;
1654 NOT_RUN:
1655 status = SCSI_ABORT_NOT_RUNNING;
1657 ABO_X:
1658 cmd->result = DID_ABORT << 16;
1659 printk(KERN_INFO "DC390: Aborted pid %li with status %i\n", cmd->pid, status);
1660 #if 0
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);
1669 //udelay (10000);
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);
1678 //udelay (250);
1679 //sbac = DC390_read32 (DMA_ScsiBusCtrl);
1680 //printk ("%08lx ", sbac);
1681 //DC390_write32 (DMA_ScsiBusCtrl, sbac & ~(SCSI_LINES | SCAM));
1682 //udelay (100);
1683 //sbac = DC390_read32 (DMA_ScsiBusCtrl);
1684 //printk ("%08lx ", sbac);
1685 DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
1686 udelay (250);
1687 DC390_write8 (ScsiCmd, NOP_CMD);
1688 sbac = DC390_read32 (DMA_ScsiBusCtrl);
1689 printk ("%08lx\n", sbac);
1691 #endif
1692 dc390_lastabortedpid = cmd->pid;
1693 DC390_UNLOCK_ACB;
1694 //do_DC390_Interrupt (pACB->IRQLevel, 0, 0);
1695 #ifndef USE_NEW_EH
1696 if (status == SCSI_ABORT_SUCCESS) cmd->scsi_done(cmd);
1697 #endif
1698 return( status );
1702 static void dc390_ResetDevParam( PACB pACB )
1704 PDCB pDCB, pdcb;
1706 pDCB = pACB->pLinkDCB;
1707 if (! pDCB) return;
1708 pdcb = pDCB;
1711 pDCB->SyncMode &= ~SYNC_NEGO_DONE;
1712 pDCB->SyncPeriod = 0;
1713 pDCB->SyncOffset = 0;
1714 pDCB->TagMask = 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);
1725 #if 0
1726 /* Moves all SRBs from Going to Waiting for all DCBs */
1727 static void dc390_RecoverSRB( PACB pACB )
1729 PDCB pDCB, pdcb;
1730 PSRB psrb, psrb2;
1731 UINT cnt, i;
1733 pDCB = pACB->pLinkDCB;
1734 if( !pDCB ) return;
1735 pdcb = pDCB;
1738 cnt = pdcb->GoingSRBCnt;
1739 psrb = pdcb->pGoingSRB;
1740 for (i=0; i<cnt; i++)
1742 psrb2 = psrb;
1743 psrb = psrb->pNextSRB;
1744 /* dc390_RewaitSRB( pDCB, psrb ); */
1745 if( pdcb->pWaitingSRB )
1747 psrb2->pNextSRB = pdcb->pWaitingSRB;
1748 pdcb->pWaitingSRB = psrb2;
1750 else
1752 pdcb->pWaitingSRB = psrb2;
1753 pdcb->pWaitLast = psrb2;
1754 psrb2->pNextSRB = NULL;
1757 pdcb->GoingSRBCnt = 0;
1758 pdcb->pGoingSRB = NULL;
1759 pdcb->TagMask = 0;
1760 pdcb = pdcb->pNextDCB;
1761 } while( pdcb != pDCB );
1763 #endif
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)
1778 UCHAR bval;
1779 DC390_AFLAGS
1780 PACB pACB = (PACB) cmd->host->hostdata;
1782 printk(KERN_INFO "DC390: RESET ... ");
1784 DC390_LOCK_ACB;
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 );
1794 udelay (1000);
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;
1805 pACB->ACBFlag = 0;
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 );
1812 printk("done\n");
1813 DC390_UNLOCK_ACB;
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 )
1830 PEEprom prom;
1831 UCHAR index;
1832 PDCB pDCB, pDCB2;
1834 pDCB = kmalloc (sizeof(DC390_DCB), GFP_ATOMIC);
1835 DCBDEBUG(printk (KERN_INFO "DC390: alloc mem for DCB (ID %i, LUN %i): %p\n" \
1836 id, lun, pDCB);)
1838 *ppDCB = pDCB; pDCB2 = 0;
1839 if (!pDCB) return;
1840 if( pACB->DCBCnt == 0 )
1842 pACB->pLinkDCB = pDCB;
1843 pACB->pDCBRunRobin = pDCB;
1845 else
1847 pACB->pLastDCB->pNextDCB = pDCB;
1850 pACB->DCBCnt++;
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;
1863 pDCB->TagMask = 0;
1864 pDCB->MaxCommand = 1;
1865 index = pACB->AdapterIndex;
1866 pDCB->DCBFlag = 0;
1868 /* Is there a corresp. LUN==0 device ? */
1869 if (lun != 0)
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 */
1874 if (pDCB2)
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;
1886 else
1888 pDCB->DevMode = prom->EE_MODE1;
1889 pDCB->SyncMode = 0;
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;
1899 pDCB->Inquiry7 = 0;
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;
1917 } else {
1918 pDCB->SyncMode &= ~EN_TAG_QUEUEING;
1919 pDCB->MaxCommand = 1;
1922 if( pDCB->DevMode & SYNC_NEGO_ )
1923 pDCB->SyncMode |= SYNC_ENABLE;
1924 else {
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)
1945 int i;
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 )
1971 UINT count, i;
1973 count = pACB->SRBCount;
1974 for( i=0; i<count; i++)
1976 if( i != count-1 )
1977 pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
1978 else
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)
1996 PACB pACB;
1997 UCHAR i;
1998 DC390_AFLAGS
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;
2005 psh->irq = Irq;
2006 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,50)
2007 psh->base = io_port;
2008 #else
2009 psh->base = (char*)io_port;
2010 #endif
2011 psh->unique_id = io_port;
2012 psh->dma_channel = -1;
2013 psh->last_reset = jiffies;
2015 pACB = (PACB) psh->hostdata;
2016 DC390_LOCKA_INIT;
2017 DC390_LOCK_ACB;
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);)
2026 psh->max_id = 8;
2028 if( psh->max_id - 1 == dc390_eepromBuf[index][EE_ADAPT_SCSI_ID] )
2029 psh->max_id--;
2030 psh->max_lun = 1;
2031 if( dc390_eepromBuf[index][EE_MODE2] & LUN_CHECK )
2032 psh->max_lun = 8;
2034 pACB->pLinkDCB = NULL;
2035 pACB->pDCBRunRobin = NULL;
2036 pACB->pActiveDCB = NULL;
2037 pACB->pFreeSRB = pACB->SRB_array;
2038 pACB->SRBCount = MAX_SRB_CNT;
2039 pACB->QueryCnt = 0;
2040 pACB->pQueryHead = NULL;
2041 pACB->AdapterIndex = index;
2042 pACB->status = 0;
2043 psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID];
2044 pACB->DeviceCnt = 0;
2045 pACB->DCBCnt = 0;
2046 pACB->TagMaxNum = 2 << dc390_eepromBuf[index][EE_TAG_CMD_NUM];
2047 pACB->ACBFlag = 0;
2048 pACB->scan_devices = 1;
2049 pACB->MsgLen = 0;
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)
2078 PACB pACB, pACB2;
2079 UCHAR dstate;
2080 int i;
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");
2087 return( -1 );
2089 else
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);
2098 return( -1 );
2101 if( !dc390_pACB_start )
2103 pACB2 = NULL;
2104 dc390_pACB_start = pACB;
2105 dc390_pACB_current = pACB;
2106 pACB->pNextACB = NULL;
2108 else
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 );
2121 udelay (1000);
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++ )
2126 udelay(1000);
2129 pACB->ACBFlag = 0;
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 */
2146 return(0);
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)
2169 PSH psh;
2170 PACB pACB;
2171 DC390_AFLAGS
2173 if (dc390_CheckEEpromCheckSum (PDEV, index))
2175 #ifdef CONFIG_SCSI_DC390T_NOGENSUPP
2176 printk (KERN_ERR "DC390_init: No EEPROM found!\n");
2177 return( -1 );
2178 #else
2179 int speed;
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]);
2190 #endif
2192 else
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;
2202 DC390_LOCKA_INIT;
2203 DC390_LOCK_ACB;
2205 #if 0
2206 if( !dc390_pSH_start )
2208 dc390_pSH_start = psh;
2209 dc390_pSH_current = psh;
2211 else
2213 dc390_pSH_current->next = psh;
2214 dc390_pSH_current = psh;
2216 #endif
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;
2224 PDEVSET;
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) );)
2233 DC390_UNLOCK_ACB;
2234 return (0);
2236 else
2238 //dc390_pSH_start = NULL;
2239 scsi_unregister( psh );
2240 DC390_UNLOCK_ACB;
2241 return( -1 );
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 ***********************************************************************/
2259 #ifndef NEW_PCI
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)
2264 USHORT cmd;
2265 UCHAR lat;
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",
2271 PCI_BUS_DEV);
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",
2278 PCI_BUS_DEV, lat);
2279 PCI_WRITE_CONFIG_BYTE(PDEV, PCI_LATENCY_TIMER, 64);
2283 #endif /* ! NEW_PCI */
2285 static void __init dc390_set_pci_cfg (PDEVDECL)
2287 USHORT cmd;
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)
2297 PDEVDECL0;
2298 UCHAR irq;
2299 UINT io_port;
2300 //DC390_IFLAGS
2301 DC390_DFLAGS
2303 DC390_LOCK_DRV;
2304 //dc390_pSHT_start = psht;
2305 dc390_pACB_start = NULL;
2307 if ( PCI_PRESENT )
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))
2312 continue;
2313 #endif
2314 //DC390_LOCK_IO; /* Remove this when going to new eh */
2315 PCI_GET_IO_AND_IRQ;
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))
2320 PCI_SET_MASTER;
2321 dc390_set_pci_cfg (PDEV);
2322 dc390_adapterCnt++;
2324 //DC390_UNLOCK_IO; /* Remove when going to new eh */
2326 else
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";
2332 #else
2333 psht->proc_dir = &DC390_proc_scsi_tmscsim;
2334 #endif
2335 printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt);
2336 DC390_UNLOCK_DRV;
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
2346 * with the device
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);
2353 if (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");
2358 if (pDCB)
2360 pDCB->DevMode &= ~(SYNC_NEGO_ | TAG_QUEUEING_ | EN_DISCONNECT_ );
2361 dc390_updateDCB (pACB, pDCB);
2364 kfree (cmd);
2367 void dc390_inquiry (PACB pACB, PDCB pDCB)
2369 char* buffer;
2370 Scsi_Cmnd* cmd;
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;
2385 cmd->pid = 390;
2386 cmd->bufflen = 128;
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
2407 * with the device
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);
2414 kfree (cmd);
2417 void dc390_sendstart (PACB pACB, PDCB pDCB)
2419 char* buffer;
2420 Scsi_Cmnd* cmd;
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;
2435 cmd->pid = 310;
2436 cmd->bufflen = 128;
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)
2463 *p2 = *p1;
2464 *var = simple_strtoul (*p2, p1, 10);
2465 if (*p2 == *p1) return -1;
2466 *p1 = strtok (0, " \t\n:=,;.");
2467 return 0;
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)
2476 switch (**p)
2478 case 'Y': *var |= bmask; break;
2479 case 'N': *var &= ~bmask; break;
2480 case '-': break;
2481 default: return -1;
2483 *p = strtok (0, " \t\n:=,;");
2484 return 0;
2487 #define YESNO(p, var, bmask) \
2488 if (dc390_yesno (&p, &var, bmask)) goto einv; \
2489 else dc390_updateDCB (pACB, pDCB); \
2490 if (!p) goto ok
2492 static int dc390_search (char **p1, char **p2, char *var, char* txt, int max, int scale, char* ign)
2494 int dum;
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; }
2503 else return -2;
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:=,;");
2510 return 0;
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)
2530 char* c = _prstr;
2531 while (p < e)
2532 if (*p == 0) { *c++ = ':'; p++; }
2533 else if (*p == 10) { *c++ = '\\'; *c++ = 'n'; p++; }
2534 else *c++ = *p++;
2535 *c = 0;
2536 return _prstr;
2538 #endif
2540 int dc390_set_info (char *buffer, int length, PACB pACB)
2542 char *pos = buffer, *p0 = buffer;
2543 char needs_inquiry = 0;
2544 int dum = 0;
2545 char dev;
2546 PDCB pDCB = pACB->pLinkDCB;
2547 DC390_IFLAGS
2548 DC390_AFLAGS
2549 pos[length] = 0;
2551 DC390_LOCK_IO;
2552 DC390_LOCK_ACB;
2553 /* UPPERCASE */
2554 /* Don't use kernel toupper, because of 2.0.x bug: ctmp unexported */
2555 while (*pos)
2556 { if (*pos >='a' && *pos <= 'z') *pos = *pos + 'A' - 'a'; pos++; };
2558 /* We should protect __strtok ! */
2559 /* spin_lock (strtok_lock); */
2561 /* Remove WS */
2562 pos = strtok (buffer, " \t:\n=,;");
2563 if (!pos) goto ok;
2565 next:
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;
2573 if (isdigit (*pos))
2575 /* Device config line */
2576 int dev, id, lun; char* pdec;
2577 char olddevmode;
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;
2587 /* Sanity Check */
2588 if (pDCB->TargetID != id || pDCB->TargetLUN != lun)
2590 printk (KERN_ERR "DC390: no such device: Idx=%02i ID=%02i LUN=%02i\n",
2591 dev, id, lun);
2592 goto einv2;
2595 if (pDCB->pWaitingSRB || pDCB->pGoingSRB)
2597 printk ("DC390: Cannot change dev (%i-%i) cfg: Pending requests\n",
2598 pDCB->TargetID, pDCB->TargetLUN);
2599 goto einv;
2602 olddevmode = pDCB->DevMode;
2603 YESNO (pos, pDCB->DevMode, PARITY_CHK_);
2604 needs_inquiry++;
2605 YESNO (pos, pDCB->DevMode, SYNC_NEGO_);
2606 if ((olddevmode & SYNC_NEGO_) == (pDCB->DevMode & SYNC_NEGO_)) needs_inquiry--;
2607 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_);
2611 needs_inquiry++;
2612 YESNO (pos, pDCB->DevMode, TAG_QUEUEING_);
2613 if ((olddevmode & TAG_QUEUEING_) == (pDCB->DevMode & TAG_QUEUEING_)) needs_inquiry--;
2615 dc390_updateDCB (pACB, pDCB);
2616 if (!pos) goto ok;
2618 olddevmode = pDCB->NegoPeriod;
2619 /* Look for decimal point (Speed) */
2620 pdec = pos;
2621 while (pdec++ < &buffer[length]) if (*pdec == '.') break;
2622 /* NegoPeriod */
2623 if (*pos != '-')
2625 SCANF (pos, p0, dum, 72, 800);
2626 pDCB->NegoPeriod = dum >> 2;
2627 if (pDCB->NegoPeriod != olddevmode) needs_inquiry++;
2628 if (!pos) goto ok;
2629 if (memcmp (pos, "NS", 2) == 0) pos = strtok (0, " \t\n:=,;.");
2631 else pos = strtok (0, " \t\n:=,;.");
2632 if (!pos) goto ok;
2634 /* Sync Speed in MHz */
2635 if (*pos != '-')
2637 SCANF (pos, p0, dum, 1, 13);
2638 pDCB->NegoPeriod = (1000/dum) >> 2;
2639 if (pDCB->NegoPeriod != olddevmode && !pos) needs_inquiry++;
2640 if (!pos) goto ok;
2641 /* decimal */
2642 if (pos-1 == pdec)
2644 int dumold = dum;
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:=,;");
2650 if (!pos) goto ok;
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); */
2657 if (!pos) goto ok;
2659 olddevmode = pDCB->SyncOffset;
2660 /* SyncOffs */
2661 if (*pos != '-')
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:=,;");
2668 if (!pos) goto ok;
2669 dc390_updateDCB (pACB, pDCB);
2671 //olddevmode = pDCB->MaxCommand;
2672 /* MaxCommand (Tags) */
2673 if (*pos != '-')
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:=,;");
2683 else
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");
2697 ok2:
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;
2712 if (pos) goto next;
2715 /* spin_unlock (strtok_lock); */
2716 DC390_UNLOCK_ACB;
2717 if (needs_inquiry)
2718 { dc390_updateDCB (pACB, pDCB); dc390_inquiry (pACB, pDCB); };
2719 DC390_UNLOCK_IO;
2720 return (length);
2722 einv2:
2723 pos = p0;
2724 einv:
2725 /* spin_unlock (strtok_lock); */
2726 DC390_UNLOCK_ACB;
2727 DC390_UNLOCK_IO;
2728 printk (KERN_WARNING "DC390: parse error near \"%s\"\n", (pos? pos: "NULL"));
2729 return (-EINVAL);
2731 reset:
2733 Scsi_Cmnd cmd; cmd.host = pACB->pScsiHost;
2734 printk (KERN_WARNING "DC390: Driver reset requested!\n");
2735 DC390_UNLOCK_ACB;
2736 DC390_reset (&cmd, 0);
2737 DC390_UNLOCK_IO;
2739 return (length);
2741 dump:
2743 dc390_dumpinfo (pACB, 0, 0);
2744 DC390_UNLOCK_ACB;
2745 DC390_UNLOCK_IO;
2747 return (length);
2749 inquiry:
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);
2757 DC390_UNLOCK_ACB;
2758 dc390_inquiry (pACB, pDCB);
2759 DC390_UNLOCK_IO;
2761 return (length);
2763 remove:
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);
2773 DC390_UNLOCK_ACB;
2774 DC390_UNLOCK_IO;
2776 return (length);
2778 add:
2780 int id, lun;
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);
2787 DC390_UNLOCK_ACB;
2788 dc390_inquiry (pACB, pDCB);
2789 DC390_UNLOCK_IO;
2791 return (length);
2793 start:
2795 int id, lun;
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);
2802 DC390_UNLOCK_ACB;
2803 dc390_sendstart (pACB, pDCB);
2804 dc390_inquiry (pACB, pDCB);
2805 DC390_UNLOCK_IO;
2807 return (length);
2809 einv_dev:
2810 printk (KERN_WARNING "DC390: Ignore cmnd to illegal Dev(Idx) %i. Valid range: 0 - %i.\n",
2811 dev, pACB->DCBCnt - 1);
2812 DC390_UNLOCK_ACB;
2813 DC390_UNLOCK_IO;
2814 return (-EINVAL);
2819 #undef SEARCH
2820 #undef YESNO
2821 #undef SCANF
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
2830 * start :
2831 * offset:
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 ********************************************************************/
2842 #undef SPRINTF
2843 #define SPRINTF(args...) pos += sprintf(pos, ## args)
2845 #define YESNO(YN) \
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)
2853 int dev, spd, spd1;
2854 char *pos = buffer;
2855 PSH shpnt;
2856 PACB pACB;
2857 PDCB pDCB;
2858 PSCSICMD pcmd;
2859 DC390_AFLAGS
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);
2879 DC390_LOCK_ACB;
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++)
2937 PSRB pSRB;
2938 if (pDCB->WaitSRBCnt)
2939 SPRINTF ("DCB (%02i-%i): Waiting: %i:", pDCB->TargetID, pDCB->TargetLUN,
2940 pDCB->WaitSRBCnt);
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,
2945 pDCB->GoingSRBCnt);
2946 for (pSRB = pDCB->pGoingSRB; pSRB; pSRB = pSRB->pNextSRB)
2947 #if 0 //def DC390_DEBUGTRACE
2948 SPRINTF(" %s\n ", pSRB->debugtrace);
2949 #else
2950 SPRINTF(" %li", pSRB->pcmd->pid);
2951 #endif
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);
2962 SPRINTF("\n");
2963 #endif
2966 DC390_UNLOCK_ACB;
2967 *start = buffer + offset;
2969 if (pos - buffer < offset)
2970 return 0;
2971 else if (pos - buffer - offset < length)
2972 return pos - buffer - offset;
2973 else
2974 return length;
2977 #undef YESNO
2978 #undef SPRINTF
2980 #ifdef MODULE
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)
2992 UCHAR bval;
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);
3007 return( 0 );
3010 void dc390_freeDCBs (struct Scsi_Host *host)
3012 PDCB pDCB, nDCB;
3013 PACB pACB = (PACB)(host->hostdata);
3015 pDCB = pACB->pLinkDCB;
3016 if (!pDCB) return;
3019 nDCB = pDCB->pNextDCB;
3020 DCBDEBUG(printk (KERN_INFO "DC390: Free DCB (ID %i, LUN %i): %p\n",\
3021 pDCB->TargetID, pDCB->TargetLUN, pDCB);)
3022 //kfree (pDCB);
3023 dc390_remove_dev (pACB, pDCB);
3024 pDCB = nDCB;
3025 } while (pDCB && pACB->pLinkDCB);
3029 int DC390_release (struct Scsi_Host *host)
3031 DC390_AFLAGS DC390_IFLAGS
3032 PACB pACB = (PACB)(host->hostdata);
3034 DC390_LOCK_IO;
3035 DC390_LOCK_ACB;
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);
3048 DC390_UNLOCK_ACB;
3049 DC390_UNLOCK_IO;
3050 return( 1 );
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"
3060 #endif