1 /************************************************************************
2 * GDT ISA/EISA/PCI Disk Array Controller driver for Linux *
5 * Copyright (C) 1995-99 ICP vortex Computersysteme GmbH, Achim Leubner *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published *
11 * by the Free Software Foundation; either version 2 of the License, *
12 * or (at your option) any later version. *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
19 * You should have received a copy of the GNU General Public License *
20 * along with this kernel; if not, write to the Free Software *
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
23 * Tested with Linux 1.2.13, ..., 2.2.4 *
26 * Revision 1.23 1999/03/26 09:12:31 achim
27 * Default value for hdr_channel set to 0
29 * Revision 1.22 1999/03/22 16:27:16 achim
30 * Bugfix: gdth_store_event() must not be locked with GDTH_LOCK_HA()
32 * Revision 1.21 1999/03/16 13:40:34 achim
33 * Problems with reserved drives solved
34 * gdth_eh_bus_reset() implemented
36 * Revision 1.20 1999/03/10 09:08:13 achim
37 * Bugfix: Corrections in gdth_direction_tab[] made
38 * Bugfix: Increase command timeout (gdth_update_timeout()) NOT in gdth_putq()
40 * Revision 1.19 1999/03/05 14:38:16 achim
41 * Bugfix: Heads/Sectors mapping for reserved devices possibly wrong
42 * -> gdth_eval_mapping() implemented, changes in gdth_bios_param()
43 * INIT_RETRIES set to 100s to avoid DEINIT-Timeout for controllers
44 * with BIOS disabled and memory test set to Intensive
45 * Enhanced /proc support
47 * Revision 1.18 1999/02/24 09:54:33 achim
48 * Command line parameter hdr_channel implemented
49 * Bugfix for EISA controllers + Linux 2.2.x
51 * Revision 1.17 1998/12/17 15:58:11 achim
52 * Command line parameters implemented
53 * Changes for Alpha platforms
54 * PCI controller scan changed
55 * SMP support improved (spin_lock_irqsave(),...)
56 * New async. events, new scan/reserve commands included
58 * Revision 1.16 1998/09/28 16:08:46 achim
59 * GDT_PCIMPR: DPMEM remapping, if required
62 * Revision 1.15 1998/06/03 14:54:06 achim
63 * gdth_delay(), gdth_flush() implemented
64 * Bugfix: gdth_release() changed
66 * Revision 1.14 1998/05/22 10:01:17 achim
67 * mj: pcibios_strerror() removed
68 * Improved SMP support (if version >= 2.1.95)
69 * gdth_halt(): halt_called flag added (if version < 2.1)
71 * Revision 1.13 1998/04/16 09:14:57 achim
72 * Reserve drives (for raw service) implemented
73 * New error handling code enabled
74 * Get controller name from board_info() IOCTL
75 * Final round of PCI device driver patches by Martin Mares
77 * Revision 1.12 1998/03/03 09:32:37 achim
78 * Fibre channel controller support added
80 * Revision 1.11 1998/01/27 16:19:14 achim
82 * add_timer()/del_timer() instead of GDTH_TIMER
83 * scsi_add_timer()/scsi_del_timer() instead of SCSI_TIMER
84 * New error handling included
86 * Revision 1.10 1997/10/31 12:29:57 achim
87 * Read heads/sectors from host drive
89 * Revision 1.9 1997/09/04 10:07:25 achim
90 * IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ...
91 * register_reboot_notifier() to get a notify on shutdown used
93 * Revision 1.8 1997/04/02 12:14:30 achim
94 * Version 1.00 (see gdth.h), tested with kernel 2.0.29
96 * Revision 1.7 1997/03/12 13:33:37 achim
97 * gdth_reset() changed, new async. events
99 * Revision 1.6 1997/03/04 14:01:11 achim
100 * Shutdown routine gdth_halt() implemented
102 * Revision 1.5 1997/02/21 09:08:36 achim
103 * New controller included (RP, RP1, RP2 series)
104 * IOCTL interface implemented
106 * Revision 1.4 1996/07/05 12:48:55 achim
107 * Function gdth_bios_param() implemented
108 * New constant GDTH_MAXC_P_L inserted
109 * GDT_WRITE_THR, GDT_EXT_INFO implemented
110 * Function gdth_reset() changed
112 * Revision 1.3 1996/05/10 09:04:41 achim
113 * Small changes for Linux 1.2.13
115 * Revision 1.2 1996/05/09 12:45:27 achim
116 * Loadable module support implemented
117 * /proc support corrections made
119 * Revision 1.1 1996/04/11 07:35:57 achim
122 ************************************************************************/
123 #ident "$Id: gdth.c,v 1.23 1999/03/26 09:12:31 achim Exp $"
125 /* All GDT Disk Array Controllers are fully supported by this driver.
126 * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
127 * PCI Fibre Channel Disk Array Controllers. See gdth.h for a complete
128 * list of all controller types.
130 * If you have one or more GDT3000/3020 EISA controllers with
131 * controller BIOS disabled, you have to set the IRQ values with the
132 * command line option "gdth=irq1,irq2,...", where the irq1,irq2,... are
133 * the IRQ values for the EISA controllers.
135 * After the optional list of IRQ values, other possible
136 * command line options are:
137 * disable:Y disable driver
138 * disable:N enable driver
139 * reserve_mode:0 reserve no drives for the raw service
140 * reserve_mode:1 reserve all not init., removable drives
141 * reserve_mode:2 reserve all not init. drives
142 * reserve_list:h,b,t,l,h,b,t,l,... reserve particular drive(s) with
143 * h- controller no., b- channel no.,
144 * t- target ID, l- LUN
145 * reverse_scan:Y reverse scan order for PCI controllers
146 * reverse_scan:N scan PCI controllers like BIOS
147 * max_ids:x x - target ID count per channel (1..MAXID)
148 * rescan:Y rescan all channels/IDs
149 * rescan:N use all devices found until now
150 * hdr_channel:x x - number of virtual bus for host drives
152 * The default value is: "gdth=disable:N,reserve_mode:1,reverse_scan:N,
153 * max_ids:127,rescan:N,hdr_channel:0".
154 * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y".
156 * When loading the gdth driver as a module, the same options are available.
157 * You can set the IRQs with "IRQ=...". However, the syntax to specify the
158 * options changes slightly. You must replace all ',' between options
159 * with ' ' and all ':' with '=' and you must use
160 * '1' in place of 'Y' and '0' in place of 'N'.
162 * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0
163 * max_ids=127 rescan=0 hdr_channel=0"
164 * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1".
168 #include <linux/module.h>
171 #include <linux/version.h>
172 #include <linux/kernel.h>
173 #include <linux/types.h>
174 #include <linux/pci.h>
175 #include <linux/string.h>
176 #include <linux/ctype.h>
177 #include <linux/ioport.h>
178 #include <linux/delay.h>
179 #include <linux/sched.h>
180 #include <linux/in.h>
181 #include <linux/proc_fs.h>
182 #include <linux/time.h>
183 #include <linux/timer.h>
184 #include <linux/reboot.h>
187 #include <asm/system.h>
189 #include <linux/spinlock.h>
190 #include <linux/blk.h>
197 static void gdth_delay(int milliseconds
);
198 static void gdth_eval_mapping(ulong32 size
, int *cyls
, int *heads
, int *secs
);
199 static void gdth_interrupt(int irq
,void *dev_id
,struct pt_regs
*regs
);
200 static int gdth_sync_event(int hanum
,int service
,unchar index
,Scsi_Cmnd
*scp
);
201 static int gdth_async_event(int hanum
,int service
);
202 static void gdth_log_event(gdth_evt_data
*dvr
, char *buffer
);
204 static void gdth_putq(int hanum
,Scsi_Cmnd
*scp
,unchar priority
);
205 static void gdth_next(int hanum
);
206 static int gdth_fill_raw_cmd(int hanum
,Scsi_Cmnd
*scp
,unchar b
);
207 static int gdth_special_cmd(int hanum
,Scsi_Cmnd
*scp
);
208 static gdth_evt_str
*gdth_store_event(gdth_ha_str
*ha
, ushort source
,
209 ushort idx
, gdth_evt_data
*evt
);
210 static int gdth_read_event(gdth_ha_str
*ha
, int handle
, gdth_evt_str
*estr
);
211 static void gdth_readapp_event(gdth_ha_str
*ha
, unchar application
,
213 static void gdth_clear_events(void);
215 static void gdth_copy_internal_data(Scsi_Cmnd
*scp
,char *buffer
,ushort count
);
216 static int gdth_internal_cache_cmd(int hanum
,Scsi_Cmnd
*scp
);
217 static int gdth_fill_cache_cmd(int hanum
,Scsi_Cmnd
*scp
,ushort hdrive
);
219 static int gdth_search_eisa(ushort eisa_adr
);
220 static int gdth_search_isa(ulong32 bios_adr
);
221 static int gdth_search_pci(gdth_pci_str
*pcistr
);
222 static void gdth_sort_pci(gdth_pci_str
*pcistr
, int cnt
);
223 static int gdth_init_eisa(ushort eisa_adr
,gdth_ha_str
*ha
);
224 static int gdth_init_isa(ulong32 bios_adr
,gdth_ha_str
*ha
);
225 static int gdth_init_pci(gdth_pci_str
*pcistr
,gdth_ha_str
*ha
);
227 static void gdth_enable_int(int hanum
);
228 static int gdth_get_status(unchar
*pIStatus
,int irq
);
229 static int gdth_test_busy(int hanum
);
230 static int gdth_get_cmd_index(int hanum
);
231 static void gdth_release_event(int hanum
);
232 static int gdth_wait(int hanum
,int index
,ulong32 time
);
233 static int gdth_internal_cmd(int hanum
,unchar service
,ushort opcode
,ulong32 p1
,
234 ulong32 p2
,ulong32 p3
);
235 static int gdth_search_drives(int hanum
);
237 static void *gdth_mmap(ulong paddr
, ulong size
);
238 static void gdth_munmap(void *addr
);
240 static const char *gdth_ctr_name(int hanum
);
242 static void gdth_flush(int hanum
);
243 static int gdth_halt(struct notifier_block
*nb
, ulong event
, void *buf
);
246 static unchar DebugState
= DEBUG_GDTH
;
247 extern long sys_syslog(int,char*,int);
248 #define LOGEN sys_syslog(7,NULL,0)
251 #define MAX_SERBUF 160
252 static void ser_init(void);
253 static void ser_puts(char *str
);
254 static void ser_putc(char c
);
255 static int ser_printk(const char *fmt
, ...);
256 static char strbuf
[MAX_SERBUF
+1];
258 #define COM_BASE 0x2f8
260 #define COM_BASE 0x3f8
262 static void ser_init()
264 unsigned port
=COM_BASE
;
268 /* 19200 Baud, if 9600: outb(12,port) */
278 static void ser_puts(char *str
)
283 for (ptr
=str
;*ptr
;++ptr
)
287 static void ser_putc(char c
)
289 unsigned port
=COM_BASE
;
291 while ((inb(port
+5) & 0x20)==0);
295 while ((inb(port
+5) & 0x20)==0);
300 static int ser_printk(const char *fmt
, ...)
306 i
= vsprintf(strbuf
,fmt
,args
);
312 #define TRACE(a) {if (DebugState==1) {ser_printk a;}}
313 #define TRACE2(a) {if (DebugState==1 || DebugState==2) {ser_printk a;}}
314 #define TRACE3(a) {if (DebugState!=0) {ser_printk a;}}
316 #else /* !__SERIAL__ */
317 #define TRACE(a) {if (DebugState==1) {LOGEN;printk a;}}
318 #define TRACE2(a) {if (DebugState==1 || DebugState==2) {LOGEN;printk a;}}
319 #define TRACE3(a) {if (DebugState!=0) {LOGEN;printk a;}}
328 #ifdef GDTH_STATISTICS
329 static ulong32 max_rq
=0, max_index
=0, max_sg
=0;
330 static ulong32 act_ints
=0, act_ios
=0, act_stats
=0, act_rq
=0;
331 static struct timer_list gdth_timer
;
334 #define PTR2USHORT(a) (ushort)(ulong)(a)
335 #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b)
336 #define INDEX_OK(i,t) ((i)<sizeof(t)/sizeof((t)[0]))
338 #define NUMDATA(a) ( (gdth_num_str *)((a)->hostdata))
339 #define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext)
340 #define CMDDATA(a) (&((gdth_ext_str *)((a)->hostdata))->cmdext)
342 #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b))
344 static void *gdth_mmap(ulong paddr
, ulong size
)
346 return ioremap(paddr
, size
);
348 static void gdth_munmap(void *addr
)
350 return iounmap(addr
);
352 #define gdth_readb(addr) readb((ulong)(addr))
353 #define gdth_readw(addr) readw((ulong)(addr))
354 #define gdth_readl(addr) (ulong32)readl((ulong)(addr))
355 #define gdth_writeb(b,addr) writeb((b),(ulong)(addr))
356 #define gdth_writew(b,addr) writew((b),(ulong)(addr))
357 #define gdth_writel(b,addr) writel((b),(ulong)(addr))
359 static unchar gdth_drq_tab
[4] = {5,6,7,7}; /* DRQ table */
360 static unchar gdth_irq_tab
[6] = {0,10,11,12,14,0}; /* IRQ table */
361 static unchar gdth_polling
; /* polling if TRUE */
362 static unchar gdth_from_wait
= FALSE
; /* gdth_wait() */
363 static int wait_index
,wait_hanum
; /* gdth_wait() */
364 static int gdth_ctr_count
= 0; /* controller count */
365 static int gdth_ctr_vcount
= 0; /* virt. ctr. count */
366 static int gdth_ctr_released
= 0; /* gdth_release() */
367 static struct Scsi_Host
*gdth_ctr_tab
[MAXHA
]; /* controller table */
368 static struct Scsi_Host
*gdth_ctr_vtab
[MAXHA
*MAXBUS
]; /* virt. ctr. table */
369 static unchar gdth_write_through
= FALSE
; /* write through */
370 static gdth_evt_str ebuffer
[MAX_EVENTS
]; /* event buffer */
374 #define DIN 1 /* IN data direction */
375 #define DOU 2 /* OUT data direction */
376 #define DNO DIN /* no data transfer */
377 #define DUN DIN /* unknown data direction */
378 static unchar gdth_direction_tab
[0x100] = {
379 DNO
,DNO
,DIN
,DIN
,DOU
,DIN
,DIN
,DOU
,DIN
,DUN
,DOU
,DOU
,DUN
,DUN
,DUN
,DIN
,
380 DNO
,DIN
,DIN
,DOU
,DIN
,DOU
,DNO
,DNO
,DOU
,DNO
,DIN
,DNO
,DIN
,DOU
,DNO
,DUN
,
381 DIN
,DUN
,DIN
,DUN
,DOU
,DIN
,DUN
,DUN
,DIN
,DIN
,DOU
,DNO
,DUN
,DIN
,DOU
,DOU
,
382 DOU
,DOU
,DOU
,DNO
,DIN
,DNO
,DNO
,DIN
,DOU
,DOU
,DOU
,DOU
,DIN
,DOU
,DIN
,DOU
,
383 DOU
,DOU
,DIN
,DIN
,DIN
,DNO
,DUN
,DNO
,DNO
,DNO
,DUN
,DNO
,DOU
,DIN
,DUN
,DUN
,
384 DUN
,DUN
,DUN
,DUN
,DUN
,DOU
,DUN
,DUN
,DUN
,DUN
,DIN
,DUN
,DUN
,DUN
,DUN
,DUN
,
385 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,
386 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,
387 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,
388 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,
389 DUN
,DUN
,DUN
,DUN
,DUN
,DNO
,DNO
,DUN
,DIN
,DNO
,DOU
,DUN
,DNO
,DUN
,DOU
,DOU
,
390 DOU
,DOU
,DOU
,DNO
,DUN
,DIN
,DOU
,DIN
,DIN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,
391 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,
392 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,
393 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DOU
,DUN
,DUN
,DUN
,DUN
,DUN
,
394 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
397 /* __initfunc, __initdata macros */
398 #include <linux/init.h>
400 #define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock)
401 #define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags)
402 #define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags)
404 #define GDTH_LOCK_SCSI_DONE(flags) spin_lock_irqsave(&io_request_lock,flags)
405 #define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(&io_request_lock,flags)
406 #define GDTH_LOCK_SCSI_DOCMD() spin_lock_irq(&io_request_lock)
407 #define GDTH_UNLOCK_SCSI_DOCMD() spin_unlock_irq(&io_request_lock)
409 /* LILO and modprobe/insmod parameters */
410 /* IRQ list for GDT3000/3020 EISA controllers */
411 static int irq
[MAXHA
] __initdata
=
412 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
413 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
414 /* disable driver flag */
415 static int disable __initdata
= 0;
417 static int reserve_mode
= 1;
419 static int reserve_list
[MAX_RES_ARGS
] =
420 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
421 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
422 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
423 /* scan order for PCI controllers */
424 static int reverse_scan
= 0;
425 /* virtual channel for the host drives */
426 static int hdr_channel
= 0;
427 /* max. IDs per channel */
428 static int max_ids
= MAXID
;
430 static int rescan
= 0;
433 /* parameters for modprobe/insmod */
434 MODULE_PARM(irq
, "i");
435 MODULE_PARM(disable
, "i");
436 MODULE_PARM(reserve_mode
, "i");
437 MODULE_PARM(reserve_list
, "4-" __MODULE_STRING(MAX_RES_ARGS
) "i");
438 MODULE_PARM(reverse_scan
, "i");
439 MODULE_PARM(hdr_channel
, "i");
440 MODULE_PARM(max_ids
, "i");
441 MODULE_PARM(rescan
, "i");
442 MODULE_AUTHOR("Achim Leubner");
446 #include <linux/stat.h>
447 #include "gdth_proc.h"
448 #include "gdth_proc.c"
450 /* notifier block to get a notify on system shutdown/halt/reboot */
451 static struct notifier_block gdth_notifier
= {
455 static void gdth_delay(int milliseconds
)
457 if (milliseconds
== 0) {
460 mdelay(milliseconds
);
464 static void gdth_eval_mapping(ulong32 size
, int *cyls
, int *heads
, int *secs
)
466 *cyls
= size
/HEADS
/SECS
;
467 if (*cyls
<= MAXCYLS
) {
470 } else { /* too high for 64*32 */
471 *cyls
= size
/MEDHEADS
/MEDSECS
;
472 if (*cyls
<= MAXCYLS
) {
475 } else { /* too high for 127*63 */
476 *cyls
= size
/BIGHEADS
/BIGSECS
;
483 /* controller search and initialization functions */
485 static int __init
gdth_search_eisa(ushort eisa_adr
)
489 TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr
));
490 id
= inl(eisa_adr
+ID0REG
);
491 if (id
== GDT3A_ID
|| id
== GDT3B_ID
) { /* GDT3000A or GDT3000B */
492 if ((inb(eisa_adr
+EISAREG
) & 8) == 0)
493 return 0; /* not EISA configured */
496 if (id
== GDT3_ID
) /* GDT3000 */
503 static int __init
gdth_search_isa(ulong32 bios_adr
)
508 TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr
));
509 if ((addr
= gdth_mmap(bios_adr
+BIOS_ID_OFFS
, sizeof(ulong32
))) != NULL
) {
510 id
= gdth_readl(addr
);
512 if (id
== GDT2_ID
) /* GDT2000 */
519 static int __init
gdth_search_pci(gdth_pci_str
*pcistr
)
521 ulong32 base0
, base1
, base2
;
522 ushort device_id
, cnt
;
523 struct pci_dev
*pdev
;
525 TRACE(("gdth_search_pci()\n"));
528 for (device_id
= 0; device_id
<= PCI_DEVICE_ID_VORTEX_GDTMAXRP
;
530 if (device_id
> PCI_DEVICE_ID_VORTEX_GDT6555
&&
531 device_id
< PCI_DEVICE_ID_VORTEX_GDT6x17RP
)
534 while ((pdev
= pci_find_device(PCI_VENDOR_ID_VORTEX
,device_id
,pdev
))
536 if (pci_enable_device(pdev
))
540 /* GDT PCI controller found, resources are already in pdev */
541 pcistr
[cnt
].pdev
= pdev
;
542 pcistr
[cnt
].device_id
= device_id
;
543 pcistr
[cnt
].bus
= pdev
->bus
->number
;
544 pcistr
[cnt
].device_fn
= pdev
->devfn
;
545 pcistr
[cnt
].irq
= pdev
->irq
;
546 base0
= pdev
->resource
[0].flags
;
547 base1
= pdev
->resource
[1].flags
;
548 base2
= pdev
->resource
[2].flags
;
549 if (device_id
<= PCI_DEVICE_ID_VORTEX_GDT6000B
|| /* GDT6000/B */
550 device_id
>= PCI_DEVICE_ID_VORTEX_GDT6x17RP
) { /* MPR */
551 if ((base0
& PCI_BASE_ADDRESS_SPACE
) !=
552 PCI_BASE_ADDRESS_SPACE_MEMORY
)
554 pcistr
[cnt
].dpmem
= pdev
->resource
[0].start
;
555 } else { /* GDT6110, GDT6120, .. */
556 if ((base0
& PCI_BASE_ADDRESS_SPACE
) !=
557 PCI_BASE_ADDRESS_SPACE_MEMORY
||
558 (base2
& PCI_BASE_ADDRESS_SPACE
) !=
559 PCI_BASE_ADDRESS_SPACE_MEMORY
||
560 (base1
& PCI_BASE_ADDRESS_SPACE
) !=
561 PCI_BASE_ADDRESS_SPACE_IO
)
563 pcistr
[cnt
].dpmem
= pdev
->resource
[2].start
;
564 pcistr
[cnt
].io_mm
= pdev
->resource
[0].start
;
565 pcistr
[cnt
].io
= pdev
->resource
[1].start
;
567 TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%x\n",
568 pcistr
[cnt
].bus
, PCI_SLOT(pcistr
[cnt
].device_fn
),
569 pcistr
[cnt
].irq
, pcistr
[cnt
].dpmem
));
577 static void __init
gdth_sort_pci(gdth_pci_str
*pcistr
, int cnt
)
582 TRACE(("gdth_sort_pci() cnt %d\n",cnt
));
588 for (i
= 0; i
< cnt
-1; ++i
) {
590 if ((pcistr
[i
].bus
> pcistr
[i
+1].bus
) ||
591 (pcistr
[i
].bus
== pcistr
[i
+1].bus
&&
592 PCI_SLOT(pcistr
[i
].device_fn
) >
593 PCI_SLOT(pcistr
[i
+1].device_fn
))) {
595 pcistr
[i
] = pcistr
[i
+1];
600 if ((pcistr
[i
].bus
< pcistr
[i
+1].bus
) ||
601 (pcistr
[i
].bus
== pcistr
[i
+1].bus
&&
602 PCI_SLOT(pcistr
[i
].device_fn
) <
603 PCI_SLOT(pcistr
[i
+1].device_fn
))) {
605 pcistr
[i
] = pcistr
[i
+1];
615 static int __init
gdth_init_eisa(ushort eisa_adr
,gdth_ha_str
*ha
)
618 unchar prot_ver
,eisacf
,i
,irq_found
;
620 TRACE(("gdth_init_eisa() adr. %x\n",eisa_adr
));
622 /* disable board interrupts, deinitialize services */
623 outb(0xff,eisa_adr
+EDOORREG
);
624 outb(0x00,eisa_adr
+EDENABREG
);
625 outb(0x00,eisa_adr
+EINTENABREG
);
627 outb(0xff,eisa_adr
+LDOORREG
);
628 retries
= INIT_RETRIES
;
630 while (inb(eisa_adr
+EDOORREG
) != 0xff) {
631 if (--retries
== 0) {
632 printk("GDT-EISA: Initialization error (DEINIT failed)\n");
636 TRACE2(("wait for DEINIT: retries=%d\n",retries
));
638 prot_ver
= inb(eisa_adr
+MAILBOXREG
);
639 outb(0xff,eisa_adr
+EDOORREG
);
640 if (prot_ver
!= PROTOCOL_VERSION
) {
641 printk("GDT-EISA: Illegal protocol version\n");
645 ha
->brd_phys
= (ulong32
)eisa_adr
>> 12;
647 outl(0,eisa_adr
+MAILBOXREG
);
648 outl(0,eisa_adr
+MAILBOXREG
+4);
649 outl(0,eisa_adr
+MAILBOXREG
+8);
650 outl(0,eisa_adr
+MAILBOXREG
+12);
653 if ((id
= inl(eisa_adr
+ID0REG
)) == GDT3_ID
) {
656 outl(1,eisa_adr
+MAILBOXREG
+8);
657 outb(0xfe,eisa_adr
+LDOORREG
);
658 retries
= INIT_RETRIES
;
660 while (inb(eisa_adr
+EDOORREG
) != 0xfe) {
661 if (--retries
== 0) {
662 printk("GDT-EISA: Initialization error (get IRQ failed)\n");
667 ha
->irq
= inb(eisa_adr
+MAILBOXREG
);
668 outb(0xff,eisa_adr
+EDOORREG
);
669 TRACE2(("GDT3000/3020: IRQ=%d\n",ha
->irq
));
670 /* check the result */
672 TRACE2(("Unknown IRQ, use IRQ table from cmd line !\n"));
673 for (i
= 0, irq_found
= FALSE
;
674 i
< MAXHA
&& irq
[i
] != 0xff; ++i
) {
675 if (irq
[i
]==10 || irq
[i
]==11 || irq
[i
]==12 || irq
[i
]==14) {
683 printk("GDT-EISA: Can not detect controller IRQ,\n");
684 printk("Use IRQ setting from command line (IRQ = %d)\n",
687 printk("GDT-EISA: Initialization error (unknown IRQ), Enable\n");
688 printk("the controller BIOS or use command line parameters\n");
693 eisacf
= inb(eisa_adr
+EISAREG
) & 7;
694 if (eisacf
> 4) /* level triggered */
696 ha
->irq
= gdth_irq_tab
[eisacf
];
704 static int __init
gdth_init_isa(ulong32 bios_adr
,gdth_ha_str
*ha
)
706 register gdt2_dpram_str
*dp2_ptr
;
708 unchar irq_drq
,prot_ver
;
711 TRACE(("gdth_init_isa() bios adr. %x\n",bios_adr
));
713 ha
->brd
= gdth_mmap(bios_adr
, sizeof(gdt2_dpram_str
));
714 if (ha
->brd
== NULL
) {
715 printk("GDT-ISA: Initialization error (DPMEM remap error)\n");
718 dp2_ptr
= (gdt2_dpram_str
*)ha
->brd
;
719 gdth_writeb(1, &dp2_ptr
->io
.memlock
); /* switch off write protection */
720 /* reset interface area */
721 memset_io((char *)&dp2_ptr
->u
,0,sizeof(dp2_ptr
->u
));
722 if (gdth_readl(&dp2_ptr
->u
) != 0) {
723 printk("GDT-PCI: Initialization error (DPMEM write error)\n");
724 gdth_munmap(ha
->brd
);
728 /* disable board interrupts, read DRQ and IRQ */
729 gdth_writeb(0xff, &dp2_ptr
->io
.irqdel
);
730 gdth_writeb(0x00, &dp2_ptr
->io
.irqen
);
731 gdth_writeb(0x00, &dp2_ptr
->u
.ic
.S_Status
);
732 gdth_writeb(0x00, &dp2_ptr
->u
.ic
.Cmd_Index
);
734 irq_drq
= gdth_readb(&dp2_ptr
->io
.rq
);
735 for (i
=0; i
<3; ++i
) {
736 if ((irq_drq
& 1)==0)
740 ha
->drq
= gdth_drq_tab
[i
];
742 irq_drq
= gdth_readb(&dp2_ptr
->io
.rq
) >> 3;
743 for (i
=1; i
<5; ++i
) {
744 if ((irq_drq
& 1)==0)
748 ha
->irq
= gdth_irq_tab
[i
];
750 /* deinitialize services */
751 gdth_writel(bios_adr
, &dp2_ptr
->u
.ic
.S_Info
[0]);
752 gdth_writeb(0xff, &dp2_ptr
->u
.ic
.S_Cmd_Indx
);
753 gdth_writeb(0, &dp2_ptr
->io
.event
);
754 retries
= INIT_RETRIES
;
756 while (gdth_readb(&dp2_ptr
->u
.ic
.S_Status
) != 0xff) {
757 if (--retries
== 0) {
758 printk("GDT-ISA: Initialization error (DEINIT failed)\n");
759 gdth_munmap(ha
->brd
);
764 prot_ver
= (unchar
)gdth_readl(&dp2_ptr
->u
.ic
.S_Info
[0]);
765 gdth_writeb(0, &dp2_ptr
->u
.ic
.Status
);
766 gdth_writeb(0xff, &dp2_ptr
->io
.irqdel
);
767 if (prot_ver
!= PROTOCOL_VERSION
) {
768 printk("GDT-ISA: Illegal protocol version\n");
769 gdth_munmap(ha
->brd
);
774 ha
->ic_all_size
= sizeof(dp2_ptr
->u
);
776 ha
->brd_phys
= bios_adr
>> 4;
778 /* special request to controller BIOS */
779 gdth_writel(0x00, &dp2_ptr
->u
.ic
.S_Info
[0]);
780 gdth_writel(0x00, &dp2_ptr
->u
.ic
.S_Info
[1]);
781 gdth_writel(0x01, &dp2_ptr
->u
.ic
.S_Info
[2]);
782 gdth_writel(0x00, &dp2_ptr
->u
.ic
.S_Info
[3]);
783 gdth_writeb(0xfe, &dp2_ptr
->u
.ic
.S_Cmd_Indx
);
784 gdth_writeb(0, &dp2_ptr
->io
.event
);
785 retries
= INIT_RETRIES
;
787 while (gdth_readb(&dp2_ptr
->u
.ic
.S_Status
) != 0xfe) {
788 if (--retries
== 0) {
789 printk("GDT-ISA: Initialization error\n");
790 gdth_munmap(ha
->brd
);
795 gdth_writeb(0, &dp2_ptr
->u
.ic
.Status
);
796 gdth_writeb(0xff, &dp2_ptr
->io
.irqdel
);
801 static int __init
gdth_init_pci(gdth_pci_str
*pcistr
,gdth_ha_str
*ha
)
803 register gdt6_dpram_str
*dp6_ptr
;
804 register gdt6c_dpram_str
*dp6c_ptr
;
805 register gdt6m_dpram_str
*dp6m_ptr
;
808 int i
, found
= FALSE
;
810 TRACE(("gdth_init_pci()\n"));
812 ha
->brd_phys
= (pcistr
->bus
<< 8) | (pcistr
->device_fn
& 0xf8);
813 ha
->stype
= (ulong32
)pcistr
->device_id
;
814 ha
->irq
= pcistr
->irq
;
816 if (ha
->stype
<= PCI_DEVICE_ID_VORTEX_GDT6000B
) { /* GDT6000/B */
817 TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr
->dpmem
,ha
->irq
));
818 ha
->brd
= gdth_mmap(pcistr
->dpmem
, sizeof(gdt6_dpram_str
));
819 if (ha
->brd
== NULL
) {
820 printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
823 dp6_ptr
= (gdt6_dpram_str
*)ha
->brd
;
824 /* reset interface area */
825 memset_io((char *)&dp6_ptr
->u
,0,sizeof(dp6_ptr
->u
));
826 if (gdth_readl(&dp6_ptr
->u
) != 0) {
827 printk("GDT-PCI: Initialization error (DPMEM write error)\n");
828 gdth_munmap(ha
->brd
);
832 /* disable board interrupts, deinit services */
833 gdth_writeb(0xff, &dp6_ptr
->io
.irqdel
);
834 gdth_writeb(0x00, &dp6_ptr
->io
.irqen
);;
835 gdth_writeb(0x00, &dp6_ptr
->u
.ic
.S_Status
);
836 gdth_writeb(0x00, &dp6_ptr
->u
.ic
.Cmd_Index
);
838 gdth_writel(pcistr
->dpmem
, &dp6_ptr
->u
.ic
.S_Info
[0]);
839 gdth_writeb(0xff, &dp6_ptr
->u
.ic
.S_Cmd_Indx
);
840 gdth_writeb(0, &dp6_ptr
->io
.event
);
841 retries
= INIT_RETRIES
;
843 while (gdth_readb(&dp6_ptr
->u
.ic
.S_Status
) != 0xff) {
844 if (--retries
== 0) {
845 printk("GDT-PCI: Initialization error (DEINIT failed)\n");
846 gdth_munmap(ha
->brd
);
851 prot_ver
= (unchar
)gdth_readl(&dp6_ptr
->u
.ic
.S_Info
[0]);
852 gdth_writeb(0, &dp6_ptr
->u
.ic
.S_Status
);
853 gdth_writeb(0xff, &dp6_ptr
->io
.irqdel
);
854 if (prot_ver
!= PROTOCOL_VERSION
) {
855 printk("GDT-PCI: Illegal protocol version\n");
856 gdth_munmap(ha
->brd
);
861 ha
->ic_all_size
= sizeof(dp6_ptr
->u
);
863 /* special command to controller BIOS */
864 gdth_writel(0x00, &dp6_ptr
->u
.ic
.S_Info
[0]);
865 gdth_writel(0x00, &dp6_ptr
->u
.ic
.S_Info
[1]);
866 gdth_writel(0x01, &dp6_ptr
->u
.ic
.S_Info
[2]);
867 gdth_writel(0x00, &dp6_ptr
->u
.ic
.S_Info
[3]);
868 gdth_writeb(0xfe, &dp6_ptr
->u
.ic
.S_Cmd_Indx
);
869 gdth_writeb(0, &dp6_ptr
->io
.event
);
870 retries
= INIT_RETRIES
;
872 while (gdth_readb(&dp6_ptr
->u
.ic
.S_Status
) != 0xfe) {
873 if (--retries
== 0) {
874 printk("GDT-PCI: Initialization error\n");
875 gdth_munmap(ha
->brd
);
880 gdth_writeb(0, &dp6_ptr
->u
.ic
.S_Status
);
881 gdth_writeb(0xff, &dp6_ptr
->io
.irqdel
);
883 } else if (ha
->stype
<= PCI_DEVICE_ID_VORTEX_GDT6555
) { /* GDT6110, ... */
884 ha
->plx
= (gdt6c_plx_regs
*)pcistr
->io
;
885 TRACE2(("init_pci_new() dpmem %lx irq %d\n",
886 pcistr
->dpmem
,ha
->irq
));
887 ha
->brd
= gdth_mmap(pcistr
->dpmem
, sizeof(gdt6c_dpram_str
));
888 if (ha
->brd
== NULL
) {
889 printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
890 gdth_munmap(ha
->brd
);
893 dp6c_ptr
= (gdt6c_dpram_str
*)ha
->brd
;
894 /* reset interface area */
895 memset_io((char *)&dp6c_ptr
->u
,0,sizeof(dp6c_ptr
->u
));
896 if (gdth_readl(&dp6c_ptr
->u
) != 0) {
897 printk("GDT-PCI: Initialization error (DPMEM write error)\n");
898 gdth_munmap(ha
->brd
);
902 /* disable board interrupts, deinit services */
903 outb(0x00,PTR2USHORT(&ha
->plx
->control1
));
904 outb(0xff,PTR2USHORT(&ha
->plx
->edoor_reg
));
906 gdth_writeb(0x00, &dp6c_ptr
->u
.ic
.S_Status
);
907 gdth_writeb(0x00, &dp6c_ptr
->u
.ic
.Cmd_Index
);
909 gdth_writel(pcistr
->dpmem
, &dp6c_ptr
->u
.ic
.S_Info
[0]);
910 gdth_writeb(0xff, &dp6c_ptr
->u
.ic
.S_Cmd_Indx
);
912 outb(1,PTR2USHORT(&ha
->plx
->ldoor_reg
));
914 retries
= INIT_RETRIES
;
916 while (gdth_readb(&dp6c_ptr
->u
.ic
.S_Status
) != 0xff) {
917 if (--retries
== 0) {
918 printk("GDT-PCI: Initialization error (DEINIT failed)\n");
919 gdth_munmap(ha
->brd
);
924 prot_ver
= (unchar
)gdth_readl(&dp6c_ptr
->u
.ic
.S_Info
[0]);
925 gdth_writeb(0, &dp6c_ptr
->u
.ic
.Status
);
926 if (prot_ver
!= PROTOCOL_VERSION
) {
927 printk("GDT-PCI: Illegal protocol version\n");
928 gdth_munmap(ha
->brd
);
932 ha
->type
= GDT_PCINEW
;
933 ha
->ic_all_size
= sizeof(dp6c_ptr
->u
);
935 /* special command to controller BIOS */
936 gdth_writel(0x00, &dp6c_ptr
->u
.ic
.S_Info
[0]);
937 gdth_writel(0x00, &dp6c_ptr
->u
.ic
.S_Info
[1]);
938 gdth_writel(0x01, &dp6c_ptr
->u
.ic
.S_Info
[2]);
939 gdth_writel(0x00, &dp6c_ptr
->u
.ic
.S_Info
[3]);
940 gdth_writeb(0xfe, &dp6c_ptr
->u
.ic
.S_Cmd_Indx
);
942 outb(1,PTR2USHORT(&ha
->plx
->ldoor_reg
));
944 retries
= INIT_RETRIES
;
946 while (gdth_readb(&dp6c_ptr
->u
.ic
.S_Status
) != 0xfe) {
947 if (--retries
== 0) {
948 printk("GDT-PCI: Initialization error\n");
949 gdth_munmap(ha
->brd
);
954 gdth_writeb(0, &dp6c_ptr
->u
.ic
.S_Status
);
957 TRACE2(("init_pci_mpr() dpmem %lx irq %d\n",pcistr
->dpmem
,ha
->irq
));
958 ha
->brd
= gdth_mmap(pcistr
->dpmem
, sizeof(gdt6m_dpram_str
));
959 if (ha
->brd
== NULL
) {
960 printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
964 /* check and reset interface area */
965 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
;
966 gdth_writel(DPMEM_MAGIC
, &dp6m_ptr
->u
);
967 if (gdth_readl(&dp6m_ptr
->u
) != DPMEM_MAGIC
) {
968 printk("GDT-PCI: Cannot access DPMEM at 0x%x (shadowed?)\n",
971 for (i
= 0xC8000; i
< 0xE8000; i
+= 0x4000) {
972 gdth_munmap(ha
->brd
);
973 ha
->brd
= gdth_mmap(i
, sizeof(ushort
));
974 if (ha
->brd
== NULL
) {
975 printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
978 if (gdth_readw(ha
->brd
) != 0xffff) {
979 TRACE2(("init_pci_mpr() address 0x%x busy\n", i
));
982 gdth_munmap(ha
->brd
);
983 pci_write_config_dword(pcistr
->pdev
,
984 PCI_BASE_ADDRESS_0
, i
);
985 ha
->brd
= gdth_mmap(i
, sizeof(gdt6m_dpram_str
));
986 if (ha
->brd
== NULL
) {
987 printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
990 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
;
991 gdth_writel(DPMEM_MAGIC
, &dp6m_ptr
->u
);
992 if (gdth_readl(&dp6m_ptr
->u
) == DPMEM_MAGIC
) {
993 printk("GDT-PCI: Use free address at 0x%x\n", i
);
999 printk("GDT-PCI: No free address found!\n");
1000 gdth_munmap(ha
->brd
);
1004 memset_io((char *)&dp6m_ptr
->u
,0,sizeof(dp6m_ptr
->u
));
1006 /* disable board interrupts, deinit services */
1007 gdth_writeb(gdth_readb(&dp6m_ptr
->i960r
.edoor_en_reg
) | 4,
1008 &dp6m_ptr
->i960r
.edoor_en_reg
);
1009 gdth_writeb(0xff, &dp6m_ptr
->i960r
.edoor_reg
);
1010 gdth_writeb(0x00, &dp6m_ptr
->u
.ic
.S_Status
);
1011 gdth_writeb(0x00, &dp6m_ptr
->u
.ic
.Cmd_Index
);
1013 gdth_writel(pcistr
->dpmem
, &dp6m_ptr
->u
.ic
.S_Info
[0]);
1014 gdth_writeb(0xff, &dp6m_ptr
->u
.ic
.S_Cmd_Indx
);
1015 gdth_writeb(1, &dp6m_ptr
->i960r
.ldoor_reg
);
1016 retries
= INIT_RETRIES
;
1018 while (gdth_readb(&dp6m_ptr
->u
.ic
.S_Status
) != 0xff) {
1019 if (--retries
== 0) {
1020 printk("GDT-PCI: Initialization error (DEINIT failed)\n");
1021 gdth_munmap(ha
->brd
);
1026 prot_ver
= (unchar
)gdth_readl(&dp6m_ptr
->u
.ic
.S_Info
[0]);
1027 gdth_writeb(0, &dp6m_ptr
->u
.ic
.S_Status
);
1028 if (prot_ver
!= PROTOCOL_VERSION
) {
1029 printk("GDT-PCI: Illegal protocol version\n");
1030 gdth_munmap(ha
->brd
);
1034 ha
->type
= GDT_PCIMPR
;
1035 ha
->ic_all_size
= sizeof(dp6m_ptr
->u
);
1037 /* special command to controller BIOS */
1038 gdth_writel(0x00, &dp6m_ptr
->u
.ic
.S_Info
[0]);
1039 gdth_writel(0x00, &dp6m_ptr
->u
.ic
.S_Info
[1]);
1040 gdth_writel(0x01, &dp6m_ptr
->u
.ic
.S_Info
[2]);
1041 gdth_writel(0x00, &dp6m_ptr
->u
.ic
.S_Info
[3]);
1042 gdth_writeb(0xfe, &dp6m_ptr
->u
.ic
.S_Cmd_Indx
);
1043 gdth_writeb(1, &dp6m_ptr
->i960r
.ldoor_reg
);
1044 retries
= INIT_RETRIES
;
1046 while (gdth_readb(&dp6m_ptr
->u
.ic
.S_Status
) != 0xfe) {
1047 if (--retries
== 0) {
1048 printk("GDT-PCI: Initialization error\n");
1049 gdth_munmap(ha
->brd
);
1054 gdth_writeb(0, &dp6m_ptr
->u
.ic
.S_Status
);
1061 /* controller protocol functions */
1063 static void __init
gdth_enable_int(int hanum
)
1067 gdt2_dpram_str
*dp2_ptr
;
1068 gdt6_dpram_str
*dp6_ptr
;
1069 gdt6m_dpram_str
*dp6m_ptr
;
1071 TRACE(("gdth_enable_int() hanum %d\n",hanum
));
1072 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1073 GDTH_LOCK_HA(ha
, flags
);
1075 if (ha
->type
== GDT_EISA
) {
1076 outb(0xff, ha
->bmic
+ EDOORREG
);
1077 outb(0xff, ha
->bmic
+ EDENABREG
);
1078 outb(0x01, ha
->bmic
+ EINTENABREG
);
1079 } else if (ha
->type
== GDT_ISA
) {
1080 dp2_ptr
= (gdt2_dpram_str
*)ha
->brd
;
1081 gdth_writeb(1, &dp2_ptr
->io
.irqdel
);
1082 gdth_writeb(0, &dp2_ptr
->u
.ic
.Cmd_Index
);
1083 gdth_writeb(1, &dp2_ptr
->io
.irqen
);
1084 } else if (ha
->type
== GDT_PCI
) {
1085 dp6_ptr
= (gdt6_dpram_str
*)ha
->brd
;
1086 gdth_writeb(1, &dp6_ptr
->io
.irqdel
);
1087 gdth_writeb(0, &dp6_ptr
->u
.ic
.Cmd_Index
);
1088 gdth_writeb(1, &dp6_ptr
->io
.irqen
);
1089 } else if (ha
->type
== GDT_PCINEW
) {
1090 outb(0xff, PTR2USHORT(&ha
->plx
->edoor_reg
));
1091 outb(0x03, PTR2USHORT(&ha
->plx
->control1
));
1092 } else if (ha
->type
== GDT_PCIMPR
) {
1093 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
;
1094 gdth_writeb(0xff, &dp6m_ptr
->i960r
.edoor_reg
);
1095 gdth_writeb(gdth_readb(&dp6m_ptr
->i960r
.edoor_en_reg
) & ~4,
1096 &dp6m_ptr
->i960r
.edoor_en_reg
);
1098 GDTH_UNLOCK_HA(ha
, flags
);
1102 static int gdth_get_status(unchar
*pIStatus
,int irq
)
1104 register gdth_ha_str
*ha
;
1107 TRACE(("gdth_get_status() irq %d ctr_count %d\n",
1108 irq
,gdth_ctr_count
));
1111 for (i
=0; i
<gdth_ctr_count
; ++i
) {
1112 ha
= HADATA(gdth_ctr_tab
[i
]);
1113 if (ha
->irq
!= (unchar
)irq
) /* check IRQ */
1115 if (ha
->type
== GDT_EISA
)
1116 *pIStatus
= inb((ushort
)ha
->bmic
+ EDOORREG
);
1117 else if (ha
->type
== GDT_ISA
)
1119 gdth_readb(&((gdt2_dpram_str
*)ha
->brd
)->u
.ic
.Cmd_Index
);
1120 else if (ha
->type
== GDT_PCI
)
1122 gdth_readb(&((gdt6_dpram_str
*)ha
->brd
)->u
.ic
.Cmd_Index
);
1123 else if (ha
->type
== GDT_PCINEW
)
1124 *pIStatus
= inb(PTR2USHORT(&ha
->plx
->edoor_reg
));
1125 else if (ha
->type
== GDT_PCIMPR
)
1127 gdth_readb(&((gdt6m_dpram_str
*)ha
->brd
)->i960r
.edoor_reg
);
1130 return i
; /* board found */
1136 static int gdth_test_busy(int hanum
)
1138 register gdth_ha_str
*ha
;
1139 register int gdtsema0
= 0;
1141 TRACE(("gdth_test_busy() hanum %d\n",hanum
));
1143 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1144 if (ha
->type
== GDT_EISA
)
1145 gdtsema0
= (int)inb(ha
->bmic
+ SEMA0REG
);
1146 else if (ha
->type
== GDT_ISA
)
1147 gdtsema0
= (int)gdth_readb(&((gdt2_dpram_str
*)ha
->brd
)->u
.ic
.Sema0
);
1148 else if (ha
->type
== GDT_PCI
)
1149 gdtsema0
= (int)gdth_readb(&((gdt6_dpram_str
*)ha
->brd
)->u
.ic
.Sema0
);
1150 else if (ha
->type
== GDT_PCINEW
)
1151 gdtsema0
= (int)inb(PTR2USHORT(&ha
->plx
->sema0_reg
));
1152 else if (ha
->type
== GDT_PCIMPR
)
1154 (int)gdth_readb(&((gdt6m_dpram_str
*)ha
->brd
)->i960r
.sema0_reg
);
1156 return (gdtsema0
& 1);
1160 static int gdth_get_cmd_index(int hanum
)
1162 register gdth_ha_str
*ha
;
1165 TRACE(("gdth_get_cmd_index() hanum %d\n",hanum
));
1167 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1168 for (i
=0; i
<GDTH_MAXCMDS
; ++i
) {
1169 if (ha
->cmd_tab
[i
].cmnd
== UNUSED_CMND
) {
1170 ha
->cmd_tab
[i
].cmnd
= ha
->pccb
->RequestBuffer
;
1171 ha
->cmd_tab
[i
].service
= ha
->pccb
->Service
;
1172 ha
->pccb
->CommandIndex
= (ulong32
)i
+2;
1180 static void gdth_set_sema0(int hanum
)
1182 register gdth_ha_str
*ha
;
1184 TRACE(("gdth_set_sema0() hanum %d\n",hanum
));
1186 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1187 if (ha
->type
== GDT_EISA
) {
1188 outb(1, ha
->bmic
+ SEMA0REG
);
1189 } else if (ha
->type
== GDT_ISA
) {
1190 gdth_writeb(1, &((gdt2_dpram_str
*)ha
->brd
)->u
.ic
.Sema0
);
1191 } else if (ha
->type
== GDT_PCI
) {
1192 gdth_writeb(1, &((gdt6_dpram_str
*)ha
->brd
)->u
.ic
.Sema0
);
1193 } else if (ha
->type
== GDT_PCINEW
) {
1194 outb(1, PTR2USHORT(&ha
->plx
->sema0_reg
));
1195 } else if (ha
->type
== GDT_PCIMPR
) {
1196 gdth_writeb(1, &((gdt6m_dpram_str
*)ha
->brd
)->i960r
.sema0_reg
);
1201 static void gdth_copy_command(int hanum
)
1203 register gdth_ha_str
*ha
;
1204 register gdth_cmd_str
*cmd_ptr
;
1205 register gdt6m_dpram_str
*dp6m_ptr
;
1206 register gdt6c_dpram_str
*dp6c_ptr
;
1207 gdt6_dpram_str
*dp6_ptr
;
1208 gdt2_dpram_str
*dp2_ptr
;
1209 ushort cp_count
,dp_offset
,cmd_no
;
1211 TRACE(("gdth_copy_command() hanum %d\n",hanum
));
1213 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1214 cp_count
= ha
->cmd_len
;
1215 dp_offset
= ha
->cmd_offs_dpmem
;
1216 cmd_no
= ha
->cmd_cnt
;
1220 if (ha
->type
== GDT_EISA
)
1221 return; /* no DPMEM, no copy */
1223 /* set cpcount dword aligned */
1225 cp_count
+= (4 - (cp_count
& 3));
1227 ha
->cmd_offs_dpmem
+= cp_count
;
1229 /* set offset and service, copy command to DPMEM */
1230 if (ha
->type
== GDT_ISA
) {
1231 dp2_ptr
= (gdt2_dpram_str
*)ha
->brd
;
1232 gdth_writew(dp_offset
+ DPMEM_COMMAND_OFFSET
,
1233 &dp2_ptr
->u
.ic
.comm_queue
[cmd_no
].offset
);
1234 gdth_writew((ushort
)cmd_ptr
->Service
,
1235 &dp2_ptr
->u
.ic
.comm_queue
[cmd_no
].serv_id
);
1236 memcpy_toio(&dp2_ptr
->u
.ic
.gdt_dpr_cmd
[dp_offset
],cmd_ptr
,cp_count
);
1237 } else if (ha
->type
== GDT_PCI
) {
1238 dp6_ptr
= (gdt6_dpram_str
*)ha
->brd
;
1239 gdth_writew(dp_offset
+ DPMEM_COMMAND_OFFSET
,
1240 &dp6_ptr
->u
.ic
.comm_queue
[cmd_no
].offset
);
1241 gdth_writew((ushort
)cmd_ptr
->Service
,
1242 &dp6_ptr
->u
.ic
.comm_queue
[cmd_no
].serv_id
);
1243 memcpy_toio(&dp6_ptr
->u
.ic
.gdt_dpr_cmd
[dp_offset
],cmd_ptr
,cp_count
);
1244 } else if (ha
->type
== GDT_PCINEW
) {
1245 dp6c_ptr
= (gdt6c_dpram_str
*)ha
->brd
;
1246 gdth_writew(dp_offset
+ DPMEM_COMMAND_OFFSET
,
1247 &dp6c_ptr
->u
.ic
.comm_queue
[cmd_no
].offset
);
1248 gdth_writew((ushort
)cmd_ptr
->Service
,
1249 &dp6c_ptr
->u
.ic
.comm_queue
[cmd_no
].serv_id
);
1250 memcpy_toio(&dp6c_ptr
->u
.ic
.gdt_dpr_cmd
[dp_offset
],cmd_ptr
,cp_count
);
1251 } else if (ha
->type
== GDT_PCIMPR
) {
1252 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
;
1253 gdth_writew(dp_offset
+ DPMEM_COMMAND_OFFSET
,
1254 &dp6m_ptr
->u
.ic
.comm_queue
[cmd_no
].offset
);
1255 gdth_writew((ushort
)cmd_ptr
->Service
,
1256 &dp6m_ptr
->u
.ic
.comm_queue
[cmd_no
].serv_id
);
1257 memcpy_toio(&dp6m_ptr
->u
.ic
.gdt_dpr_cmd
[dp_offset
],cmd_ptr
,cp_count
);
1262 static void gdth_release_event(int hanum
)
1264 register gdth_ha_str
*ha
;
1266 TRACE(("gdth_release_event() hanum %d\n",hanum
));
1267 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1269 #ifdef GDTH_STATISTICS
1272 for (i
=0,j
=0; j
<GDTH_MAXCMDS
; ++j
) {
1273 if (ha
->cmd_tab
[j
].cmnd
!= UNUSED_CMND
)
1276 if (max_index
< i
) {
1278 TRACE3(("GDT: max_index = %d\n",(ushort
)i
));
1283 if (ha
->pccb
->OpCode
== GDT_INIT
)
1284 ha
->pccb
->Service
|= 0x80;
1286 if (ha
->type
== GDT_EISA
) {
1287 if (ha
->pccb
->OpCode
== GDT_INIT
) /* store DMA buffer */
1288 outl(virt_to_bus(ha
->pccb
), ha
->bmic
+ MAILBOXREG
);
1289 outb(ha
->pccb
->Service
, ha
->bmic
+ LDOORREG
);
1290 } else if (ha
->type
== GDT_ISA
) {
1291 gdth_writeb(0, &((gdt2_dpram_str
*)ha
->brd
)->io
.event
);
1292 } else if (ha
->type
== GDT_PCI
) {
1293 gdth_writeb(0, &((gdt6_dpram_str
*)ha
->brd
)->io
.event
);
1294 } else if (ha
->type
== GDT_PCINEW
) {
1295 outb(1, PTR2USHORT(&ha
->plx
->ldoor_reg
));
1296 } else if (ha
->type
== GDT_PCIMPR
) {
1297 gdth_writeb(1, &((gdt6m_dpram_str
*)ha
->brd
)->i960r
.ldoor_reg
);
1302 static int gdth_wait(int hanum
,int index
,ulong32 time
)
1305 int answer_found
= FALSE
;
1307 TRACE(("gdth_wait() hanum %d index %d time %d\n",hanum
,index
,time
));
1309 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1311 return 1; /* no wait required */
1313 gdth_from_wait
= TRUE
;
1315 gdth_interrupt((int)ha
->irq
,ha
,NULL
);
1316 if (wait_hanum
==hanum
&& wait_index
==index
) {
1317 answer_found
= TRUE
;
1322 gdth_from_wait
= FALSE
;
1324 while (gdth_test_busy(hanum
))
1327 return (answer_found
);
1331 static int gdth_internal_cmd(int hanum
,unchar service
,ushort opcode
,ulong32 p1
,
1332 ulong32 p2
,ulong32 p3
)
1334 register gdth_ha_str
*ha
;
1335 register gdth_cmd_str
*cmd_ptr
;
1338 TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service
,opcode
));
1340 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1342 memset((char*)cmd_ptr
,0,sizeof(gdth_cmd_str
));
1345 for (retries
= INIT_RETRIES
;;) {
1346 cmd_ptr
->Service
= service
;
1347 cmd_ptr
->RequestBuffer
= INTERNAL_CMND
;
1348 if (!(index
=gdth_get_cmd_index(hanum
))) {
1349 TRACE(("GDT: No free command index found\n"));
1352 gdth_set_sema0(hanum
);
1353 cmd_ptr
->OpCode
= opcode
;
1354 cmd_ptr
->BoardNode
= LOCALBOARD
;
1355 if (service
== CACHESERVICE
) {
1356 if (opcode
== GDT_IOCTL
) {
1357 cmd_ptr
->u
.ioctl
.subfunc
= p1
;
1358 cmd_ptr
->u
.ioctl
.channel
= p2
;
1359 cmd_ptr
->u
.ioctl
.param_size
= (ushort
)p3
;
1360 cmd_ptr
->u
.ioctl
.p_param
= virt_to_bus(ha
->pscratch
);
1362 cmd_ptr
->u
.cache
.DeviceNo
= (ushort
)p1
;
1363 cmd_ptr
->u
.cache
.BlockNo
= p2
;
1365 } else if (service
== SCSIRAWSERVICE
) {
1366 cmd_ptr
->u
.raw
.direction
= p1
;
1367 cmd_ptr
->u
.raw
.bus
= (unchar
)p2
;
1368 cmd_ptr
->u
.raw
.target
= (unchar
)p3
;
1369 cmd_ptr
->u
.raw
.lun
= (unchar
)(p3
>> 8);
1371 ha
->cmd_len
= sizeof(gdth_cmd_str
);
1372 ha
->cmd_offs_dpmem
= 0;
1374 gdth_copy_command(hanum
);
1375 gdth_release_event(hanum
);
1377 if (!gdth_wait(hanum
,index
,INIT_TIMEOUT
)) {
1378 printk("GDT: Initialization error (timeout service %d)\n",service
);
1381 if (ha
->status
!= S_BSY
|| --retries
== 0)
1386 return (ha
->status
!= S_OK
? 0:1);
1390 /* search for devices */
1392 static int __init
gdth_search_drives(int hanum
)
1394 register gdth_ha_str
*ha
;
1396 int drv_cyls
, drv_hds
, drv_secs
;
1398 ulong32 drv_cnt
, drv_no
, j
;
1399 gdth_getch_str
*chn
;
1400 gdth_drlist_str
*drl
;
1401 gdth_iochan_str
*ioc
;
1402 gdth_raw_iochan_str
*iocr
;
1403 gdth_arraylist_str
*alst
;
1405 TRACE(("gdth_search_drives() hanum %d\n",hanum
));
1406 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1408 /* initialize controller services, at first: screen service */
1409 if (!gdth_internal_cmd(hanum
,SCREENSERVICE
,GDT_INIT
,0,0,0)) {
1410 printk("GDT: Initialization error screen service (code %d)\n",
1414 TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n"));
1416 /* initialize cache service */
1417 if (!gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_INIT
,LINUX_OS
,0,0)) {
1418 printk("GDT: Initialization error cache service (code %d)\n",
1422 TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n"));
1423 cdev_cnt
= (ushort
)ha
->info
;
1425 /* mount all cache devices */
1426 gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_MOUNT
,0xffff,1,0);
1427 TRACE2(("gdth_search_drives(): mountall CACHESERVICE OK\n"));
1429 /* initialize cache service after mountall */
1430 if (!gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_INIT
,LINUX_OS
,0,0)) {
1431 printk("GDT: Initialization error cache service (code %d)\n",
1435 TRACE2(("gdth_search_drives() CACHES. init. after mountall\n"));
1436 cdev_cnt
= (ushort
)ha
->info
;
1438 /* detect number of buses - try new IOCTL */
1439 iocr
= (gdth_raw_iochan_str
*)ha
->pscratch
;
1440 iocr
->hdr
.version
= 0xffffffff;
1441 iocr
->hdr
.list_entries
= MAXBUS
;
1442 iocr
->hdr
.first_chan
= 0;
1443 iocr
->hdr
.last_chan
= MAXBUS
-1;
1444 iocr
->hdr
.list_offset
= GDTOFFSOF(gdth_raw_iochan_str
, list
[0]);
1445 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,IOCHAN_RAW_DESC
,
1446 INVALID_CHANNEL
,sizeof(gdth_raw_iochan_str
))) {
1447 TRACE2(("IOCHAN_RAW_DESC supported!\n"));
1448 ha
->bus_cnt
= iocr
->hdr
.chan_count
;
1449 for (bus_no
= 0; bus_no
< ha
->bus_cnt
; ++bus_no
) {
1450 if (iocr
->list
[bus_no
].proc_id
< MAXID
)
1451 ha
->bus_id
[bus_no
] = iocr
->list
[bus_no
].proc_id
;
1453 ha
->bus_id
[bus_no
] = 0xff;
1457 chn
= (gdth_getch_str
*)ha
->pscratch
;
1458 for (bus_no
= 0; bus_no
< MAXBUS
; ++bus_no
) {
1459 chn
->channel_no
= bus_no
;
1460 if (!gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,
1461 SCSI_CHAN_CNT
| L_CTRL_PATTERN
,
1462 IO_CHANNEL
| INVALID_CHANNEL
,
1463 sizeof(gdth_getch_str
))) {
1465 printk("GDT: Error detecting channel count (0x%x)\n",
1471 if (chn
->siop_id
< MAXID
)
1472 ha
->bus_id
[bus_no
] = chn
->siop_id
;
1474 ha
->bus_id
[bus_no
] = 0xff;
1476 ha
->bus_cnt
= (unchar
)bus_no
;
1478 TRACE2(("gdth_search_drives() %d channels\n",ha
->bus_cnt
));
1480 /* read cache configuration */
1481 if (!gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,CACHE_INFO
,
1482 INVALID_CHANNEL
,sizeof(gdth_cinfo_str
))) {
1483 printk("GDT: Initialization error cache service (code %d)\n",
1487 ha
->cpar
= ((gdth_cinfo_str
*)ha
->pscratch
)->cpar
;
1488 TRACE2(("gdth_search_drives() cinfo: vs %x sta %d str %d dw %d b %d\n",
1489 ha
->cpar
.version
,ha
->cpar
.state
,ha
->cpar
.strategy
,
1490 ha
->cpar
.write_back
,ha
->cpar
.block_size
));
1492 /* read board info and features */
1493 ha
->more_proc
= FALSE
;
1494 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,BOARD_INFO
,
1495 INVALID_CHANNEL
,sizeof(gdth_binfo_str
))) {
1496 memcpy(&ha
->binfo
, (gdth_binfo_str
*)ha
->pscratch
, sizeof(gdth_binfo_str
));
1497 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,BOARD_FEATURES
,
1498 INVALID_CHANNEL
,sizeof(gdth_bfeat_str
))) {
1499 TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n"));
1500 ha
->bfeat
= *(gdth_bfeat_str
*)ha
->pscratch
;
1501 ha
->more_proc
= TRUE
;
1504 TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n"));
1505 strcpy(ha
->binfo
.type_string
, gdth_ctr_name(hanum
));
1507 TRACE2(("Controller name: %s\n",ha
->binfo
.type_string
));
1509 /* read more informations */
1510 if (ha
->more_proc
) {
1511 /* physical drives, channel addresses */
1512 ioc
= (gdth_iochan_str
*)ha
->pscratch
;
1513 ioc
->hdr
.version
= 0xffffffff;
1514 ioc
->hdr
.list_entries
= MAXBUS
;
1515 ioc
->hdr
.first_chan
= 0;
1516 ioc
->hdr
.last_chan
= MAXBUS
-1;
1517 ioc
->hdr
.list_offset
= GDTOFFSOF(gdth_iochan_str
, list
[0]);
1518 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,IOCHAN_DESC
,
1519 INVALID_CHANNEL
,sizeof(gdth_iochan_str
))) {
1520 for (bus_no
= 0; bus_no
< ha
->bus_cnt
; ++bus_no
) {
1521 ha
->raw
[bus_no
].address
= ioc
->list
[bus_no
].address
;
1522 ha
->raw
[bus_no
].local_no
= ioc
->list
[bus_no
].local_no
;
1525 for (bus_no
= 0; bus_no
< ha
->bus_cnt
; ++bus_no
) {
1526 ha
->raw
[bus_no
].address
= IO_CHANNEL
;
1527 ha
->raw
[bus_no
].local_no
= bus_no
;
1530 for (bus_no
= 0; bus_no
< ha
->bus_cnt
; ++bus_no
) {
1531 chn
= (gdth_getch_str
*)ha
->pscratch
;
1532 chn
->channel_no
= ha
->raw
[bus_no
].local_no
;
1533 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,
1534 SCSI_CHAN_CNT
| L_CTRL_PATTERN
,
1535 ha
->raw
[bus_no
].address
| INVALID_CHANNEL
,
1536 sizeof(gdth_getch_str
))) {
1537 ha
->raw
[bus_no
].pdev_cnt
= chn
->drive_cnt
;
1538 TRACE2(("Channel %d: %d phys. drives\n",
1539 bus_no
,chn
->drive_cnt
));
1541 if (ha
->raw
[bus_no
].pdev_cnt
> 0) {
1542 drl
= (gdth_drlist_str
*)ha
->pscratch
;
1543 drl
->sc_no
= ha
->raw
[bus_no
].local_no
;
1544 drl
->sc_cnt
= ha
->raw
[bus_no
].pdev_cnt
;
1545 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,
1546 SCSI_DR_LIST
| L_CTRL_PATTERN
,
1547 ha
->raw
[bus_no
].address
| INVALID_CHANNEL
,
1548 sizeof(gdth_drlist_str
))) {
1549 for (j
= 0; j
< ha
->raw
[bus_no
].pdev_cnt
; ++j
)
1550 ha
->raw
[bus_no
].id_list
[j
] = drl
->sc_list
[j
];
1552 ha
->raw
[bus_no
].pdev_cnt
= 0;
1557 /* logical drives */
1558 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,CACHE_DRV_CNT
,
1559 INVALID_CHANNEL
,sizeof(ulong32
))) {
1560 drv_cnt
= *(ulong32
*)ha
->pscratch
;
1561 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,CACHE_DRV_LIST
,
1562 INVALID_CHANNEL
,drv_cnt
* sizeof(ulong32
))) {
1563 for (j
= 0; j
< drv_cnt
; ++j
) {
1564 drv_no
= ((ulong32
*)ha
->pscratch
)[j
];
1565 if (drv_no
< MAX_HDRIVES
) {
1566 ha
->hdr
[drv_no
].is_logdrv
= TRUE
;
1567 TRACE2(("Drive %d is log. drive\n",drv_no
));
1571 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,
1572 ARRAY_DRV_LIST
| LA_CTRL_PATTERN
,
1573 0, 35 * sizeof(gdth_arraylist_str
))) {
1574 for (j
= 0; j
< 35; ++j
) {
1575 alst
= &((gdth_arraylist_str
*)ha
->pscratch
)[j
];
1576 ha
->hdr
[j
].is_arraydrv
= alst
->is_arrayd
;
1577 ha
->hdr
[j
].is_master
= alst
->is_master
;
1578 ha
->hdr
[j
].is_parity
= alst
->is_parity
;
1579 ha
->hdr
[j
].is_hotfix
= alst
->is_hotfix
;
1580 ha
->hdr
[j
].master_no
= alst
->cd_handle
;
1586 /* initialize raw service */
1587 if (!gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_INIT
,0,0,0)) {
1588 printk("GDT: Initialization error raw service (code %d)\n",
1592 TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n"));
1594 /* set/get features raw service (scatter/gather) */
1596 if (gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_SET_FEAT
,SCATTER_GATHER
,
1598 TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n"));
1599 if (gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_GET_FEAT
,0,0,0)) {
1600 TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n",
1602 ha
->raw_feat
= (ushort
)ha
->info
;
1606 /* set/get features cache service (equal to raw service) */
1607 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_SET_FEAT
,0,
1608 SCATTER_GATHER
,0)) {
1609 TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n"));
1610 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_GET_FEAT
,0,0,0)) {
1611 TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n",
1613 ha
->cache_feat
= (ushort
)ha
->info
;
1617 /* reserve drives for raw service */
1618 if (reserve_mode
!= 0) {
1619 gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_RESERVE_ALL
,
1620 reserve_mode
== 1 ? 1 : 3, 0, 0);
1621 TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n",
1624 for (i
= 0; i
< MAX_RES_ARGS
; i
+= 4) {
1625 if (reserve_list
[i
] == hanum
&& reserve_list
[i
+1] < ha
->bus_cnt
&&
1626 reserve_list
[i
+2] < ha
->tid_cnt
&& reserve_list
[i
+3] < MAXLUN
) {
1627 TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n",
1628 reserve_list
[i
], reserve_list
[i
+1],
1629 reserve_list
[i
+2], reserve_list
[i
+3]));
1630 if (!gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_RESERVE
,0,
1631 reserve_list
[i
+1], reserve_list
[i
+2] |
1632 (reserve_list
[i
+3] << 8))) {
1633 printk("GDT: Error raw service (RESERVE, code %d)\n",
1639 /* scanning for cache devices */
1640 for (i
=0; i
<cdev_cnt
&& i
<MAX_HDRIVES
; ++i
) {
1641 TRACE(("gdth_search_drives() cachedev. %d\n",i
));
1642 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_INFO
,i
,0,0)) {
1643 /* static relation between host drive number and Bus/ID */
1644 TRACE(("gdth_search_dr() drive %d mapped to bus/id %d/%d\n",
1647 ha
->hdr
[i
].present
= TRUE
;
1648 ha
->hdr
[i
].size
= ha
->info
;
1650 /* evaluate mapping (sectors per head, heads per cylinder) */
1651 ha
->hdr
[i
].size
&= ~SECS32
;
1652 if (ha
->info2
== 0) {
1653 gdth_eval_mapping(ha
->hdr
[i
].size
,&drv_cyls
,&drv_hds
,&drv_secs
);
1655 drv_hds
= ha
->info2
& 0xff;
1656 drv_secs
= (ha
->info2
>> 8) & 0xff;
1657 drv_cyls
= ha
->hdr
[i
].size
/drv_hds
/drv_secs
;
1659 ha
->hdr
[i
].heads
= (unchar
)drv_hds
;
1660 ha
->hdr
[i
].secs
= (unchar
)drv_secs
;
1662 ha
->hdr
[i
].size
= drv_cyls
* drv_hds
* drv_secs
;
1663 TRACE2(("gdth_search_dr() cdr. %d size %d hds %d scs %d\n",
1664 i
,ha
->hdr
[i
].size
,drv_hds
,drv_secs
));
1666 /* get informations about device */
1667 if (gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_DEVTYPE
,i
,
1669 TRACE(("gdth_search_dr() cache drive %d devtype %d\n",
1671 ha
->hdr
[i
].devtype
= (ushort
)ha
->info
;
1676 TRACE(("gdth_search_drives() OK\n"));
1681 /* command queueing/sending functions */
1683 static void gdth_putq(int hanum
,Scsi_Cmnd
*scp
,unchar priority
)
1685 register gdth_ha_str
*ha
;
1686 register Scsi_Cmnd
*pscp
;
1687 register Scsi_Cmnd
*nscp
;
1691 TRACE(("gdth_putq() priority %d\n",priority
));
1692 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1693 GDTH_LOCK_HA(ha
, flags
);
1695 scp
->SCp
.this_residual
= (int)priority
;
1698 if (priority
>= DEFAULT_PRI
) {
1699 if ((b
!= ha
->virt_bus
&& ha
->raw
[BUS_L2P(ha
,b
)].lock
) ||
1700 (b
== ha
->virt_bus
&& t
< MAX_HDRIVES
&& ha
->hdr
[t
].lock
)) {
1701 TRACE2(("gdth_putq(): locked IO -> update_timeout()\n"));
1702 scp
->SCp
.buffers_residual
= gdth_update_timeout(hanum
, scp
, 0);
1706 if (ha
->req_first
==NULL
) {
1707 ha
->req_first
= scp
; /* queue was empty */
1708 scp
->SCp
.ptr
= NULL
;
1709 } else { /* queue not empty */
1710 pscp
= ha
->req_first
;
1711 nscp
= (Scsi_Cmnd
*)pscp
->SCp
.ptr
;
1712 /* priority: 0-highest,..,0xff-lowest */
1713 while (nscp
&& (unchar
)nscp
->SCp
.this_residual
<= priority
) {
1715 nscp
= (Scsi_Cmnd
*)pscp
->SCp
.ptr
;
1717 pscp
->SCp
.ptr
= (char *)scp
;
1718 scp
->SCp
.ptr
= (char *)nscp
;
1720 GDTH_UNLOCK_HA(ha
, flags
);
1722 #ifdef GDTH_STATISTICS
1724 for (nscp
=ha
->req_first
; nscp
; nscp
=(Scsi_Cmnd
*)nscp
->SCp
.ptr
)
1726 if (max_rq
< flags
) {
1728 TRACE3(("GDT: max_rq = %d\n",(ushort
)max_rq
));
1733 static void gdth_next(int hanum
)
1735 register gdth_ha_str
*ha
;
1736 register Scsi_Cmnd
*pscp
;
1737 register Scsi_Cmnd
*nscp
;
1738 unchar b
, t
, firsttime
;
1739 unchar this_cmd
, next_cmd
;
1743 TRACE(("gdth_next() hanum %d\n",hanum
));
1744 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1745 GDTH_LOCK_HA(ha
, flags
);
1747 ha
->cmd_cnt
= ha
->cmd_offs_dpmem
= 0;
1748 this_cmd
= firsttime
= TRUE
;
1749 next_cmd
= gdth_polling
? FALSE
:TRUE
;
1752 for (nscp
= pscp
= ha
->req_first
; nscp
; nscp
= (Scsi_Cmnd
*)nscp
->SCp
.ptr
) {
1753 if (nscp
!= pscp
&& nscp
!= (Scsi_Cmnd
*)pscp
->SCp
.ptr
)
1754 pscp
= (Scsi_Cmnd
*)pscp
->SCp
.ptr
;
1757 if (nscp
->SCp
.this_residual
>= DEFAULT_PRI
) {
1758 if ((b
!= ha
->virt_bus
&& ha
->raw
[BUS_L2P(ha
,b
)].lock
) ||
1759 (b
== ha
->virt_bus
&& t
< MAX_HDRIVES
&& ha
->hdr
[t
].lock
))
1764 if (gdth_test_busy(hanum
)) { /* controller busy ? */
1765 TRACE(("gdth_next() controller %d busy !\n",hanum
));
1766 if (!gdth_polling
) {
1767 GDTH_UNLOCK_HA(ha
, flags
);
1770 while (gdth_test_busy(hanum
))
1776 if (nscp
->done
!= gdth_scsi_done
)
1778 if (nscp
->SCp
.phase
== -1) {
1779 nscp
->SCp
.phase
= SCSIRAWSERVICE
; /* default: raw svc. */
1780 if (nscp
->cmnd
[0] == TEST_UNIT_READY
) {
1781 TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n",
1783 /* TEST_UNIT_READY -> set scan mode */
1784 if ((ha
->scan_mode
& 0x0f) == 0) {
1785 if (b
== 0 && t
== 0 && nscp
->lun
== 0) {
1787 TRACE2(("Scan mode: 0x%x\n", ha
->scan_mode
));
1789 } else if ((ha
->scan_mode
& 0x0f) == 1) {
1790 if (b
== 0 && ((t
== 0 && nscp
->lun
== 1) ||
1791 (t
== 1 && nscp
->lun
== 0))) {
1792 nscp
->SCp
.Status
= GDT_SCAN_START
;
1793 nscp
->SCp
.phase
|= ((ha
->scan_mode
& 0x10 ? 1:0) << 8);
1794 ha
->scan_mode
= 0x12;
1795 TRACE2(("Scan mode: 0x%x (SCAN_START)\n",
1798 ha
->scan_mode
&= 0x10;
1799 TRACE2(("Scan mode: 0x%x\n", ha
->scan_mode
));
1801 } else if (ha
->scan_mode
== 0x12) {
1802 if (b
== ha
->bus_cnt
&& t
== ha
->tid_cnt
-1) {
1803 nscp
->SCp
.Status
= GDT_SCAN_END
;
1804 ha
->scan_mode
&= 0x10;
1805 TRACE2(("Scan mode: 0x%x (SCAN_END)\n",
1813 if (nscp
->SCp
.Status
!= -1) {
1814 if ((nscp
->SCp
.phase
& 0xff) == SCSIRAWSERVICE
) {
1815 if (!(cmd_index
=gdth_fill_raw_cmd(hanum
,nscp
,BUS_L2P(ha
,b
))))
1821 if (nscp
->done
== gdth_scsi_done
) {
1822 if (!(cmd_index
=gdth_special_cmd(hanum
,nscp
)))
1826 if (b
!= ha
->virt_bus
) {
1827 if (ha
->raw
[BUS_L2P(ha
,b
)].io_cnt
[t
] >= GDTH_MAX_RAW
||
1828 !(cmd_index
=gdth_fill_raw_cmd(hanum
,nscp
,BUS_L2P(ha
,b
))))
1831 ha
->raw
[BUS_L2P(ha
,b
)].io_cnt
[t
]++;
1832 } else if (t
>= MAX_HDRIVES
|| !ha
->hdr
[t
].present
|| nscp
->lun
!= 0) {
1833 TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n",
1834 nscp
->cmnd
[0], b
, t
, nscp
->lun
));
1835 nscp
->result
= DID_BAD_TARGET
<< 16;
1836 GDTH_UNLOCK_HA(ha
,flags
);
1837 /* io_request_lock already active ! */
1838 nscp
->scsi_done(nscp
);
1839 GDTH_LOCK_HA(ha
,flags
);
1841 switch (nscp
->cmnd
[0]) {
1842 case TEST_UNIT_READY
:
1849 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp
->cmnd
[0],
1850 nscp
->cmnd
[1],nscp
->cmnd
[2],nscp
->cmnd
[3],
1851 nscp
->cmnd
[4],nscp
->cmnd
[5]));
1852 if (gdth_internal_cache_cmd(hanum
,nscp
)) {
1853 GDTH_UNLOCK_HA(ha
,flags
);
1854 /* io_request_lock already active ! */
1855 nscp
->scsi_done(nscp
);
1856 GDTH_LOCK_HA(ha
,flags
);
1860 case ALLOW_MEDIUM_REMOVAL
:
1861 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp
->cmnd
[0],
1862 nscp
->cmnd
[1],nscp
->cmnd
[2],nscp
->cmnd
[3],
1863 nscp
->cmnd
[4],nscp
->cmnd
[5]));
1864 if ( (nscp
->cmnd
[4]&1) && !(ha
->hdr
[t
].devtype
&1) ) {
1865 TRACE(("Prevent r. nonremov. drive->do nothing\n"));
1866 nscp
->result
= DID_OK
<< 16;
1867 if (!nscp
->SCp
.have_data_in
)
1868 nscp
->SCp
.have_data_in
++;
1870 GDTH_UNLOCK_HA(ha
,flags
);
1871 /* io_request_lock already active ! */
1872 nscp
->scsi_done(nscp
);
1873 GDTH_LOCK_HA(ha
,flags
);
1876 nscp
->cmnd
[3] = (ha
->hdr
[t
].devtype
&1) ? 1:0;
1877 TRACE(("Prevent/allow r. %d rem. drive %d\n",
1878 nscp
->cmnd
[4],nscp
->cmnd
[3]));
1879 if (!(cmd_index
=gdth_fill_cache_cmd(hanum
,nscp
,t
)))
1888 if (!(cmd_index
=gdth_fill_cache_cmd(hanum
,nscp
,t
)))
1893 TRACE2(("cache cmd %x/%x/%x/%x/%x/%x unknown\n",nscp
->cmnd
[0],
1894 nscp
->cmnd
[1],nscp
->cmnd
[2],nscp
->cmnd
[3],
1895 nscp
->cmnd
[4],nscp
->cmnd
[5]));
1896 printk("GDT: Unknown SCSI command 0x%x to cache service !\n",
1898 nscp
->result
= DID_ABORT
<< 16;
1899 if (!nscp
->SCp
.have_data_in
)
1900 nscp
->SCp
.have_data_in
++;
1902 GDTH_UNLOCK_HA(ha
,flags
);
1903 /* io_request_lock already active ! */
1904 nscp
->scsi_done(nscp
);
1905 GDTH_LOCK_HA(ha
,flags
);
1913 if (nscp
== ha
->req_first
)
1914 ha
->req_first
= pscp
= (Scsi_Cmnd
*)nscp
->SCp
.ptr
;
1916 pscp
->SCp
.ptr
= nscp
->SCp
.ptr
;
1921 if (ha
->cmd_cnt
> 0) {
1922 gdth_release_event(hanum
);
1925 GDTH_UNLOCK_HA(ha
, flags
);
1927 if (gdth_polling
&& ha
->cmd_cnt
> 0) {
1928 if (!gdth_wait(hanum
,cmd_index
,POLL_TIMEOUT
))
1929 printk("GDT: Controller %d: Command %d timed out !\n",
1934 static void gdth_copy_internal_data(Scsi_Cmnd
*scp
,char *buffer
,ushort count
)
1938 struct scatterlist
*sl
;
1940 cpcount
= count
<=(ushort
)scp
->bufflen
? count
:(ushort
)scp
->bufflen
;
1942 sl
= (struct scatterlist
*)scp
->request_buffer
;
1943 for (i
=0,cpsum
=0; i
<scp
->use_sg
; ++i
,++sl
) {
1944 cpnow
= (ushort
)sl
->length
;
1945 TRACE(("copy_internal() now %d sum %d count %d %d\n",
1946 cpnow
,cpsum
,cpcount
,(ushort
)scp
->bufflen
));
1947 if (cpsum
+cpnow
> cpcount
)
1948 cpnow
= cpcount
- cpsum
;
1950 memcpy((char*)sl
->address
,buffer
,cpnow
);
1951 if (cpsum
== cpcount
)
1956 TRACE(("copy_internal() count %d\n",cpcount
));
1957 memcpy((char*)scp
->request_buffer
,buffer
,cpcount
);
1961 static int gdth_internal_cache_cmd(int hanum
,Scsi_Cmnd
*scp
)
1963 register gdth_ha_str
*ha
;
1966 gdth_rdcap_data rdc
;
1968 gdth_modep_data mpd
;
1970 ha
= HADATA(gdth_ctr_tab
[hanum
]);
1972 TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n",
1975 switch (scp
->cmnd
[0]) {
1976 case TEST_UNIT_READY
:
1979 TRACE2(("Test/Verify/Start hdrive %d\n",t
));
1983 TRACE2(("Inquiry hdrive %d devtype %d\n",
1984 t
,ha
->hdr
[t
].devtype
));
1985 inq
.type_qual
= (ha
->hdr
[t
].devtype
&4) ? TYPE_ROM
:TYPE_DISK
;
1986 /* you can here set all disks to removable, if you want to do
1987 a flush using the ALLOW_MEDIUM_REMOVAL command */
1988 inq
.modif_rmb
= ha
->hdr
[t
].devtype
&1 ? 0x80:0x00;
1992 strcpy(inq
.vendor
,"ICP ");
1993 sprintf(inq
.product
,"Host Drive #%02d",t
);
1994 strcpy(inq
.revision
," ");
1995 gdth_copy_internal_data(scp
,(char*)&inq
,sizeof(gdth_inq_data
));
1999 TRACE2(("Request sense hdrive %d\n",t
));
2000 sd
.errorcode
= 0x70;
2005 gdth_copy_internal_data(scp
,(char*)&sd
,sizeof(gdth_sense_data
));
2009 TRACE2(("Mode sense hdrive %d\n",t
));
2010 memset((char*)&mpd
,0,sizeof(gdth_modep_data
));
2011 mpd
.hd
.data_length
= sizeof(gdth_modep_data
);
2012 mpd
.hd
.dev_par
= (ha
->hdr
[t
].devtype
&2) ? 0x80:0;
2013 mpd
.hd
.bd_length
= sizeof(mpd
.bd
);
2014 mpd
.bd
.block_length
[0] = (SECTOR_SIZE
& 0x00ff0000) >> 16;
2015 mpd
.bd
.block_length
[1] = (SECTOR_SIZE
& 0x0000ff00) >> 8;
2016 mpd
.bd
.block_length
[2] = (SECTOR_SIZE
& 0x000000ff);
2017 gdth_copy_internal_data(scp
,(char*)&mpd
,sizeof(gdth_modep_data
));
2021 TRACE2(("Read capacity hdrive %d\n",t
));
2022 rdc
.last_block_no
= ntohl(ha
->hdr
[t
].size
-1);
2023 rdc
.block_length
= ntohl(SECTOR_SIZE
);
2024 gdth_copy_internal_data(scp
,(char*)&rdc
,sizeof(gdth_rdcap_data
));
2028 TRACE2(("Internal cache cmd 0x%x unknown\n",scp
->cmnd
[0]));
2031 scp
->result
= DID_OK
<< 16;
2033 if (!scp
->SCp
.have_data_in
)
2034 scp
->SCp
.have_data_in
++;
2041 static int gdth_fill_cache_cmd(int hanum
,Scsi_Cmnd
*scp
,ushort hdrive
)
2043 register gdth_ha_str
*ha
;
2044 register gdth_cmd_str
*cmdp
;
2045 struct scatterlist
*sl
;
2049 ha
= HADATA(gdth_ctr_tab
[hanum
]);
2051 TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n",
2052 scp
->cmnd
[0],scp
->cmd_len
,hdrive
));
2054 if (ha
->type
==GDT_EISA
&& ha
->cmd_cnt
>0)
2057 cmdp
->Service
= CACHESERVICE
;
2058 cmdp
->RequestBuffer
= scp
;
2059 /* search free command index */
2060 if (!(cmd_index
=gdth_get_cmd_index(hanum
))) {
2061 TRACE(("GDT: No free command index found\n"));
2064 /* if it's the first command, set command semaphore */
2065 if (ha
->cmd_cnt
== 0)
2066 gdth_set_sema0(hanum
);
2069 if (scp
->cmnd
[0]==ALLOW_MEDIUM_REMOVAL
) {
2070 if (scp
->cmnd
[4] & 1) /* prevent ? */
2071 cmdp
->OpCode
= GDT_MOUNT
;
2072 else if (scp
->cmnd
[3] & 1) /* removable drive ? */
2073 cmdp
->OpCode
= GDT_UNMOUNT
;
2075 cmdp
->OpCode
= GDT_FLUSH
;
2077 if (scp
->cmnd
[0]==WRITE_6
|| scp
->cmnd
[0]==WRITE_10
) {
2078 if (gdth_write_through
)
2079 cmdp
->OpCode
= GDT_WRITE_THR
;
2081 cmdp
->OpCode
= GDT_WRITE
;
2083 cmdp
->OpCode
= GDT_READ
;
2087 cmdp
->BoardNode
= LOCALBOARD
;
2088 cmdp
->u
.cache
.DeviceNo
= hdrive
;
2090 if (scp
->cmnd
[0]==ALLOW_MEDIUM_REMOVAL
) {
2091 cmdp
->u
.cache
.BlockNo
= 1;
2092 cmdp
->u
.cache
.sg_canz
= 0;
2094 if (scp
->cmd_len
!= 6) {
2095 cmdp
->u
.cache
.BlockNo
= ntohl(*(ulong32
*)&scp
->cmnd
[2]);
2096 cmdp
->u
.cache
.BlockCnt
= (ulong32
)ntohs(*(ushort
*)&scp
->cmnd
[7]);
2098 cmdp
->u
.cache
.BlockNo
=
2099 ntohl(*(ulong32
*)&scp
->cmnd
[0]) & 0x001fffffUL
;
2100 cmdp
->u
.cache
.BlockCnt
= scp
->cmnd
[4]==0 ? 0x100 : scp
->cmnd
[4];
2104 cmdp
->u
.cache
.DestAddr
= 0xffffffff;
2105 sl
= (struct scatterlist
*)scp
->request_buffer
;
2106 for (i
=0; i
<scp
->use_sg
; ++i
,++sl
) {
2107 cmdp
->u
.cache
.sg_lst
[i
].sg_ptr
= virt_to_bus(sl
->address
);
2108 cmdp
->u
.cache
.sg_lst
[i
].sg_len
= (ulong32
)sl
->length
;
2110 cmdp
->u
.cache
.sg_canz
= (ulong32
)i
;
2112 #ifdef GDTH_STATISTICS
2113 if (max_sg
< (ulong32
)i
) {
2114 max_sg
= (ulong32
)i
;
2115 TRACE3(("GDT: max_sg = %d\n",i
));
2119 cmdp
->u
.cache
.sg_lst
[i
].sg_len
= 0;
2121 if (ha
->cache_feat
& SCATTER_GATHER
) {
2122 cmdp
->u
.cache
.DestAddr
= 0xffffffff;
2123 cmdp
->u
.cache
.sg_canz
= 1;
2124 cmdp
->u
.cache
.sg_lst
[0].sg_ptr
=
2125 virt_to_bus(scp
->request_buffer
);
2126 cmdp
->u
.cache
.sg_lst
[0].sg_len
= scp
->request_bufflen
;
2127 cmdp
->u
.cache
.sg_lst
[1].sg_len
= 0;
2129 cmdp
->u
.cache
.DestAddr
= virt_to_bus(scp
->request_buffer
);
2130 cmdp
->u
.cache
.sg_canz
= 0;
2134 TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n",
2135 cmdp
->u
.cache
.DestAddr
,cmdp
->u
.cache
.sg_canz
,
2136 cmdp
->u
.cache
.sg_lst
[0].sg_ptr
,
2137 cmdp
->u
.cache
.sg_lst
[0].sg_len
));
2138 TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n",
2139 cmdp
->OpCode
,cmdp
->u
.cache
.BlockNo
,cmdp
->u
.cache
.BlockCnt
));
2141 /* evaluate command size, check space */
2142 ha
->cmd_len
= GDTOFFSOF(gdth_cmd_str
,u
.cache
.sg_lst
) +
2143 (ushort
)cmdp
->u
.cache
.sg_canz
* sizeof(gdth_sg_str
);
2144 if (ha
->cmd_len
& 3)
2145 ha
->cmd_len
+= (4 - (ha
->cmd_len
& 3));
2147 if (ha
->cmd_cnt
> 0) {
2148 if ((ha
->cmd_offs_dpmem
+ ha
->cmd_len
+ DPMEM_COMMAND_OFFSET
) >
2150 TRACE2(("gdth_fill_cache() DPMEM overflow\n"));
2151 ha
->cmd_tab
[cmd_index
-2].cmnd
= UNUSED_CMND
;
2157 gdth_copy_command(hanum
);
2161 static int gdth_fill_raw_cmd(int hanum
,Scsi_Cmnd
*scp
,unchar b
)
2163 register gdth_ha_str
*ha
;
2164 register gdth_cmd_str
*cmdp
;
2165 struct scatterlist
*sl
;
2170 ha
= HADATA(gdth_ctr_tab
[hanum
]);
2174 TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n",
2175 scp
->cmnd
[0],b
,t
,l
));
2177 if (ha
->type
==GDT_EISA
&& ha
->cmd_cnt
>0)
2180 cmdp
->Service
= SCSIRAWSERVICE
;
2181 cmdp
->RequestBuffer
= scp
;
2182 /* search free command index */
2183 if (!(cmd_index
=gdth_get_cmd_index(hanum
))) {
2184 TRACE(("GDT: No free command index found\n"));
2187 /* if it's the first command, set command semaphore */
2188 if (ha
->cmd_cnt
== 0)
2189 gdth_set_sema0(hanum
);
2192 if (scp
->SCp
.Status
!= -1) {
2193 cmdp
->OpCode
= scp
->SCp
.Status
; /* special raw cmd. */
2194 cmdp
->BoardNode
= LOCALBOARD
;
2195 cmdp
->u
.raw
.direction
= (scp
->SCp
.phase
>> 8);
2196 TRACE2(("special raw cmd 0x%x param 0x%x\n",
2197 cmdp
->OpCode
, cmdp
->u
.raw
.direction
));
2199 /* evaluate command size */
2200 ha
->cmd_len
= GDTOFFSOF(gdth_cmd_str
,u
.raw
.sg_lst
);
2202 cmdp
->OpCode
= GDT_WRITE
; /* always */
2203 cmdp
->BoardNode
= LOCALBOARD
;
2204 cmdp
->u
.raw
.reserved
= 0;
2205 cmdp
->u
.raw
.mdisc_time
= 0;
2206 cmdp
->u
.raw
.mcon_time
= 0;
2207 cmdp
->u
.raw
.clen
= scp
->cmd_len
;
2208 cmdp
->u
.raw
.target
= t
;
2209 cmdp
->u
.raw
.lun
= l
;
2210 cmdp
->u
.raw
.bus
= b
;
2211 cmdp
->u
.raw
.priority
= 0;
2212 cmdp
->u
.raw
.link_p
= NULL
;
2213 cmdp
->u
.raw
.sdlen
= scp
->request_bufflen
;
2214 cmdp
->u
.raw
.sense_len
= 16;
2215 cmdp
->u
.raw
.sense_data
= virt_to_bus(scp
->sense_buffer
);
2216 cmdp
->u
.raw
.direction
=
2217 gdth_direction_tab
[scp
->cmnd
[0]]==DOU
? DATA_OUT
: DATA_IN
;
2218 memcpy(cmdp
->u
.raw
.cmd
,scp
->cmnd
,12);
2221 cmdp
->u
.raw
.sdata
= 0xffffffff;
2222 sl
= (struct scatterlist
*)scp
->request_buffer
;
2223 for (i
=0; i
<scp
->use_sg
; ++i
,++sl
) {
2224 cmdp
->u
.raw
.sg_lst
[i
].sg_ptr
= virt_to_bus(sl
->address
);
2225 cmdp
->u
.raw
.sg_lst
[i
].sg_len
= (ulong32
)sl
->length
;
2227 cmdp
->u
.raw
.sg_ranz
= (ulong32
)i
;
2229 #ifdef GDTH_STATISTICS
2230 if (max_sg
< (ulong32
)i
) {
2231 max_sg
= (ulong32
)i
;
2232 TRACE3(("GDT: max_sg = %d\n",i
));
2236 cmdp
->u
.raw
.sg_lst
[i
].sg_len
= 0;
2238 if (ha
->raw_feat
& SCATTER_GATHER
) {
2239 cmdp
->u
.raw
.sdata
= 0xffffffff;
2240 cmdp
->u
.raw
.sg_ranz
= 1;
2241 cmdp
->u
.raw
.sg_lst
[0].sg_ptr
= virt_to_bus(scp
->request_buffer
);
2242 cmdp
->u
.raw
.sg_lst
[0].sg_len
= scp
->request_bufflen
;
2243 cmdp
->u
.raw
.sg_lst
[1].sg_len
= 0;
2245 cmdp
->u
.raw
.sdata
= virt_to_bus(scp
->request_buffer
);
2246 cmdp
->u
.raw
.sg_ranz
= 0;
2249 TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n",
2250 cmdp
->u
.raw
.sdata
,cmdp
->u
.raw
.sg_ranz
,
2251 cmdp
->u
.raw
.sg_lst
[0].sg_ptr
,
2252 cmdp
->u
.raw
.sg_lst
[0].sg_len
));
2254 /* evaluate command size */
2255 ha
->cmd_len
= GDTOFFSOF(gdth_cmd_str
,u
.raw
.sg_lst
) +
2256 (ushort
)cmdp
->u
.raw
.sg_ranz
* sizeof(gdth_sg_str
);
2259 if (ha
->cmd_len
& 3)
2260 ha
->cmd_len
+= (4 - (ha
->cmd_len
& 3));
2262 if (ha
->cmd_cnt
> 0) {
2263 if ((ha
->cmd_offs_dpmem
+ ha
->cmd_len
+ DPMEM_COMMAND_OFFSET
) >
2265 TRACE2(("gdth_fill_raw() DPMEM overflow\n"));
2266 ha
->cmd_tab
[cmd_index
-2].cmnd
= UNUSED_CMND
;
2272 gdth_copy_command(hanum
);
2276 static int gdth_special_cmd(int hanum
,Scsi_Cmnd
*scp
)
2278 register gdth_ha_str
*ha
;
2279 register gdth_cmd_str
*cmdp
;
2282 ha
= HADATA(gdth_ctr_tab
[hanum
]);
2284 TRACE2(("gdth_special_cmd(): "));
2286 if (ha
->type
==GDT_EISA
&& ha
->cmd_cnt
>0)
2289 memcpy( cmdp
, scp
->request_buffer
, sizeof(gdth_cmd_str
));
2290 cmdp
->RequestBuffer
= scp
;
2292 /* search free command index */
2293 if (!(cmd_index
=gdth_get_cmd_index(hanum
))) {
2294 TRACE(("GDT: No free command index found\n"));
2298 /* if it's the first command, set command semaphore */
2299 if (ha
->cmd_cnt
== 0)
2300 gdth_set_sema0(hanum
);
2302 /* evaluate command size, check space */
2303 if (cmdp
->OpCode
== GDT_IOCTL
) {
2304 TRACE2(("IOCTL\n"));
2306 GDTOFFSOF(gdth_cmd_str
,u
.ioctl
.p_param
) + sizeof(ulong32
);
2307 } else if (cmdp
->Service
== CACHESERVICE
) {
2308 TRACE2(("cache command %d\n",cmdp
->OpCode
));
2310 GDTOFFSOF(gdth_cmd_str
,u
.cache
.sg_lst
) + sizeof(gdth_sg_str
);
2311 } else if (cmdp
->Service
== SCSIRAWSERVICE
) {
2312 TRACE2(("raw command %d/%d\n",cmdp
->OpCode
,cmdp
->u
.raw
.cmd
[0]));
2314 GDTOFFSOF(gdth_cmd_str
,u
.raw
.sg_lst
) + sizeof(gdth_sg_str
);
2317 if (ha
->cmd_len
& 3)
2318 ha
->cmd_len
+= (4 - (ha
->cmd_len
& 3));
2320 if (ha
->cmd_cnt
> 0) {
2321 if ((ha
->cmd_offs_dpmem
+ ha
->cmd_len
+ DPMEM_COMMAND_OFFSET
) >
2323 TRACE2(("gdth_special_cmd() DPMEM overflow\n"));
2324 ha
->cmd_tab
[cmd_index
-2].cmnd
= UNUSED_CMND
;
2330 gdth_copy_command(hanum
);
2335 /* Controller event handling functions */
2336 static gdth_evt_str
*gdth_store_event(gdth_ha_str
*ha
, ushort source
,
2337 ushort idx
, gdth_evt_data
*evt
)
2342 /* no GDTH_LOCK_HA() ! */
2343 TRACE2(("gdth_store_event() source %d idx %d\n", source
, idx
));
2344 if (source
== 0) /* no source -> no event */
2347 if (ebuffer
[elastidx
].event_source
== source
&&
2348 ebuffer
[elastidx
].event_idx
== idx
&&
2349 !memcmp((char *)&ebuffer
[elastidx
].event_data
.eu
,
2350 (char *)&evt
->eu
, evt
->size
)) {
2351 e
= &ebuffer
[elastidx
];
2352 do_gettimeofday(&tv
);
2353 e
->last_stamp
= tv
.tv_sec
;
2356 if (ebuffer
[elastidx
].event_source
!= 0) { /* entry not free ? */
2358 if (elastidx
== MAX_EVENTS
)
2360 if (elastidx
== eoldidx
) { /* reached mark ? */
2362 if (eoldidx
== MAX_EVENTS
)
2366 e
= &ebuffer
[elastidx
];
2367 e
->event_source
= source
;
2369 do_gettimeofday(&tv
);
2370 e
->first_stamp
= e
->last_stamp
= tv
.tv_sec
;
2372 e
->event_data
= *evt
;
2377 static int gdth_read_event(gdth_ha_str
*ha
, int handle
, gdth_evt_str
*estr
)
2383 TRACE2(("gdth_read_event() handle %d\n", handle
));
2384 GDTH_LOCK_HA(ha
, flags
);
2389 estr
->event_source
= 0;
2391 if (eindex
>= MAX_EVENTS
) {
2392 GDTH_UNLOCK_HA(ha
, flags
);
2395 e
= &ebuffer
[eindex
];
2396 if (e
->event_source
!= 0) {
2397 if (eindex
!= elastidx
) {
2398 if (++eindex
== MAX_EVENTS
)
2403 memcpy(estr
, e
, sizeof(gdth_evt_str
));
2405 GDTH_UNLOCK_HA(ha
, flags
);
2409 static void gdth_readapp_event(gdth_ha_str
*ha
,
2410 unchar application
, gdth_evt_str
*estr
)
2415 unchar found
= FALSE
;
2417 TRACE2(("gdth_readapp_event() app. %d\n", application
));
2418 GDTH_LOCK_HA(ha
, flags
);
2421 e
= &ebuffer
[eindex
];
2422 if (e
->event_source
== 0)
2424 if ((e
->application
& application
) == 0) {
2425 e
->application
|= application
;
2429 if (eindex
== elastidx
)
2431 if (++eindex
== MAX_EVENTS
)
2435 memcpy(estr
, e
, sizeof(gdth_evt_str
));
2437 estr
->event_source
= 0;
2438 GDTH_UNLOCK_HA(ha
, flags
);
2441 static void gdth_clear_events()
2443 TRACE(("gdth_clear_events()"));
2445 eoldidx
= elastidx
= 0;
2446 ebuffer
[0].event_source
= 0;
2450 /* SCSI interface functions */
2452 static void gdth_interrupt(int irq
,void *dev_id
,struct pt_regs
*regs
)
2454 register gdth_ha_str
*ha
;
2455 gdt6m_dpram_str
*dp6m_ptr
;
2456 gdt6_dpram_str
*dp6_ptr
;
2457 gdt2_dpram_str
*dp2_ptr
;
2461 ushort CmdStatus
, Service
= 0;
2462 ulong32 InfoBytes
, InfoBytes2
= 0;
2466 TRACE(("gdth_interrupt() IRQ %d\n",irq
));
2468 /* if polling and not from gdth_wait() -> return */
2470 if (!gdth_from_wait
) {
2476 GDTH_LOCK_HA((gdth_ha_str
*)dev_id
,flags
);
2479 /* search controller */
2480 if ((hanum
= gdth_get_status(&IStatus
,irq
)) == -1) {
2482 TRACE2(("gdth_interrupt(): Spurious interrupt received\n"));
2485 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
);
2489 #ifdef GDTH_STATISTICS
2493 ha
= HADATA(gdth_ctr_tab
[hanum
]);
2494 if (ha
->type
== GDT_EISA
) {
2495 if (IStatus
& 0x80) { /* error flag */
2497 CmdStatus
= inw(ha
->bmic
+ MAILBOXREG
+8);
2498 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
));
2499 if (IStatus
== ASYNCINDEX
) { /* async. event ? */
2500 Service
= inw(ha
->bmic
+ MAILBOXREG
+10);
2501 InfoBytes2
= inl(ha
->bmic
+ MAILBOXREG
+4);
2503 } else /* no error */
2505 InfoBytes
= inl(ha
->bmic
+ MAILBOXREG
+12);
2506 if (gdth_polling
) /* init. -> more info */
2507 InfoBytes2
= inl(ha
->bmic
+ MAILBOXREG
+4);
2508 outb(0xff, ha
->bmic
+ EDOORREG
); /* acknowledge interrupt */
2509 outb(0x00, ha
->bmic
+ SEMA1REG
); /* reset status semaphore */
2510 } else if (ha
->type
== GDT_ISA
) {
2511 dp2_ptr
= (gdt2_dpram_str
*)ha
->brd
;
2512 if (IStatus
& 0x80) { /* error flag */
2514 CmdStatus
= gdth_readw(&dp2_ptr
->u
.ic
.Status
);
2515 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
));
2516 if (IStatus
== ASYNCINDEX
) { /* async. event ? */
2517 Service
= gdth_readw(&dp2_ptr
->u
.ic
.Service
);
2518 InfoBytes2
= gdth_readl(&dp2_ptr
->u
.ic
.Info
[1]);
2520 } else /* no error */
2522 InfoBytes
= gdth_readl(&dp2_ptr
->u
.ic
.Info
[0]);
2523 if (gdth_polling
) /* init. -> more info */
2524 InfoBytes2
= gdth_readl(&dp2_ptr
->u
.ic
.Info
[1]);
2525 gdth_writeb(0xff, &dp2_ptr
->io
.irqdel
); /* acknowledge interrupt */
2526 gdth_writeb(0, &dp2_ptr
->u
.ic
.Cmd_Index
); /* reset command index */
2527 gdth_writeb(0, &dp2_ptr
->io
.Sema1
); /* reset status semaphore */
2528 } else if (ha
->type
== GDT_PCI
) {
2529 dp6_ptr
= (gdt6_dpram_str
*)ha
->brd
;
2530 if (IStatus
& 0x80) { /* error flag */
2532 CmdStatus
= gdth_readw(&dp6_ptr
->u
.ic
.Status
);
2533 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
));
2534 if (IStatus
== ASYNCINDEX
) { /* async. event ? */
2535 Service
= gdth_readw(&dp6_ptr
->u
.ic
.Service
);
2536 InfoBytes2
= gdth_readl(&dp6_ptr
->u
.ic
.Info
[1]);
2538 } else /* no error */
2540 InfoBytes
= gdth_readl(&dp6_ptr
->u
.ic
.Info
[0]);
2541 if (gdth_polling
) /* init. -> more info */
2542 InfoBytes2
= gdth_readl(&dp6_ptr
->u
.ic
.Info
[1]);
2543 gdth_writeb(0xff, &dp6_ptr
->io
.irqdel
); /* acknowledge interrupt */
2544 gdth_writeb(0, &dp6_ptr
->u
.ic
.Cmd_Index
); /* reset command index */
2545 gdth_writeb(0, &dp6_ptr
->io
.Sema1
); /* reset status semaphore */
2546 } else if (ha
->type
== GDT_PCINEW
) {
2547 if (IStatus
& 0x80) { /* error flag */
2549 CmdStatus
= inw(PTR2USHORT(&ha
->plx
->status
));
2550 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
));
2551 if (IStatus
== ASYNCINDEX
) { /* async. event ? */
2552 Service
= inw(PTR2USHORT(&ha
->plx
->service
));
2553 InfoBytes2
= inl(PTR2USHORT(&ha
->plx
->info
[1]));
2558 InfoBytes
= inl(PTR2USHORT(&ha
->plx
->info
[0]));
2559 if (gdth_polling
) /* init. -> more info */
2560 InfoBytes2
= inl(PTR2USHORT(&ha
->plx
->info
[1]));
2561 outb(0xff, PTR2USHORT(&ha
->plx
->edoor_reg
));
2562 outb(0x00, PTR2USHORT(&ha
->plx
->sema1_reg
));
2563 } else if (ha
->type
== GDT_PCIMPR
) {
2564 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
;
2565 if (IStatus
& 0x80) { /* error flag */
2567 CmdStatus
= gdth_readw(&dp6m_ptr
->i960r
.status
);
2568 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
));
2569 if (IStatus
== ASYNCINDEX
) { /* async. event ? */
2570 Service
= gdth_readw(&dp6m_ptr
->i960r
.service
);
2571 InfoBytes2
= gdth_readl(&dp6m_ptr
->i960r
.info
[1]);
2573 } else /* no error */
2575 InfoBytes
= gdth_readl(&dp6m_ptr
->i960r
.info
[0]);
2576 if (gdth_polling
) /* init. -> more info */
2577 InfoBytes2
= gdth_readl(&dp6m_ptr
->i960r
.info
[1]);
2578 gdth_writeb(0xff, &dp6m_ptr
->i960r
.edoor_reg
);
2579 gdth_writeb(0, &dp6m_ptr
->i960r
.sema1_reg
);
2581 TRACE2(("gdth_interrupt() unknown controller type\n"));
2583 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
);
2587 TRACE(("gdth_interrupt() index %d stat %d info %d\n",
2588 IStatus
,CmdStatus
,InfoBytes
));
2589 ha
->status
= CmdStatus
;
2590 ha
->info
= InfoBytes
;
2591 ha
->info2
= InfoBytes2
;
2593 if (gdth_from_wait
) {
2595 wait_index
= (int)IStatus
;
2598 if (IStatus
== ASYNCINDEX
) {
2599 TRACE2(("gdth_interrupt() async. event\n"));
2600 gdth_async_event(hanum
,Service
);
2602 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
);
2607 if (IStatus
== SPEZINDEX
) {
2608 TRACE2(("Service unknown or not initialized !\n"));
2609 dvr
.size
= sizeof(dvr
.eu
.driver
);
2610 dvr
.eu
.driver
.ionode
= hanum
;
2611 gdth_store_event(ha
, ES_DRIVER
, 4, &dvr
);
2613 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
);
2616 scp
= ha
->cmd_tab
[IStatus
-2].cmnd
;
2617 Service
= ha
->cmd_tab
[IStatus
-2].service
;
2618 ha
->cmd_tab
[IStatus
-2].cmnd
= UNUSED_CMND
;
2619 if (scp
== UNUSED_CMND
) {
2620 TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus
));
2621 dvr
.size
= sizeof(dvr
.eu
.driver
);
2622 dvr
.eu
.driver
.ionode
= hanum
;
2623 dvr
.eu
.driver
.index
= IStatus
;
2624 gdth_store_event(ha
, ES_DRIVER
, 1, &dvr
);
2626 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
);
2629 if (scp
== INTERNAL_CMND
) {
2630 TRACE(("gdth_interrupt() answer to internal command\n"));
2632 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
);
2636 TRACE(("gdth_interrupt() sync. status\n"));
2637 rval
= gdth_sync_event(hanum
,Service
,IStatus
,scp
);
2639 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
);
2641 gdth_putq(hanum
,scp
,scp
->SCp
.this_residual
);
2642 } else if (rval
== 1) {
2643 GDTH_LOCK_SCSI_DONE(flags
);
2644 scp
->scsi_done(scp
);
2645 GDTH_UNLOCK_SCSI_DONE(flags
);
2650 static int gdth_sync_event(int hanum
,int service
,unchar index
,Scsi_Cmnd
*scp
)
2652 register gdth_ha_str
*ha
;
2659 ha
= HADATA(gdth_ctr_tab
[hanum
]);
2661 TRACE(("gdth_sync_event() serv %d status %d\n",
2662 service
,ha
->status
));
2664 if (service
== SCREENSERVICE
) {
2665 msg
= (gdth_msg_str
*)ha
->pscratch
;
2666 ha
->scratch_busy
= FALSE
;
2667 TRACE(("len: %d, answer: %d, ext: %d, alen: %d\n",
2668 msg
->msg_len
,msg
->msg_answer
,msg
->msg_ext
,msg
->msg_alen
));
2670 if (!(msg
->msg_answer
&& msg
->msg_ext
)) {
2671 msg
->msg_text
[msg
->msg_len
] = '\0';
2672 printk("%s",msg
->msg_text
);
2675 if (msg
->msg_ext
&& !msg
->msg_answer
) {
2676 while (gdth_test_busy(hanum
))
2678 cmdp
->Service
= SCREENSERVICE
;
2679 cmdp
->RequestBuffer
= SCREEN_CMND
;
2680 gdth_get_cmd_index(hanum
);
2681 gdth_set_sema0(hanum
);
2682 cmdp
->OpCode
= GDT_READ
;
2683 cmdp
->BoardNode
= LOCALBOARD
;
2684 cmdp
->u
.screen
.reserved
= 0;
2685 cmdp
->u
.screen
.msg_handle
= msg
->msg_handle
;
2686 cmdp
->u
.screen
.msg_addr
= virt_to_bus(msg
);
2687 ha
->scratch_busy
= TRUE
;
2688 ha
->cmd_offs_dpmem
= 0;
2689 ha
->cmd_len
= GDTOFFSOF(gdth_cmd_str
,u
.screen
.msg_addr
)
2692 gdth_copy_command(hanum
);
2693 gdth_release_event(hanum
);
2697 if (msg
->msg_answer
&& msg
->msg_alen
) {
2698 for (i
=0; i
<msg
->msg_alen
&& i
<MSGLEN
; ++i
) {
2703 msg
->msg_text
[i
] = c
;
2706 if (c
!='\r' && msg
->msg_alen
!=0) {
2707 msg
->msg_answer
= 1;
2711 msg
->msg_answer
= 0;
2714 while (gdth_test_busy(hanum
))
2716 cmdp
->Service
= SCREENSERVICE
;
2717 cmdp
->RequestBuffer
= SCREEN_CMND
;
2718 gdth_get_cmd_index(hanum
);
2719 gdth_set_sema0(hanum
);
2720 cmdp
->OpCode
= GDT_WRITE
;
2721 cmdp
->BoardNode
= LOCALBOARD
;
2722 cmdp
->u
.screen
.reserved
= 0;
2723 cmdp
->u
.screen
.msg_handle
= msg
->msg_handle
;
2724 cmdp
->u
.screen
.msg_addr
= virt_to_bus(msg
);
2725 ha
->scratch_busy
= TRUE
;
2726 ha
->cmd_offs_dpmem
= 0;
2727 ha
->cmd_len
= GDTOFFSOF(gdth_cmd_str
,u
.screen
.msg_addr
)
2730 gdth_copy_command(hanum
);
2731 gdth_release_event(hanum
);
2737 if (scp
->SCp
.Status
== -1 && scp
->channel
!= ha
->virt_bus
) {
2738 ha
->raw
[BUS_L2P(ha
,scp
->channel
)].io_cnt
[scp
->target
]--;
2740 /* cache or raw service */
2741 if (ha
->status
== S_OK
) {
2742 scp
->SCp
.Message
= S_OK
;
2743 if (scp
->SCp
.Status
!= -1) {
2744 TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n",
2746 scp
->SCp
.Status
= -1;
2747 scp
->SCp
.this_residual
= HIGH_PRI
;
2750 scp
->result
= DID_OK
<< 16;
2751 } else if (ha
->status
== S_BSY
) {
2752 TRACE2(("Controller busy -> retry !\n"));
2753 scp
->SCp
.Message
= S_BSY
;
2756 scp
->SCp
.Message
= (int)((ha
->info
<<16)|ha
->status
);
2757 if (scp
->SCp
.Status
!= -1) {
2758 TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n",
2759 scp
->SCp
.Status
, ha
->status
));
2760 scp
->SCp
.Status
= -1;
2761 scp
->SCp
.this_residual
= HIGH_PRI
;
2764 if (service
== CACHESERVICE
) {
2765 memset((char*)scp
->sense_buffer
,0,16);
2766 scp
->sense_buffer
[0] = 0x70;
2767 scp
->sense_buffer
[2] = NOT_READY
;
2768 scp
->result
= (DID_OK
<< 16) | (CHECK_CONDITION
<< 1);
2770 if (scp
->done
!= gdth_scsi_done
)
2772 dvr
.size
= sizeof(dvr
.eu
.sync
);
2773 dvr
.eu
.sync
.ionode
= hanum
;
2774 dvr
.eu
.sync
.service
= service
;
2775 dvr
.eu
.sync
.status
= ha
->status
;
2776 dvr
.eu
.sync
.info
= ha
->info
;
2777 dvr
.eu
.sync
.hostdrive
= scp
->target
;
2778 if (ha
->status
>= 0x8000)
2779 gdth_store_event(ha
, ES_SYNC
, 0, &dvr
);
2781 gdth_store_event(ha
, ES_SYNC
, service
, &dvr
);
2784 if (ha
->status
!=S_RAW_SCSI
|| ha
->info
>=0x100) {
2785 scp
->result
= DID_BAD_TARGET
<< 16;
2787 scp
->result
= (DID_OK
<< 16) | ha
->info
;
2791 if (!scp
->SCp
.have_data_in
)
2792 scp
->SCp
.have_data_in
++;
2800 static char *async_cache_tab
[] = {
2801 /* 0*/ "\011\000\002\002\002\004\002\006\004"
2802 "GDT HA %u, service %u, async. status %u/%lu unknown",
2803 /* 1*/ "\011\000\002\002\002\004\002\006\004"
2804 "GDT HA %u, service %u, async. status %u/%lu unknown",
2805 /* 2*/ "\005\000\002\006\004"
2806 "GDT HA %u, Host Drive %lu not ready",
2807 /* 3*/ "\005\000\002\006\004"
2808 "GDT HA %u, Host Drive %lu: REASSIGN not successful and/or data error on reassigned blocks. Drive may crash in the future and should be replaced",
2809 /* 4*/ "\005\000\002\006\004"
2810 "GDT HA %u, mirror update on Host Drive %lu failed",
2811 /* 5*/ "\005\000\002\006\004"
2812 "GDT HA %u, Mirror Drive %lu failed",
2813 /* 6*/ "\005\000\002\006\004"
2814 "GDT HA %u, Mirror Drive %lu: REASSIGN not successful and/or data error on reassigned blocks. Drive may crash in the future and should be replaced",
2815 /* 7*/ "\005\000\002\006\004"
2816 "GDT HA %u, Host Drive %lu write protected",
2817 /* 8*/ "\005\000\002\006\004"
2818 "GDT HA %u, media changed in Host Drive %lu",
2819 /* 9*/ "\005\000\002\006\004"
2820 "GDT HA %u, Host Drive %lu is offline",
2821 /*10*/ "\005\000\002\006\004"
2822 "GDT HA %u, media change of Mirror Drive %lu",
2823 /*11*/ "\005\000\002\006\004"
2824 "GDT HA %u, Mirror Drive %lu is write protected",
2825 /*12*/ "\005\000\002\006\004"
2826 "GDT HA %u, general error on Host Drive %lu. Please check the devices of this drive!",
2827 /*13*/ "\007\000\002\006\002\010\002"
2828 "GDT HA %u, Array Drive %u: Cache Drive %u failed",
2829 /*14*/ "\005\000\002\006\002"
2830 "GDT HA %u, Array Drive %u: FAIL state entered",
2831 /*15*/ "\005\000\002\006\002"
2832 "GDT HA %u, Array Drive %u: error",
2833 /*16*/ "\007\000\002\006\002\010\002"
2834 "GDT HA %u, Array Drive %u: failed drive replaced by Cache Drive %u",
2835 /*17*/ "\005\000\002\006\002"
2836 "GDT HA %u, Array Drive %u: parity build failed",
2837 /*18*/ "\005\000\002\006\002"
2838 "GDT HA %u, Array Drive %u: drive rebuild failed",
2839 /*19*/ "\005\000\002\010\002"
2840 "GDT HA %u, Test of Hot Fix %u failed",
2841 /*20*/ "\005\000\002\006\002"
2842 "GDT HA %u, Array Drive %u: drive build finished successfully",
2843 /*21*/ "\005\000\002\006\002"
2844 "GDT HA %u, Array Drive %u: drive rebuild finished successfully",
2845 /*22*/ "\007\000\002\006\002\010\002"
2846 "GDT HA %u, Array Drive %u: Hot Fix %u activated",
2847 /*23*/ "\005\000\002\006\002"
2848 "GDT HA %u, Host Drive %u: processing of i/o aborted due to serious drive error",
2849 /*24*/ "\005\000\002\010\002"
2850 "GDT HA %u, mirror update on Cache Drive %u completed",
2851 /*25*/ "\005\000\002\010\002"
2852 "GDT HA %u, mirror update on Cache Drive %lu failed",
2853 /*26*/ "\005\000\002\006\002"
2854 "GDT HA %u, Array Drive %u: drive rebuild started",
2855 /*27*/ "\005\000\002\012\001"
2856 "GDT HA %u, Fault bus %u: SHELF OK detected",
2857 /*28*/ "\005\000\002\012\001"
2858 "GDT HA %u, Fault bus %u: SHELF not OK detected",
2859 /*29*/ "\007\000\002\012\001\013\001"
2860 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug started",
2861 /*30*/ "\007\000\002\012\001\013\001"
2862 "GDT HA %u, Fault bus %u, ID %u: new disk detected",
2863 /*31*/ "\007\000\002\012\001\013\001"
2864 "GDT HA %u, Fault bus %u, ID %u: old disk detected",
2865 /*32*/ "\007\000\002\012\001\013\001"
2866 "GDT HA %u, Fault bus %u, ID %u: plugging an active disk is illegal",
2867 /*33*/ "\007\000\002\012\001\013\001"
2868 "GDT HA %u, Fault bus %u, ID %u: illegal device detected",
2869 /*34*/ "\011\000\002\012\001\013\001\006\004"
2870 "GDT HA %u, Fault bus %u, ID %u: insufficient disk capacity (%lu MB required)",
2871 /*35*/ "\007\000\002\012\001\013\001"
2872 "GDT HA %u, Fault bus %u, ID %u: disk write protected",
2873 /*36*/ "\007\000\002\012\001\013\001"
2874 "GDT HA %u, Fault bus %u, ID %u: disk not available",
2875 /*37*/ "\007\000\002\012\001\006\004"
2876 "GDT HA %u, Fault bus %u: swap detected (%lu)",
2877 /*38*/ "\007\000\002\012\001\013\001"
2878 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug finished successfully",
2879 /*39*/ "\007\000\002\012\001\013\001"
2880 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted due to user Hot Plug",
2881 /*40*/ "\007\000\002\012\001\013\001"
2882 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted",
2883 /*41*/ "\007\000\002\012\001\013\001"
2884 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug for Hot Fix started",
2885 /*42*/ "\005\000\002\006\002"
2886 "GDT HA %u, Array Drive %u: drive build started",
2887 /*43*/ "\003\000\002"
2888 "GDT HA %u, DRAM parity error detected",
2889 /*44*/ "\005\000\002\006\002"
2890 "GDT HA %u, Mirror Drive %u: update started",
2891 /*45*/ "\007\000\002\006\002\010\002"
2892 "GDT HA %u, Mirror Drive %u: Hot Fix %u activated",
2893 /*46*/ "\005\000\002\006\002"
2894 "GDT HA %u, Array Drive %u: no matching Pool Hot Fix Drive available",
2895 /*47*/ "\005\000\002\006\002"
2896 "GDT HA %u, Array Drive %u: Pool Hot Fix Drive available",
2897 /*48*/ "\005\000\002\006\002"
2898 "GDT HA %u, Mirror Drive %u: no matching Pool Hot Fix Drive available",
2899 /*49*/ "\005\000\002\006\002"
2900 "GDT HA %u, Mirror Drive %u: Pool Hot Fix Drive available",
2901 /*50*/ "\007\000\002\012\001\013\001"
2902 "GDT HA %u, SCSI bus %u, ID %u: IGNORE_WIDE_RESIDUE message received",
2903 /*51*/ "\005\000\002\006\002"
2904 "GDT HA %u, Array Drive %u: expand started",
2905 /*52*/ "\005\000\002\006\002"
2906 "GDT HA %u, Array Drive %u: expand finished successfully",
2907 /*53*/ "\005\000\002\006\002"
2908 "GDT HA %u, Array Drive %u: expand failed",
2909 /*54*/ "\003\000\002"
2910 "GDT HA %u, CPU temperature critical",
2911 /*55*/ "\003\000\002"
2912 "GDT HA %u, CPU temperature OK",
2913 /*56*/ "\005\000\002\006\004"
2914 "GDT HA %u, Host drive %lu created",
2915 /*57*/ "\005\000\002\006\002"
2916 "GDT HA %u, Array Drive %u: expand restarted",
2917 /*58*/ "\005\000\002\006\002"
2918 "GDT HA %u, Array Drive %u: expand stopped",
2919 /*59*/ "\005\000\002\010\002"
2920 "GDT HA %u, Mirror Drive %u: drive build quited",
2921 /*60*/ "\005\000\002\006\002"
2922 "GDT HA %u, Array Drive %u: parity build quited",
2923 /*61*/ "\005\000\002\006\002"
2924 "GDT HA %u, Array Drive %u: drive rebuild quited",
2925 /*62*/ "\005\000\002\006\002"
2926 "GDT HA %u, Array Drive %u: parity verify started",
2927 /*63*/ "\005\000\002\006\002"
2928 "GDT HA %u, Array Drive %u: parity verify done",
2929 /*64*/ "\005\000\002\006\002"
2930 "GDT HA %u, Array Drive %u: parity verify failed",
2931 /*65*/ "\005\000\002\006\002"
2932 "GDT HA %u, Array Drive %u: parity error detected",
2933 /*66*/ "\005\000\002\006\002"
2934 "GDT HA %u, Array Drive %u: parity verify quited",
2935 /*67*/ "\005\000\002\006\002"
2936 "GDT HA %u, Host Drive %u reserved",
2937 /*68*/ "\005\000\002\006\002"
2938 "GDT HA %u, Host Drive %u mounted and released",
2939 /*69*/ "\005\000\002\006\002"
2940 "GDT HA %u, Host Drive %u released",
2941 /*70*/ "\003\000\002"
2942 "GDT HA %u, DRAM error detected and corrected with ECC",
2943 /*71*/ "\003\000\002"
2944 "GDT HA %u, Uncorrectable DRAM error detected with ECC",
2945 /*72*/ "\011\000\002\012\001\013\001\014\001"
2946 "GDT HA %u, SCSI bus %u, ID %u, LUN %u: reassigning block",
2950 static int gdth_async_event(int hanum
,int service
)
2958 ha
= HADATA(gdth_ctr_tab
[hanum
]);
2960 msg
= (gdth_msg_str
*)ha
->pscratch
;
2961 TRACE2(("gdth_async_event() ha %d serv %d\n",
2964 if (service
== SCREENSERVICE
) {
2965 if (ha
->status
== MSG_REQUEST
) {
2966 while (gdth_test_busy(hanum
))
2968 cmdp
->Service
= SCREENSERVICE
;
2969 cmdp
->RequestBuffer
= SCREEN_CMND
;
2970 cmd_index
= gdth_get_cmd_index(hanum
);
2971 gdth_set_sema0(hanum
);
2972 cmdp
->OpCode
= GDT_READ
;
2973 cmdp
->BoardNode
= LOCALBOARD
;
2974 cmdp
->u
.screen
.reserved
= 0;
2975 cmdp
->u
.screen
.msg_handle
= MSG_INV_HANDLE
;
2976 cmdp
->u
.screen
.msg_addr
= virt_to_bus(msg
);
2977 ha
->scratch_busy
= TRUE
;
2978 ha
->cmd_offs_dpmem
= 0;
2979 ha
->cmd_len
= GDTOFFSOF(gdth_cmd_str
,u
.screen
.msg_addr
)
2982 gdth_copy_command(hanum
);
2983 if (ha
->type
== GDT_EISA
)
2984 printk("[EISA slot %d] ",(ushort
)ha
->brd_phys
);
2985 else if (ha
->type
== GDT_ISA
)
2986 printk("[DPMEM 0x%4X] ",(ushort
)ha
->brd_phys
);
2988 printk("[PCI %d/%d] ",(ushort
)(ha
->brd_phys
>>8),
2989 (ushort
)((ha
->brd_phys
>>3)&0x1f));
2990 gdth_release_event(hanum
);
2994 dvr
.size
= sizeof(dvr
.eu
.async
);
2995 dvr
.eu
.async
.ionode
= hanum
;
2996 dvr
.eu
.async
.service
= service
;
2997 dvr
.eu
.async
.status
= ha
->status
;
2998 dvr
.eu
.async
.info
= ha
->info
;
2999 *(ulong32
*)dvr
.eu
.async
.scsi_coord
= ha
->info2
;
3000 gdth_store_event(ha
, ES_ASYNC
, service
, &dvr
);
3001 gdth_log_event( &dvr
, NULL
);
3006 static void gdth_log_event(gdth_evt_data
*dvr
, char *buffer
)
3008 gdth_stackframe stack
;
3012 TRACE2(("gdth_log_event()\n"));
3013 if (dvr
->eu
.async
.service
== CACHESERVICE
&&
3014 INDEX_OK(dvr
->eu
.async
.status
, async_cache_tab
)) {
3015 TRACE2(("GDT: Async. event cache service, event no.: %d\n",
3016 dvr
->eu
.async
.status
));
3018 f
= async_cache_tab
[dvr
->eu
.async
.status
];
3020 /* i: parameter to push, j: stack element to fill */
3021 for (j
=0,i
=1; i
< f
[0]; i
+=2) {
3024 stack
.b
[j
++] = *(ulong32
*)&dvr
->eu
.stream
[(int)f
[i
]];
3027 stack
.b
[j
++] = *(ushort
*)&dvr
->eu
.stream
[(int)f
[i
]];
3030 stack
.b
[j
++] = *(unchar
*)&dvr
->eu
.stream
[(int)f
[i
]];
3037 if (buffer
== NULL
) {
3038 printk(&f
[(int)f
[0]],stack
);
3041 sprintf(buffer
,&f
[(int)f
[0]],stack
);
3045 if (buffer
== NULL
) {
3046 printk("GDT HA %u, Unknown async. event service %d event no. %d\n",
3047 dvr
->eu
.async
.ionode
,dvr
->eu
.async
.service
,dvr
->eu
.async
.status
);
3049 sprintf(buffer
,"GDT HA %u, Unknown async. event service %d event no. %d",
3050 dvr
->eu
.async
.ionode
,dvr
->eu
.async
.service
,dvr
->eu
.async
.status
);
3055 #ifdef GDTH_STATISTICS
3056 void gdth_timeout(ulong data
)
3064 ha
= HADATA(gdth_ctr_tab
[hanum
]);
3065 GDTH_LOCK_HA(ha
, flags
);
3067 for (act_stats
=0,i
=0; i
<GDTH_MAXCMDS
; ++i
)
3068 if (ha
->cmd_tab
[i
].cmnd
!= UNUSED_CMND
)
3071 for (act_rq
=0,nscp
=ha
->req_first
; nscp
; nscp
=(Scsi_Cmnd
*)nscp
->SCp
.ptr
)
3074 TRACE2(("gdth_to(): ints %d, ios %d, act_stats %d, act_rq %d\n",
3075 act_ints
, act_ios
, act_stats
, act_rq
));
3076 act_ints
= act_ios
= 0;
3078 gdth_timer
.expires
= jiffies
+ 30 * HZ
;
3079 add_timer(&gdth_timer
);
3080 GDTH_UNLOCK_HA(ha
, flags
);
3085 int __init
gdth_detect(Scsi_Host_Template
*shtp
)
3087 struct Scsi_Host
*shp
;
3091 int i
,hanum
,cnt
,ctr
;
3096 printk("GDT: This driver contains debugging information !! Trace level = %d\n",
3098 printk(" Destination of debugging information: ");
3101 printk("Serial port COM2\n");
3103 printk("Serial port COM1\n");
3106 printk("Console\n");
3111 TRACE(("gdth_detect()\n"));
3114 printk("GDT: Controller driver disabled from command line !\n");
3118 /* initializations */
3119 gdth_polling
= TRUE
; b
= 0;
3120 gdth_clear_events();
3122 /* scanning for controllers, at first: ISA controller */
3123 for (isa_bios
=0xc8000UL
; isa_bios
<=0xd8000UL
; isa_bios
+=0x8000UL
) {
3124 if (gdth_ctr_count
>= MAXHA
)
3126 if (gdth_search_isa(isa_bios
)) { /* controller found */
3127 shp
= scsi_register(shtp
,sizeof(gdth_ext_str
));
3129 if (!gdth_init_isa(isa_bios
,ha
)) {
3130 scsi_unregister(shp
);
3133 /* controller found and initialized */
3134 printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n",
3135 isa_bios
,ha
->irq
,ha
->drq
);
3137 if (request_irq(ha
->irq
,gdth_interrupt
,SA_INTERRUPT
,"gdth",ha
))
3139 printk("GDT-ISA: Unable to allocate IRQ\n");
3140 scsi_unregister(shp
);
3143 if (request_dma(ha
->drq
,"gdth")) {
3144 printk("GDT-ISA: Unable to allocate DMA channel\n");
3145 free_irq(ha
->irq
,NULL
);
3146 scsi_unregister(shp
);
3149 set_dma_mode(ha
->drq
,DMA_MODE_CASCADE
);
3150 enable_dma(ha
->drq
);
3151 shp
->unchecked_isa_dma
= 1;
3153 shp
->dma_channel
= ha
->drq
;
3154 hanum
= gdth_ctr_count
;
3155 gdth_ctr_tab
[gdth_ctr_count
++] = shp
;
3156 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
;
3158 NUMDATA(shp
)->hanum
= (ushort
)hanum
;
3159 NUMDATA(shp
)->busnum
= 0;
3161 ha
->pccb
= CMDDATA(shp
);
3162 ha
->pscratch
= (void *) __get_free_pages(GFP_ATOMIC
| GFP_DMA
, GDTH_SCRATCH_ORD
);
3163 ha
->scratch_busy
= FALSE
;
3164 ha
->req_first
= NULL
;
3165 ha
->tid_cnt
= MAX_HDRIVES
;
3166 if (max_ids
> 0 && max_ids
< ha
->tid_cnt
)
3167 ha
->tid_cnt
= max_ids
;
3168 for (i
=0; i
<GDTH_MAXCMDS
; ++i
)
3169 ha
->cmd_tab
[i
].cmnd
= UNUSED_CMND
;
3170 ha
->scan_mode
= rescan
? 0x10 : 0;
3172 if (ha
->pscratch
== NULL
|| !gdth_search_drives(hanum
)) {
3173 printk("GDT-ISA: Error during device scan\n");
3176 if (ha
->pscratch
!= NULL
)
3177 free_pages((unsigned long)ha
->pscratch
, GDTH_SCRATCH_ORD
);
3178 free_irq(ha
->irq
,NULL
);
3179 scsi_unregister(shp
);
3182 if (hdr_channel
< 0 || hdr_channel
> ha
->bus_cnt
)
3183 hdr_channel
= ha
->bus_cnt
;
3184 ha
->virt_bus
= hdr_channel
;
3186 shp
->max_id
= ha
->tid_cnt
;
3187 shp
->max_lun
= MAXLUN
;
3188 shp
->max_channel
= ha
->bus_cnt
;
3189 GDTH_INIT_LOCK_HA(ha
);
3190 gdth_enable_int(hanum
);
3194 /* scanning for EISA controllers */
3195 for (eisa_slot
=0x1000; eisa_slot
<=0x8000; eisa_slot
+=0x1000) {
3196 if (gdth_ctr_count
>= MAXHA
)
3198 if (gdth_search_eisa(eisa_slot
)) { /* controller found */
3199 shp
= scsi_register(shtp
,sizeof(gdth_ext_str
));
3201 if (!gdth_init_eisa(eisa_slot
,ha
)) {
3202 scsi_unregister(shp
);
3205 /* controller found and initialized */
3206 printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
3207 eisa_slot
>>12,ha
->irq
);
3209 if (request_irq(ha
->irq
,gdth_interrupt
,SA_INTERRUPT
,"gdth",ha
))
3211 printk("GDT-EISA: Unable to allocate IRQ\n");
3212 scsi_unregister(shp
);
3215 shp
->unchecked_isa_dma
= 0;
3217 shp
->dma_channel
= 0xff;
3218 hanum
= gdth_ctr_count
;
3219 gdth_ctr_tab
[gdth_ctr_count
++] = shp
;
3220 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
;
3222 NUMDATA(shp
)->hanum
= (ushort
)hanum
;
3223 NUMDATA(shp
)->busnum
= 0;
3224 TRACE2(("EISA detect Bus 0: hanum %d\n",
3225 NUMDATA(shp
)->hanum
));
3227 ha
->pccb
= CMDDATA(shp
);
3228 ha
->pscratch
= (void *) __get_free_pages(GFP_ATOMIC
| GFP_DMA
, GDTH_SCRATCH_ORD
);
3229 ha
->scratch_busy
= FALSE
;
3230 ha
->req_first
= NULL
;
3231 ha
->tid_cnt
= MAX_HDRIVES
;
3232 if (max_ids
> 0 && max_ids
< ha
->tid_cnt
)
3233 ha
->tid_cnt
= max_ids
;
3234 for (i
=0; i
<GDTH_MAXCMDS
; ++i
)
3235 ha
->cmd_tab
[i
].cmnd
= UNUSED_CMND
;
3236 ha
->scan_mode
= rescan
? 0x10 : 0;
3238 if (ha
->pscratch
== NULL
|| !gdth_search_drives(hanum
)) {
3239 printk("GDT-EISA: Error during device scan\n");
3242 if (ha
->pscratch
!= NULL
)
3243 free_pages((unsigned long)ha
->pscratch
, GDTH_SCRATCH_ORD
);
3244 free_irq(ha
->irq
,NULL
);
3245 scsi_unregister(shp
);
3248 if (hdr_channel
< 0 || hdr_channel
> ha
->bus_cnt
)
3249 hdr_channel
= ha
->bus_cnt
;
3250 ha
->virt_bus
= hdr_channel
;
3252 shp
->max_id
= ha
->tid_cnt
;
3253 shp
->max_lun
= MAXLUN
;
3254 shp
->max_channel
= ha
->bus_cnt
;
3255 GDTH_INIT_LOCK_HA(ha
);
3256 gdth_enable_int(hanum
);
3260 /* scanning for PCI controllers */
3263 gdth_pci_str pcistr
[MAXHA
];
3265 cnt
= gdth_search_pci(pcistr
);
3266 gdth_sort_pci(pcistr
,cnt
);
3267 for (ctr
= 0; ctr
< cnt
; ++ctr
) {
3268 if (gdth_ctr_count
>= MAXHA
)
3270 shp
= scsi_register(shtp
,sizeof(gdth_ext_str
));
3272 if (!gdth_init_pci(&pcistr
[ctr
],ha
)) {
3273 scsi_unregister(shp
);
3276 /* controller found and initialized */
3277 printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n",
3278 pcistr
[ctr
].bus
,PCI_SLOT(pcistr
[ctr
].device_fn
),ha
->irq
);
3280 if (request_irq(ha
->irq
, gdth_interrupt
,
3281 SA_INTERRUPT
|SA_SHIRQ
, "gdth", ha
))
3283 printk("GDT-PCI: Unable to allocate IRQ\n");
3284 scsi_unregister(shp
);
3287 shp
->unchecked_isa_dma
= 0;
3289 shp
->dma_channel
= 0xff;
3290 hanum
= gdth_ctr_count
;
3291 gdth_ctr_tab
[gdth_ctr_count
++] = shp
;
3292 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
;
3294 NUMDATA(shp
)->hanum
= (ushort
)hanum
;
3295 NUMDATA(shp
)->busnum
= 0;
3297 ha
->pccb
= CMDDATA(shp
);
3298 ha
->pscratch
= (void *) __get_free_pages(GFP_ATOMIC
| GFP_DMA
, GDTH_SCRATCH_ORD
);
3299 ha
->scratch_busy
= FALSE
;
3300 ha
->req_first
= NULL
;
3301 ha
->tid_cnt
= pcistr
[ctr
].device_id
>= 0x200 ? MAXID
: MAX_HDRIVES
;
3302 if (max_ids
> 0 && max_ids
< ha
->tid_cnt
)
3303 ha
->tid_cnt
= max_ids
;
3304 for (i
=0; i
<GDTH_MAXCMDS
; ++i
)
3305 ha
->cmd_tab
[i
].cmnd
= UNUSED_CMND
;
3306 ha
->scan_mode
= rescan
? 0x10 : 0;
3308 if (ha
->pscratch
== NULL
|| !gdth_search_drives(hanum
)) {
3309 printk("GDT-PCI: Error during device scan\n");
3312 if (ha
->pscratch
!= NULL
)
3313 free_pages((unsigned long)ha
->pscratch
, GDTH_SCRATCH_ORD
);
3314 free_irq(ha
->irq
,NULL
);
3315 scsi_unregister(shp
);
3318 if (hdr_channel
< 0 || hdr_channel
> ha
->bus_cnt
)
3319 hdr_channel
= ha
->bus_cnt
;
3320 ha
->virt_bus
= hdr_channel
;
3322 shp
->max_id
= ha
->tid_cnt
;
3323 shp
->max_lun
= MAXLUN
;
3324 shp
->max_channel
= ha
->bus_cnt
;
3325 GDTH_INIT_LOCK_HA(ha
);
3326 gdth_enable_int(hanum
);
3330 TRACE2(("gdth_detect() %d controller detected\n",gdth_ctr_count
));
3331 if (gdth_ctr_count
> 0) {
3332 #ifdef GDTH_STATISTICS
3333 TRACE2(("gdth_detect(): Initializing timer !\n"));
3334 init_timer(&gdth_timer
);
3335 gdth_timer
.expires
= jiffies
+ HZ
;
3336 gdth_timer
.data
= 0L;
3337 gdth_timer
.function
= gdth_timeout
;
3338 add_timer(&gdth_timer
);
3340 register_reboot_notifier(&gdth_notifier
);
3342 gdth_polling
= FALSE
;
3343 return gdth_ctr_vcount
;
3347 int gdth_release(struct Scsi_Host
*shp
)
3352 TRACE2(("gdth_release()\n"));
3353 if (NUMDATA(shp
)->busnum
== 0) {
3354 hanum
= NUMDATA(shp
)->hanum
;
3355 ha
= HADATA(gdth_ctr_tab
[hanum
]);
3359 free_irq(shp
->irq
,NULL
);
3361 if (shp
->dma_channel
!= 0xff) {
3362 free_dma(shp
->dma_channel
);
3364 free_pages((unsigned long)ha
->pscratch
, GDTH_SCRATCH_ORD
);
3365 gdth_ctr_released
++;
3366 TRACE2(("gdth_release(): HA %d of %d\n",
3367 gdth_ctr_released
, gdth_ctr_count
));
3369 if (gdth_ctr_released
== gdth_ctr_count
) {
3370 #ifdef GDTH_STATISTICS
3371 del_timer(&gdth_timer
);
3373 unregister_reboot_notifier(&gdth_notifier
);
3377 scsi_unregister(shp
);
3382 static const char *gdth_ctr_name(int hanum
)
3386 TRACE2(("gdth_ctr_name()\n"));
3388 ha
= HADATA(gdth_ctr_tab
[hanum
]);
3390 if (ha
->type
== GDT_EISA
) {
3391 switch (ha
->stype
) {
3393 return("GDT3000/3020");
3395 return("GDT3000A/3020A/3050A");
3397 return("GDT3000B/3010A");
3399 } else if (ha
->type
== GDT_ISA
) {
3400 return("GDT2000/2020");
3401 } else if (ha
->type
== GDT_PCI
) {
3402 switch (ha
->stype
) {
3403 case PCI_DEVICE_ID_VORTEX_GDT60x0
:
3404 return("GDT6000/6020/6050");
3405 case PCI_DEVICE_ID_VORTEX_GDT6000B
:
3406 return("GDT6000B/6010");
3409 /* new controllers (GDT_PCINEW, GDT_PCIMPR, ..) use board_info IOCTL! */
3414 const char *gdth_info(struct Scsi_Host
*shp
)
3419 TRACE2(("gdth_info()\n"));
3420 hanum
= NUMDATA(shp
)->hanum
;
3421 ha
= HADATA(gdth_ctr_tab
[hanum
]);
3423 return ((const char *)ha
->binfo
.type_string
);
3426 /* old error handling */
3427 int gdth_abort(Scsi_Cmnd
*scp
)
3429 TRACE2(("gdth_abort() reason %d\n",scp
->abort_reason
));
3430 return SCSI_ABORT_SNOOZE
;
3433 int gdth_reset(Scsi_Cmnd
*scp
, unsigned int reset_flags
)
3435 TRACE2(("gdth_reset()\n"));
3436 return SCSI_RESET_PUNT
;
3439 /* new error handling */
3440 int gdth_eh_abort(Scsi_Cmnd
*scp
)
3442 TRACE2(("gdth_eh_abort()\n"));
3446 int gdth_eh_device_reset(Scsi_Cmnd
*scp
)
3448 TRACE2(("gdth_eh_device_reset()\n"));
3452 int gdth_eh_bus_reset(Scsi_Cmnd
*scp
)
3459 TRACE2(("gdth_eh_bus_reset()\n"));
3460 hanum
= NUMDATA(scp
->host
)->hanum
;
3461 ha
= HADATA(gdth_ctr_tab
[hanum
]);
3462 if (scp
->channel
== ha
->virt_bus
)
3465 GDTH_LOCK_HA(ha
, flags
);
3466 for (i
= 0; i
< MAXID
; ++i
)
3467 ha
->raw
[BUS_L2P(ha
,scp
->channel
)].io_cnt
[i
] = 0;
3468 for (i
= 0; i
< GDTH_MAXCMDS
; ++i
) {
3469 cmnd
= ha
->cmd_tab
[i
].cmnd
;
3470 if (!SPECIAL_SCP(cmnd
) && cmnd
->channel
== scp
->channel
)
3471 ha
->cmd_tab
[i
].cmnd
= UNUSED_CMND
;
3473 gdth_polling
= TRUE
;
3474 while (gdth_test_busy(hanum
))
3476 gdth_internal_cmd(hanum
, SCSIRAWSERVICE
, GDT_RESET_BUS
,
3477 BUS_L2P(ha
,scp
->channel
), 0, 0);
3478 gdth_polling
= FALSE
;
3479 GDTH_UNLOCK_HA(ha
, flags
);
3483 int gdth_eh_host_reset(Scsi_Cmnd
*scp
)
3485 TRACE2(("gdth_eh_host_reset()\n"));
3489 int gdth_bios_param(Disk
*disk
,kdev_t dev
,int *ip
)
3495 hanum
= NUMDATA(disk
->device
->host
)->hanum
;
3496 t
= disk
->device
->id
;
3497 TRACE2(("gdth_bios_param() ha %d bus %d target %d\n",
3498 hanum
, disk
->device
->channel
, t
));
3499 ha
= HADATA(gdth_ctr_tab
[hanum
]);
3501 if (disk
->device
->channel
!= ha
->virt_bus
|| ha
->hdr
[t
].heads
== 0) {
3502 /* raw device or host drive without mapping information */
3503 TRACE2(("Evaluate mapping\n"));
3504 gdth_eval_mapping(disk
->capacity
,&ip
[2],&ip
[0],&ip
[1]);
3506 ip
[0] = ha
->hdr
[t
].heads
;
3507 ip
[1] = ha
->hdr
[t
].secs
;
3508 ip
[2] = disk
->capacity
/ ip
[0] / ip
[1];
3511 TRACE2(("gdth_bios_param(): %d heads, %d secs, %d cyls\n",
3512 ip
[0],ip
[1],ip
[2]));
3517 static void internal_done(Scsi_Cmnd
*scp
)
3519 scp
->SCp
.sent_command
++;
3522 int gdth_command(Scsi_Cmnd
*scp
)
3524 TRACE2(("gdth_command()\n"));
3526 scp
->SCp
.sent_command
= 0;
3527 gdth_queuecommand(scp
,internal_done
);
3529 while (!scp
->SCp
.sent_command
)
3535 int gdth_queuecommand(Scsi_Cmnd
*scp
,void (*done
)(Scsi_Cmnd
*))
3540 TRACE(("gdth_queuecommand() cmd 0x%x id %d lun %d\n",
3541 scp
->cmnd
[0],scp
->target
,scp
->lun
));
3543 scp
->scsi_done
= (void *)done
;
3544 scp
->SCp
.have_data_in
= 1;
3545 scp
->SCp
.phase
= -1;
3546 scp
->SCp
.Status
= -1;
3547 hanum
= NUMDATA(scp
->host
)->hanum
;
3548 #ifdef GDTH_STATISTICS
3552 priority
= DEFAULT_PRI
;
3553 if (scp
->done
== gdth_scsi_done
)
3554 priority
= scp
->SCp
.this_residual
;
3555 gdth_update_timeout(hanum
, scp
, scp
->timeout_per_command
* 6);
3556 gdth_putq( hanum
, scp
, priority
);
3562 static void gdth_flush(int hanum
)
3568 gdth_cmd_str gdtcmd
;
3570 TRACE2(("gdth_flush() hanum %d\n",hanum
));
3571 ha
= HADATA(gdth_ctr_tab
[hanum
]);
3573 sdev
= scsi_get_host_dev(gdth_ctr_tab
[hanum
]);
3574 scp
= scsi_allocate_device(sdev
, 1, FALSE
);
3579 for (i
= 0; i
< MAX_HDRIVES
; ++i
) {
3580 if (ha
->hdr
[i
].present
) {
3581 gdtcmd
.BoardNode
= LOCALBOARD
;
3582 gdtcmd
.Service
= CACHESERVICE
;
3583 gdtcmd
.OpCode
= GDT_FLUSH
;
3584 gdtcmd
.u
.cache
.DeviceNo
= i
;
3585 gdtcmd
.u
.cache
.BlockNo
= 1;
3586 gdtcmd
.u
.cache
.sg_canz
= 0;
3587 TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum
, i
));
3588 gdth_do_cmd(scp
, &gdtcmd
, 30);
3591 scsi_release_command(scp
);
3592 scsi_free_host_dev(sdev
);
3595 /* shutdown routine */
3596 static int gdth_halt(struct notifier_block
*nb
, ulong event
, void *buf
)
3602 gdth_cmd_str gdtcmd
;
3605 TRACE2(("gdth_halt() event %d\n",event
));
3606 if (event
!= SYS_RESTART
&& event
!= SYS_HALT
&& event
!= SYS_POWER_OFF
)
3608 printk("GDT: Flushing all host drives .. ");
3609 for (hanum
= 0; hanum
< gdth_ctr_count
; ++hanum
) {
3613 /* controller reset */
3614 sdev
= scsi_get_host_dev(gdth_ctr_tab
[hanum
]);
3615 scp
= scsi_allocate_device(sdev
, 1, FALSE
);
3619 gdtcmd
.BoardNode
= LOCALBOARD
;
3620 gdtcmd
.Service
= CACHESERVICE
;
3621 gdtcmd
.OpCode
= GDT_RESET
;
3622 TRACE2(("gdth_halt(): reset controller %d\n", hanum
));
3623 gdth_do_cmd(scp
, &gdtcmd
, 10);
3624 scsi_release_command(scp
);
3625 scsi_free_host_dev(sdev
);
3631 #ifdef GDTH_STATISTICS
3632 del_timer(&gdth_timer
);
3634 unregister_reboot_notifier(&gdth_notifier
);
3638 /* called from init/main.c */
3639 void __init
gdth_setup(char *str
,int *ints
)
3642 char *cur_str
, *argv
;
3644 TRACE2(("gdth_setup() str %s ints[0] %d\n",
3645 str
? str
:"NULL", ints
? ints
[0]:0));
3647 /* read irq[] from ints[] */
3653 for (i
= 0; i
< argc
; ++i
)
3658 /* analyse string */
3660 while (argv
&& (cur_str
= strchr(argv
, ':'))) {
3661 int val
= 0, c
= *++cur_str
;
3663 if (c
== 'n' || c
== 'N')
3665 else if (c
== 'y' || c
== 'Y')
3668 val
= (int)simple_strtoul(cur_str
, NULL
, 0);
3670 if (!strncmp(argv
, "disable:", 8))
3672 else if (!strncmp(argv
, "reserve_mode:", 13))
3674 else if (!strncmp(argv
, "reverse_scan:", 13))
3676 else if (!strncmp(argv
, "hdr_channel:", 12))
3678 else if (!strncmp(argv
, "max_ids:", 8))
3680 else if (!strncmp(argv
, "rescan:", 7))
3682 else if (!strncmp(argv
, "reserve_list:", 13)) {
3683 reserve_list
[0] = val
;
3684 for (i
= 1; i
< MAX_RES_ARGS
; i
++) {
3685 cur_str
= strchr(cur_str
, ',');
3688 if (!isdigit((int)*++cur_str
)) {
3693 (int)simple_strtoul(cur_str
, NULL
, 0);
3701 if ((argv
= strchr(argv
, ',')))
3708 Scsi_Host_Template driver_template
= GDTH
;
3709 #include "scsi_module.c"