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 #if LINUX_VERSION_CODE >= 0x020100 185 #include <linux/reboot.h> 187 #include <linux/bios32.h> 191 #include <asm/system.h> 193 #if LINUX_VERSION_CODE >= 0x02015F 194 #include <linux/spinlock.h> 197 #if LINUX_VERSION_CODE >= 0x010300 198 #include <linux/blk.h> 200 #include"../block/blk.h" 208 static voidgdth_delay(int milliseconds
); 209 static voidgdth_eval_mapping(ulong32 size
,int*cyls
,int*heads
,int*secs
); 210 #if LINUX_VERSION_CODE >= 0x010346 211 static voidgdth_interrupt(int irq
,void*dev_id
,struct pt_regs
*regs
); 213 static voidgdth_interrupt(int irq
,struct pt_regs
*regs
); 215 static intgdth_sync_event(int hanum
,int service
,unchar index
,Scsi_Cmnd
*scp
); 216 static intgdth_async_event(int hanum
,int service
); 217 static voidgdth_log_event(gdth_evt_data
*dvr
,char*buffer
); 219 static voidgdth_putq(int hanum
,Scsi_Cmnd
*scp
,unchar priority
); 220 static voidgdth_next(int hanum
); 221 static intgdth_fill_raw_cmd(int hanum
,Scsi_Cmnd
*scp
,unchar b
); 222 static intgdth_special_cmd(int hanum
,Scsi_Cmnd
*scp
); 223 static gdth_evt_str
*gdth_store_event(gdth_ha_str
*ha
, ushort source
, 224 ushort idx
, gdth_evt_data
*evt
); 225 static intgdth_read_event(gdth_ha_str
*ha
,int handle
, gdth_evt_str
*estr
); 226 static voidgdth_readapp_event(gdth_ha_str
*ha
, unchar application
, 228 static voidgdth_clear_events(void); 230 static voidgdth_copy_internal_data(Scsi_Cmnd
*scp
,char*buffer
,ushort count
); 231 static intgdth_internal_cache_cmd(int hanum
,Scsi_Cmnd
*scp
); 232 static intgdth_fill_cache_cmd(int hanum
,Scsi_Cmnd
*scp
,ushort hdrive
); 234 static intgdth_search_eisa(ushort eisa_adr
); 235 static intgdth_search_isa(ulong32 bios_adr
); 236 static intgdth_search_pci(gdth_pci_str
*pcistr
); 237 static voidgdth_sort_pci(gdth_pci_str
*pcistr
,int cnt
); 238 static intgdth_init_eisa(ushort eisa_adr
,gdth_ha_str
*ha
); 239 static intgdth_init_isa(ulong32 bios_adr
,gdth_ha_str
*ha
); 240 static intgdth_init_pci(gdth_pci_str
*pcistr
,gdth_ha_str
*ha
); 242 static voidgdth_enable_int(int hanum
); 243 static intgdth_get_status(unchar
*pIStatus
,int irq
); 244 static intgdth_test_busy(int hanum
); 245 static intgdth_get_cmd_index(int hanum
); 246 static voidgdth_release_event(int hanum
); 247 static intgdth_wait(int hanum
,int index
,ulong32 time
); 248 static intgdth_internal_cmd(int hanum
,unchar service
,ushort opcode
,ulong32 p1
, 249 ulong32 p2
,ulong32 p3
); 250 static intgdth_search_drives(int hanum
); 252 static void*gdth_mmap(ulong paddr
, ulong size
); 253 static voidgdth_munmap(void*addr
); 255 static const char*gdth_ctr_name(int hanum
); 257 #if LINUX_VERSION_CODE >= 0x010300 258 static voidgdth_flush(int hanum
); 259 #if LINUX_VERSION_CODE >= 0x020100 260 static intgdth_halt(struct notifier_block
*nb
, ulong event
,void*buf
); 262 static int halt_called
= FALSE
; 268 static unchar DebugState
= DEBUG_GDTH
; 269 externlongsys_syslog(int,char*,int); 270 #define LOGEN sys_syslog(7,NULL,0) 273 #define MAX_SERBUF 160 274 static voidser_init(void); 275 static voidser_puts(char*str
); 276 static voidser_putc(char c
); 277 static intser_printk(const char*fmt
, ...); 278 static char strbuf
[MAX_SERBUF
+1]; 280 #define COM_BASE 0x2f8 282 #define COM_BASE 0x3f8 284 static voidser_init() 286 unsigned port
=COM_BASE
; 290 /* 19200 Baud, if 9600: outb(12,port) */ 300 static voidser_puts(char*str
) 305 for(ptr
=str
;*ptr
;++ptr
) 309 static voidser_putc(char c
) 311 unsigned port
=COM_BASE
; 313 while((inb(port
+5) &0x20)==0); 317 while((inb(port
+5) &0x20)==0); 322 static intser_printk(const char*fmt
, ...) 328 i
=vsprintf(strbuf
,fmt
,args
); 334 #define TRACE(a) {if (DebugState==1) {ser_printk a;}} 335 #define TRACE2(a) {if (DebugState==1 || DebugState==2) {ser_printk a;}} 336 #define TRACE3(a) {if (DebugState!=0) {ser_printk a;}} 338 #else/* !__SERIAL__ */ 339 #define TRACE(a) {if (DebugState==1) {LOGEN;printk a;}} 340 #define TRACE2(a) {if (DebugState==1 || DebugState==2) {LOGEN;printk a;}} 341 #define TRACE3(a) {if (DebugState!=0) {LOGEN;printk a;}} 350 #ifdef GDTH_STATISTICS 351 static ulong32 max_rq
=0, max_index
=0, max_sg
=0; 352 static ulong32 act_ints
=0, act_ios
=0, act_stats
=0, act_rq
=0; 353 static struct timer_list gdth_timer
; 356 #define PTR2USHORT(a) (ushort)(ulong)(a) 357 #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) 358 #define INDEX_OK(i,t) ((i)<sizeof(t)/sizeof((t)[0])) 360 #define NUMDATA(a) ( (gdth_num_str *)((a)->hostdata)) 361 #define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext) 362 #define CMDDATA(a) (&((gdth_ext_str *)((a)->hostdata))->cmdext) 364 #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) 366 #if LINUX_VERSION_CODE < 0x010300 367 static void*gdth_mmap(ulong paddr
, ulong size
) 369 if(paddr
>= high_memory
) 374 static voidgdth_munmap(void*addr
) 377 inline ulong32
virt_to_phys(volatilevoid*addr
) 381 inlinevoid*phys_to_virt(ulong32 addr
) 385 #define virt_to_bus virt_to_phys 386 #define bus_to_virt phys_to_virt 387 #define gdth_readb(addr) (*(volatile unchar *)(addr)) 388 #define gdth_readw(addr) (*(volatile ushort *)(addr)) 389 #define gdth_readl(addr) (*(volatile ulong32 *)(addr)) 390 #define gdth_writeb(b,addr) (*(volatile unchar *)(addr) = (b)) 391 #define gdth_writew(b,addr) (*(volatile ushort *)(addr) = (b)) 392 #define gdth_writel(b,addr) (*(volatile ulong32 *)(addr) = (b)) 393 #define memset_io(a,b,c) memset((void *)(a),(b),(c)) 394 #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) 395 #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) 397 #define PCI_SLOT(devfn) ((devfn >> 3) & 0x1f) 399 #elif LINUX_VERSION_CODE < 0x020100 400 static int remapped
= FALSE
; 401 static void*gdth_mmap(ulong paddr
, ulong size
) 403 if( paddr
>= high_memory
) { 405 returnvremap(paddr
, size
); 410 static voidgdth_munmap(void*addr
) 416 #define gdth_readb(addr) readb((ulong)(addr)) 417 #define gdth_readw(addr) readw((ulong)(addr)) 418 #define gdth_readl(addr) (ulong32)readl((ulong)(addr)) 419 #define gdth_writeb(b,addr) writeb((b),(ulong)(addr)) 420 #define gdth_writew(b,addr) writew((b),(ulong)(addr)) 421 #define gdth_writel(b,addr) writel((b),(ulong)(addr)) 424 static void*gdth_mmap(ulong paddr
, ulong size
) 426 returnioremap(paddr
, size
); 428 static voidgdth_munmap(void*addr
) 432 #define gdth_readb(addr) readb((ulong)(addr)) 433 #define gdth_readw(addr) readw((ulong)(addr)) 434 #define gdth_readl(addr) (ulong32)readl((ulong)(addr)) 435 #define gdth_writeb(b,addr) writeb((b),(ulong)(addr)) 436 #define gdth_writew(b,addr) writew((b),(ulong)(addr)) 437 #define gdth_writel(b,addr) writel((b),(ulong)(addr)) 441 static unchar gdth_drq_tab
[4] = {5,6,7,7};/* DRQ table */ 442 static unchar gdth_irq_tab
[6] = {0,10,11,12,14,0};/* IRQ table */ 443 static unchar gdth_polling
;/* polling if TRUE */ 444 static unchar gdth_from_wait
= FALSE
;/* gdth_wait() */ 445 static int wait_index
,wait_hanum
;/* gdth_wait() */ 446 static int gdth_ctr_count
=0;/* controller count */ 447 static int gdth_ctr_vcount
=0;/* virt. ctr. count */ 448 static int gdth_ctr_released
=0;/* gdth_release() */ 449 static struct Scsi_Host
*gdth_ctr_tab
[MAXHA
];/* controller table */ 450 static struct Scsi_Host
*gdth_ctr_vtab
[MAXHA
*MAXBUS
];/* virt. ctr. table */ 451 static unchar gdth_write_through
= FALSE
;/* write through */ 452 static gdth_evt_str ebuffer
[MAX_EVENTS
];/* event buffer */ 456 #define DIN 1/* IN data direction */ 457 #define DOU 2/* OUT data direction */ 458 #define DNO DIN/* no data transfer */ 459 #define DUN DIN/* unknown data direction */ 460 static unchar gdth_direction_tab
[0x100] = { 461 DNO
,DNO
,DIN
,DIN
,DOU
,DIN
,DIN
,DOU
,DIN
,DUN
,DOU
,DOU
,DUN
,DUN
,DUN
,DIN
, 462 DNO
,DIN
,DIN
,DOU
,DIN
,DOU
,DNO
,DNO
,DOU
,DNO
,DIN
,DNO
,DIN
,DOU
,DNO
,DUN
, 463 DIN
,DUN
,DIN
,DUN
,DOU
,DIN
,DUN
,DUN
,DIN
,DIN
,DOU
,DNO
,DUN
,DIN
,DOU
,DOU
, 464 DOU
,DOU
,DOU
,DNO
,DIN
,DNO
,DNO
,DIN
,DOU
,DOU
,DOU
,DOU
,DIN
,DOU
,DIN
,DOU
, 465 DOU
,DOU
,DIN
,DIN
,DIN
,DNO
,DUN
,DNO
,DNO
,DNO
,DUN
,DNO
,DOU
,DIN
,DUN
,DUN
, 466 DUN
,DUN
,DUN
,DUN
,DUN
,DOU
,DUN
,DUN
,DUN
,DUN
,DIN
,DUN
,DUN
,DUN
,DUN
,DUN
, 467 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
, 468 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
, 469 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
, 470 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
, 471 DUN
,DUN
,DUN
,DUN
,DUN
,DNO
,DNO
,DUN
,DIN
,DNO
,DOU
,DUN
,DNO
,DUN
,DOU
,DOU
, 472 DOU
,DOU
,DOU
,DNO
,DUN
,DIN
,DOU
,DIN
,DIN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
, 473 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
, 474 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
, 475 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DOU
,DUN
,DUN
,DUN
,DUN
,DUN
, 476 DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
,DUN
479 /* __initfunc, __initdata macros */ 480 #if LINUX_VERSION_CODE >= 0x020126 481 #include <linux/init.h> 483 #define __initfunc(A) A 488 #if LINUX_VERSION_CODE >= 0x02015F 489 #define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock) 490 #define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags) 491 #define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags) 493 #define GDTH_LOCK_SCSI_DONE(flags) spin_lock_irqsave(&io_request_lock,flags) 494 #define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(&io_request_lock,flags) 495 #define GDTH_LOCK_SCSI_DOCMD() spin_lock_irq(&io_request_lock) 496 #define GDTH_UNLOCK_SCSI_DOCMD() spin_unlock_irq(&io_request_lock) 498 #define GDTH_INIT_LOCK_HA(ha) do {} while (0) 499 #define GDTH_LOCK_HA(ha,flags) do {save_flags(flags); cli();} while (0) 500 #define GDTH_UNLOCK_HA(ha,flags) do {restore_flags(flags);} while (0) 502 #define GDTH_LOCK_SCSI_DONE(flags) do {} while (0) 503 #define GDTH_UNLOCK_SCSI_DONE(flags) do {} while (0) 504 #define GDTH_LOCK_SCSI_DOCMD() do {} while (0) 505 #define GDTH_UNLOCK_SCSI_DOCMD() do {} while (0) 508 /* LILO and modprobe/insmod parameters */ 509 /* IRQ list for GDT3000/3020 EISA controllers */ 510 static int irq
[MAXHA
] __initdata
= 511 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 512 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 513 /* disable driver flag */ 514 static int disable __initdata
=0; 516 static int reserve_mode
=1; 518 static int reserve_list
[MAX_RES_ARGS
] = 519 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 520 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 521 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 522 /* scan order for PCI controllers */ 523 static int reverse_scan
=0; 524 /* virtual channel for the host drives */ 525 static int hdr_channel
=0; 526 /* max. IDs per channel */ 527 static int max_ids
= MAXID
; 529 static int rescan
=0; 532 #if LINUX_VERSION_CODE >= 0x02011A 533 /* parameters for modprobe/insmod */ 534 MODULE_PARM(irq
,"i"); 535 MODULE_PARM(disable
,"i"); 536 MODULE_PARM(reserve_mode
,"i"); 537 MODULE_PARM(reserve_list
,"4-"__MODULE_STRING(MAX_RES_ARGS
)"i"); 538 MODULE_PARM(reverse_scan
,"i"); 539 MODULE_PARM(hdr_channel
,"i"); 540 MODULE_PARM(max_ids
,"i"); 541 MODULE_PARM(rescan
,"i"); 542 MODULE_AUTHOR("Achim Leubner"); 547 #if LINUX_VERSION_CODE >= 0x010300 548 #include <linux/stat.h> 549 struct proc_dir_entry proc_scsi_gdth
= { 550 PROC_SCSI_GDTH
,4,"gdth", 551 S_IFDIR
| S_IRUGO
| S_IXUGO
,2 553 #include"gdth_proc.h" 554 #include"gdth_proc.c" 557 #if LINUX_VERSION_CODE >= 0x020100 558 /* notifier block to get a notify on system shutdown/halt/reboot */ 559 static struct notifier_block gdth_notifier
= { 565 static voidgdth_delay(int milliseconds
) 567 if(milliseconds
==0) { 570 #if LINUX_VERSION_CODE >= 0x020168 571 mdelay(milliseconds
); 574 for(i
=0; i
< milliseconds
; ++i
) 580 static voidgdth_eval_mapping(ulong32 size
,int*cyls
,int*heads
,int*secs
) 582 *cyls
= size
/HEADS
/SECS
; 583 if(*cyls
<= MAXCYLS
) { 586 }else{/* too high for 64*32 */ 587 *cyls
= size
/MEDHEADS
/MEDSECS
; 588 if(*cyls
<= MAXCYLS
) { 591 }else{/* too high for 127*63 */ 592 *cyls
= size
/BIGHEADS
/BIGSECS
; 599 /* controller search and initialization functions */ 601 static int __init
gdth_search_eisa(ushort eisa_adr
) 605 TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr
)); 606 id
=inl(eisa_adr
+ID0REG
); 607 if(id
== GDT3A_ID
|| id
== GDT3B_ID
) {/* GDT3000A or GDT3000B */ 608 if((inb(eisa_adr
+EISAREG
) &8) ==0) 609 return0;/* not EISA configured */ 612 if(id
== GDT3_ID
)/* GDT3000 */ 619 static int __init
gdth_search_isa(ulong32 bios_adr
) 624 TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr
)); 625 if((addr
=gdth_mmap(bios_adr
+BIOS_ID_OFFS
,sizeof(ulong32
))) != NULL
) { 626 id
=gdth_readl(addr
); 628 if(id
== GDT2_ID
)/* GDT2000 */ 635 static int __init
gdth_search_pci(gdth_pci_str
*pcistr
) 637 ulong32 base0
, base1
, base2
; 638 ushort device_id
, cnt
; 639 #if LINUX_VERSION_CODE >= 0x2015C 640 struct pci_dev
*pdev
; 646 TRACE(("gdth_search_pci()\n")); 649 for(device_id
=0; device_id
<= PCI_DEVICE_ID_VORTEX_GDTMAXRP
; 651 if(device_id
> PCI_DEVICE_ID_VORTEX_GDT6555
&& 652 device_id
< PCI_DEVICE_ID_VORTEX_GDT6x17RP
) 655 while((pdev
=pci_find_device(PCI_VENDOR_ID_VORTEX
,device_id
,pdev
)) 659 /* GDT PCI controller found, resources are already in pdev */ 660 pcistr
[cnt
].pdev
= pdev
; 661 pcistr
[cnt
].device_id
= device_id
; 662 pcistr
[cnt
].bus
= pdev
->bus
->number
; 663 pcistr
[cnt
].device_fn
= pdev
->devfn
; 664 pcistr
[cnt
].irq
= pdev
->irq
; 665 base0
= pdev
->resource
[0].flags
; 666 base1
= pdev
->resource
[1].flags
; 667 base2
= pdev
->resource
[2].flags
; 668 if(device_id
<= PCI_DEVICE_ID_VORTEX_GDT6000B
||/* GDT6000/B */ 669 device_id
>= PCI_DEVICE_ID_VORTEX_GDT6x17RP
) {/* MPR */ 670 if((base0
& PCI_BASE_ADDRESS_SPACE
) != 671 PCI_BASE_ADDRESS_SPACE_MEMORY
) 673 pcistr
[cnt
].dpmem
= pdev
->resource
[0].start
; 674 }else{/* GDT6110, GDT6120, .. */ 675 if((base0
& PCI_BASE_ADDRESS_SPACE
) != 676 PCI_BASE_ADDRESS_SPACE_MEMORY
|| 677 (base2
& PCI_BASE_ADDRESS_SPACE
) != 678 PCI_BASE_ADDRESS_SPACE_MEMORY
|| 679 (base1
& PCI_BASE_ADDRESS_SPACE
) != 680 PCI_BASE_ADDRESS_SPACE_IO
) 682 pcistr
[cnt
].dpmem
= pdev
->resource
[2].start
; 683 pcistr
[cnt
].io_mm
= pdev
->resource
[0].start
; 684 pcistr
[cnt
].io
= pdev
->resource
[1].start
; 686 TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%x\n", 687 pcistr
[cnt
].bus
,PCI_SLOT(pcistr
[cnt
].device_fn
), 688 pcistr
[cnt
].irq
, pcistr
[cnt
].dpmem
)); 696 static void __init
gdth_sort_pci(gdth_pci_str
*pcistr
,int cnt
) 701 TRACE(("gdth_sort_pci() cnt %d\n",cnt
)); 707 for(i
=0; i
< cnt
-1; ++i
) { 709 if((pcistr
[i
].bus
> pcistr
[i
+1].bus
) || 710 (pcistr
[i
].bus
== pcistr
[i
+1].bus
&& 711 PCI_SLOT(pcistr
[i
].device_fn
) > 712 PCI_SLOT(pcistr
[i
+1].device_fn
))) { 714 pcistr
[i
] = pcistr
[i
+1]; 719 if((pcistr
[i
].bus
< pcistr
[i
+1].bus
) || 720 (pcistr
[i
].bus
== pcistr
[i
+1].bus
&& 721 PCI_SLOT(pcistr
[i
].device_fn
) < 722 PCI_SLOT(pcistr
[i
+1].device_fn
))) { 724 pcistr
[i
] = pcistr
[i
+1]; 734 static int __init
gdth_init_eisa(ushort eisa_adr
,gdth_ha_str
*ha
) 737 unchar prot_ver
,eisacf
,i
,irq_found
; 739 TRACE(("gdth_init_eisa() adr. %x\n",eisa_adr
)); 741 /* disable board interrupts, deinitialize services */ 742 outb(0xff,eisa_adr
+EDOORREG
); 743 outb(0x00,eisa_adr
+EDENABREG
); 744 outb(0x00,eisa_adr
+EINTENABREG
); 746 outb(0xff,eisa_adr
+LDOORREG
); 747 retries
= INIT_RETRIES
; 749 while(inb(eisa_adr
+EDOORREG
) !=0xff) { 751 printk("GDT-EISA: Initialization error (DEINIT failed)\n"); 755 TRACE2(("wait for DEINIT: retries=%d\n",retries
)); 757 prot_ver
=inb(eisa_adr
+MAILBOXREG
); 758 outb(0xff,eisa_adr
+EDOORREG
); 759 if(prot_ver
!= PROTOCOL_VERSION
) { 760 printk("GDT-EISA: Illegal protocol version\n"); 764 ha
->brd_phys
= (ulong32
)eisa_adr
>>12; 766 outl(0,eisa_adr
+MAILBOXREG
); 767 outl(0,eisa_adr
+MAILBOXREG
+4); 768 outl(0,eisa_adr
+MAILBOXREG
+8); 769 outl(0,eisa_adr
+MAILBOXREG
+12); 772 if((id
=inl(eisa_adr
+ID0REG
)) == GDT3_ID
) { 775 outl(1,eisa_adr
+MAILBOXREG
+8); 776 outb(0xfe,eisa_adr
+LDOORREG
); 777 retries
= INIT_RETRIES
; 779 while(inb(eisa_adr
+EDOORREG
) !=0xfe) { 781 printk("GDT-EISA: Initialization error (get IRQ failed)\n"); 786 ha
->irq
=inb(eisa_adr
+MAILBOXREG
); 787 outb(0xff,eisa_adr
+EDOORREG
); 788 TRACE2(("GDT3000/3020: IRQ=%d\n",ha
->irq
)); 789 /* check the result */ 791 TRACE2(("Unknown IRQ, use IRQ table from cmd line !\n")); 792 for(i
=0, irq_found
= FALSE
; 793 i
< MAXHA
&& irq
[i
] !=0xff; ++i
) { 794 if(irq
[i
]==10|| irq
[i
]==11|| irq
[i
]==12|| irq
[i
]==14) { 802 printk("GDT-EISA: Can not detect controller IRQ,\n"); 803 printk("Use IRQ setting from command line (IRQ = %d)\n", 806 printk("GDT-EISA: Initialization error (unknown IRQ), Enable\n"); 807 printk("the controller BIOS or use command line parameters\n"); 812 eisacf
=inb(eisa_adr
+EISAREG
) &7; 813 if(eisacf
>4)/* level triggered */ 815 ha
->irq
= gdth_irq_tab
[eisacf
]; 823 static int __init
gdth_init_isa(ulong32 bios_adr
,gdth_ha_str
*ha
) 825 register gdt2_dpram_str
*dp2_ptr
; 827 unchar irq_drq
,prot_ver
; 830 TRACE(("gdth_init_isa() bios adr. %x\n",bios_adr
)); 832 ha
->brd
=gdth_mmap(bios_adr
,sizeof(gdt2_dpram_str
)); 833 if(ha
->brd
== NULL
) { 834 printk("GDT-ISA: Initialization error (DPMEM remap error)\n"); 837 dp2_ptr
= (gdt2_dpram_str
*)ha
->brd
; 838 gdth_writeb(1, &dp2_ptr
->io
.memlock
);/* switch off write protection */ 839 /* reset interface area */ 840 memset_io((char*)&dp2_ptr
->u
,0,sizeof(dp2_ptr
->u
)); 841 if(gdth_readl(&dp2_ptr
->u
) !=0) { 842 printk("GDT-PCI: Initialization error (DPMEM write error)\n"); 843 gdth_munmap(ha
->brd
); 847 /* disable board interrupts, read DRQ and IRQ */ 848 gdth_writeb(0xff, &dp2_ptr
->io
.irqdel
); 849 gdth_writeb(0x00, &dp2_ptr
->io
.irqen
); 850 gdth_writeb(0x00, &dp2_ptr
->u
.ic
.S_Status
); 851 gdth_writeb(0x00, &dp2_ptr
->u
.ic
.Cmd_Index
); 853 irq_drq
=gdth_readb(&dp2_ptr
->io
.rq
); 859 ha
->drq
= gdth_drq_tab
[i
]; 861 irq_drq
=gdth_readb(&dp2_ptr
->io
.rq
) >>3; 867 ha
->irq
= gdth_irq_tab
[i
]; 869 /* deinitialize services */ 870 gdth_writel(bios_adr
, &dp2_ptr
->u
.ic
.S_Info
[0]); 871 gdth_writeb(0xff, &dp2_ptr
->u
.ic
.S_Cmd_Indx
); 872 gdth_writeb(0, &dp2_ptr
->io
.event
); 873 retries
= INIT_RETRIES
; 875 while(gdth_readb(&dp2_ptr
->u
.ic
.S_Status
) !=0xff) { 877 printk("GDT-ISA: Initialization error (DEINIT failed)\n"); 878 gdth_munmap(ha
->brd
); 883 prot_ver
= (unchar
)gdth_readl(&dp2_ptr
->u
.ic
.S_Info
[0]); 884 gdth_writeb(0, &dp2_ptr
->u
.ic
.Status
); 885 gdth_writeb(0xff, &dp2_ptr
->io
.irqdel
); 886 if(prot_ver
!= PROTOCOL_VERSION
) { 887 printk("GDT-ISA: Illegal protocol version\n"); 888 gdth_munmap(ha
->brd
); 893 ha
->ic_all_size
=sizeof(dp2_ptr
->u
); 895 ha
->brd_phys
= bios_adr
>>4; 897 /* special request to controller BIOS */ 898 gdth_writel(0x00, &dp2_ptr
->u
.ic
.S_Info
[0]); 899 gdth_writel(0x00, &dp2_ptr
->u
.ic
.S_Info
[1]); 900 gdth_writel(0x01, &dp2_ptr
->u
.ic
.S_Info
[2]); 901 gdth_writel(0x00, &dp2_ptr
->u
.ic
.S_Info
[3]); 902 gdth_writeb(0xfe, &dp2_ptr
->u
.ic
.S_Cmd_Indx
); 903 gdth_writeb(0, &dp2_ptr
->io
.event
); 904 retries
= INIT_RETRIES
; 906 while(gdth_readb(&dp2_ptr
->u
.ic
.S_Status
) !=0xfe) { 908 printk("GDT-ISA: Initialization error\n"); 909 gdth_munmap(ha
->brd
); 914 gdth_writeb(0, &dp2_ptr
->u
.ic
.Status
); 915 gdth_writeb(0xff, &dp2_ptr
->io
.irqdel
); 920 static int __init
gdth_init_pci(gdth_pci_str
*pcistr
,gdth_ha_str
*ha
) 922 register gdt6_dpram_str
*dp6_ptr
; 923 register gdt6c_dpram_str
*dp6c_ptr
; 924 register gdt6m_dpram_str
*dp6m_ptr
; 927 int i
, found
= FALSE
; 929 TRACE(("gdth_init_pci()\n")); 931 ha
->brd_phys
= (pcistr
->bus
<<8) | (pcistr
->device_fn
&0xf8); 932 ha
->stype
= (ulong32
)pcistr
->device_id
; 933 ha
->irq
= pcistr
->irq
; 935 if(ha
->stype
<= PCI_DEVICE_ID_VORTEX_GDT6000B
) {/* GDT6000/B */ 936 TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr
->dpmem
,ha
->irq
)); 937 ha
->brd
=gdth_mmap(pcistr
->dpmem
,sizeof(gdt6_dpram_str
)); 938 if(ha
->brd
== NULL
) { 939 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 942 dp6_ptr
= (gdt6_dpram_str
*)ha
->brd
; 943 /* reset interface area */ 944 memset_io((char*)&dp6_ptr
->u
,0,sizeof(dp6_ptr
->u
)); 945 if(gdth_readl(&dp6_ptr
->u
) !=0) { 946 printk("GDT-PCI: Initialization error (DPMEM write error)\n"); 947 gdth_munmap(ha
->brd
); 951 /* disable board interrupts, deinit services */ 952 gdth_writeb(0xff, &dp6_ptr
->io
.irqdel
); 953 gdth_writeb(0x00, &dp6_ptr
->io
.irqen
);; 954 gdth_writeb(0x00, &dp6_ptr
->u
.ic
.S_Status
); 955 gdth_writeb(0x00, &dp6_ptr
->u
.ic
.Cmd_Index
); 957 gdth_writel(pcistr
->dpmem
, &dp6_ptr
->u
.ic
.S_Info
[0]); 958 gdth_writeb(0xff, &dp6_ptr
->u
.ic
.S_Cmd_Indx
); 959 gdth_writeb(0, &dp6_ptr
->io
.event
); 960 retries
= INIT_RETRIES
; 962 while(gdth_readb(&dp6_ptr
->u
.ic
.S_Status
) !=0xff) { 964 printk("GDT-PCI: Initialization error (DEINIT failed)\n"); 965 gdth_munmap(ha
->brd
); 970 prot_ver
= (unchar
)gdth_readl(&dp6_ptr
->u
.ic
.S_Info
[0]); 971 gdth_writeb(0, &dp6_ptr
->u
.ic
.S_Status
); 972 gdth_writeb(0xff, &dp6_ptr
->io
.irqdel
); 973 if(prot_ver
!= PROTOCOL_VERSION
) { 974 printk("GDT-PCI: Illegal protocol version\n"); 975 gdth_munmap(ha
->brd
); 980 ha
->ic_all_size
=sizeof(dp6_ptr
->u
); 982 /* special command to controller BIOS */ 983 gdth_writel(0x00, &dp6_ptr
->u
.ic
.S_Info
[0]); 984 gdth_writel(0x00, &dp6_ptr
->u
.ic
.S_Info
[1]); 985 gdth_writel(0x01, &dp6_ptr
->u
.ic
.S_Info
[2]); 986 gdth_writel(0x00, &dp6_ptr
->u
.ic
.S_Info
[3]); 987 gdth_writeb(0xfe, &dp6_ptr
->u
.ic
.S_Cmd_Indx
); 988 gdth_writeb(0, &dp6_ptr
->io
.event
); 989 retries
= INIT_RETRIES
; 991 while(gdth_readb(&dp6_ptr
->u
.ic
.S_Status
) !=0xfe) { 993 printk("GDT-PCI: Initialization error\n"); 994 gdth_munmap(ha
->brd
); 999 gdth_writeb(0, &dp6_ptr
->u
.ic
.S_Status
); 1000 gdth_writeb(0xff, &dp6_ptr
->io
.irqdel
); 1002 }else if(ha
->stype
<= PCI_DEVICE_ID_VORTEX_GDT6555
) {/* GDT6110, ... */ 1003 ha
->plx
= (gdt6c_plx_regs
*)pcistr
->io
; 1004 TRACE2(("init_pci_new() dpmem %lx irq %d\n", 1005 pcistr
->dpmem
,ha
->irq
)); 1006 ha
->brd
=gdth_mmap(pcistr
->dpmem
,sizeof(gdt6c_dpram_str
)); 1007 if(ha
->brd
== NULL
) { 1008 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1009 gdth_munmap(ha
->brd
); 1012 dp6c_ptr
= (gdt6c_dpram_str
*)ha
->brd
; 1013 /* reset interface area */ 1014 memset_io((char*)&dp6c_ptr
->u
,0,sizeof(dp6c_ptr
->u
)); 1015 if(gdth_readl(&dp6c_ptr
->u
) !=0) { 1016 printk("GDT-PCI: Initialization error (DPMEM write error)\n"); 1017 gdth_munmap(ha
->brd
); 1021 /* disable board interrupts, deinit services */ 1022 outb(0x00,PTR2USHORT(&ha
->plx
->control1
)); 1023 outb(0xff,PTR2USHORT(&ha
->plx
->edoor_reg
)); 1025 gdth_writeb(0x00, &dp6c_ptr
->u
.ic
.S_Status
); 1026 gdth_writeb(0x00, &dp6c_ptr
->u
.ic
.Cmd_Index
); 1028 gdth_writel(pcistr
->dpmem
, &dp6c_ptr
->u
.ic
.S_Info
[0]); 1029 gdth_writeb(0xff, &dp6c_ptr
->u
.ic
.S_Cmd_Indx
); 1031 outb(1,PTR2USHORT(&ha
->plx
->ldoor_reg
)); 1033 retries
= INIT_RETRIES
; 1035 while(gdth_readb(&dp6c_ptr
->u
.ic
.S_Status
) !=0xff) { 1037 printk("GDT-PCI: Initialization error (DEINIT failed)\n"); 1038 gdth_munmap(ha
->brd
); 1043 prot_ver
= (unchar
)gdth_readl(&dp6c_ptr
->u
.ic
.S_Info
[0]); 1044 gdth_writeb(0, &dp6c_ptr
->u
.ic
.Status
); 1045 if(prot_ver
!= PROTOCOL_VERSION
) { 1046 printk("GDT-PCI: Illegal protocol version\n"); 1047 gdth_munmap(ha
->brd
); 1051 ha
->type
= GDT_PCINEW
; 1052 ha
->ic_all_size
=sizeof(dp6c_ptr
->u
); 1054 /* special command to controller BIOS */ 1055 gdth_writel(0x00, &dp6c_ptr
->u
.ic
.S_Info
[0]); 1056 gdth_writel(0x00, &dp6c_ptr
->u
.ic
.S_Info
[1]); 1057 gdth_writel(0x01, &dp6c_ptr
->u
.ic
.S_Info
[2]); 1058 gdth_writel(0x00, &dp6c_ptr
->u
.ic
.S_Info
[3]); 1059 gdth_writeb(0xfe, &dp6c_ptr
->u
.ic
.S_Cmd_Indx
); 1061 outb(1,PTR2USHORT(&ha
->plx
->ldoor_reg
)); 1063 retries
= INIT_RETRIES
; 1065 while(gdth_readb(&dp6c_ptr
->u
.ic
.S_Status
) !=0xfe) { 1067 printk("GDT-PCI: Initialization error\n"); 1068 gdth_munmap(ha
->brd
); 1073 gdth_writeb(0, &dp6c_ptr
->u
.ic
.S_Status
); 1076 TRACE2(("init_pci_mpr() dpmem %lx irq %d\n",pcistr
->dpmem
,ha
->irq
)); 1077 ha
->brd
=gdth_mmap(pcistr
->dpmem
,sizeof(gdt6m_dpram_str
)); 1078 if(ha
->brd
== NULL
) { 1079 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1083 /* check and reset interface area */ 1084 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
; 1085 gdth_writel(DPMEM_MAGIC
, &dp6m_ptr
->u
); 1086 if(gdth_readl(&dp6m_ptr
->u
) != DPMEM_MAGIC
) { 1087 printk("GDT-PCI: Cannot access DPMEM at 0x%x (shadowed?)\n", 1088 (int)pcistr
->dpmem
); 1090 for(i
=0xC8000; i
<0xE8000; i
+=0x4000) { 1091 gdth_munmap(ha
->brd
); 1092 ha
->brd
=gdth_mmap(i
,sizeof(ushort
)); 1093 if(ha
->brd
== NULL
) { 1094 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1097 if(gdth_readw(ha
->brd
) !=0xffff) { 1098 TRACE2(("init_pci_mpr() address 0x%x busy\n", i
)); 1101 gdth_munmap(ha
->brd
); 1102 #if LINUX_VERSION_CODE >= 0x2015C 1103 pci_write_config_dword(pcistr
->pdev
, 1104 PCI_BASE_ADDRESS_0
, i
); 1106 pcibios_write_config_dword(pcistr
->bus
, pcistr
->device_fn
, 1107 PCI_BASE_ADDRESS_0
, i
); 1109 ha
->brd
=gdth_mmap(i
,sizeof(gdt6m_dpram_str
)); 1110 if(ha
->brd
== NULL
) { 1111 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1114 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
; 1115 gdth_writel(DPMEM_MAGIC
, &dp6m_ptr
->u
); 1116 if(gdth_readl(&dp6m_ptr
->u
) == DPMEM_MAGIC
) { 1117 printk("GDT-PCI: Use free address at 0x%x\n", i
); 1123 printk("GDT-PCI: No free address found!\n"); 1124 gdth_munmap(ha
->brd
); 1128 memset_io((char*)&dp6m_ptr
->u
,0,sizeof(dp6m_ptr
->u
)); 1130 /* disable board interrupts, deinit services */ 1131 gdth_writeb(gdth_readb(&dp6m_ptr
->i960r
.edoor_en_reg
) |4, 1132 &dp6m_ptr
->i960r
.edoor_en_reg
); 1133 gdth_writeb(0xff, &dp6m_ptr
->i960r
.edoor_reg
); 1134 gdth_writeb(0x00, &dp6m_ptr
->u
.ic
.S_Status
); 1135 gdth_writeb(0x00, &dp6m_ptr
->u
.ic
.Cmd_Index
); 1137 gdth_writel(pcistr
->dpmem
, &dp6m_ptr
->u
.ic
.S_Info
[0]); 1138 gdth_writeb(0xff, &dp6m_ptr
->u
.ic
.S_Cmd_Indx
); 1139 gdth_writeb(1, &dp6m_ptr
->i960r
.ldoor_reg
); 1140 retries
= INIT_RETRIES
; 1142 while(gdth_readb(&dp6m_ptr
->u
.ic
.S_Status
) !=0xff) { 1144 printk("GDT-PCI: Initialization error (DEINIT failed)\n"); 1145 gdth_munmap(ha
->brd
); 1150 prot_ver
= (unchar
)gdth_readl(&dp6m_ptr
->u
.ic
.S_Info
[0]); 1151 gdth_writeb(0, &dp6m_ptr
->u
.ic
.S_Status
); 1152 if(prot_ver
!= PROTOCOL_VERSION
) { 1153 printk("GDT-PCI: Illegal protocol version\n"); 1154 gdth_munmap(ha
->brd
); 1158 ha
->type
= GDT_PCIMPR
; 1159 ha
->ic_all_size
=sizeof(dp6m_ptr
->u
); 1161 /* special command to controller BIOS */ 1162 gdth_writel(0x00, &dp6m_ptr
->u
.ic
.S_Info
[0]); 1163 gdth_writel(0x00, &dp6m_ptr
->u
.ic
.S_Info
[1]); 1164 gdth_writel(0x01, &dp6m_ptr
->u
.ic
.S_Info
[2]); 1165 gdth_writel(0x00, &dp6m_ptr
->u
.ic
.S_Info
[3]); 1166 gdth_writeb(0xfe, &dp6m_ptr
->u
.ic
.S_Cmd_Indx
); 1167 gdth_writeb(1, &dp6m_ptr
->i960r
.ldoor_reg
); 1168 retries
= INIT_RETRIES
; 1170 while(gdth_readb(&dp6m_ptr
->u
.ic
.S_Status
) !=0xfe) { 1172 printk("GDT-PCI: Initialization error\n"); 1173 gdth_munmap(ha
->brd
); 1178 gdth_writeb(0, &dp6m_ptr
->u
.ic
.S_Status
); 1185 /* controller protocol functions */ 1187 static void __init
gdth_enable_int(int hanum
) 1191 gdt2_dpram_str
*dp2_ptr
; 1192 gdt6_dpram_str
*dp6_ptr
; 1193 gdt6m_dpram_str
*dp6m_ptr
; 1195 TRACE(("gdth_enable_int() hanum %d\n",hanum
)); 1196 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1197 GDTH_LOCK_HA(ha
, flags
); 1199 if(ha
->type
== GDT_EISA
) { 1200 outb(0xff, ha
->bmic
+ EDOORREG
); 1201 outb(0xff, ha
->bmic
+ EDENABREG
); 1202 outb(0x01, ha
->bmic
+ EINTENABREG
); 1203 }else if(ha
->type
== GDT_ISA
) { 1204 dp2_ptr
= (gdt2_dpram_str
*)ha
->brd
; 1205 gdth_writeb(1, &dp2_ptr
->io
.irqdel
); 1206 gdth_writeb(0, &dp2_ptr
->u
.ic
.Cmd_Index
); 1207 gdth_writeb(1, &dp2_ptr
->io
.irqen
); 1208 }else if(ha
->type
== GDT_PCI
) { 1209 dp6_ptr
= (gdt6_dpram_str
*)ha
->brd
; 1210 gdth_writeb(1, &dp6_ptr
->io
.irqdel
); 1211 gdth_writeb(0, &dp6_ptr
->u
.ic
.Cmd_Index
); 1212 gdth_writeb(1, &dp6_ptr
->io
.irqen
); 1213 }else if(ha
->type
== GDT_PCINEW
) { 1214 outb(0xff,PTR2USHORT(&ha
->plx
->edoor_reg
)); 1215 outb(0x03,PTR2USHORT(&ha
->plx
->control1
)); 1216 }else if(ha
->type
== GDT_PCIMPR
) { 1217 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
; 1218 gdth_writeb(0xff, &dp6m_ptr
->i960r
.edoor_reg
); 1219 gdth_writeb(gdth_readb(&dp6m_ptr
->i960r
.edoor_en_reg
) & ~4, 1220 &dp6m_ptr
->i960r
.edoor_en_reg
); 1222 GDTH_UNLOCK_HA(ha
, flags
); 1226 static intgdth_get_status(unchar
*pIStatus
,int irq
) 1228 register gdth_ha_str
*ha
; 1231 TRACE(("gdth_get_status() irq %d ctr_count %d\n", 1232 irq
,gdth_ctr_count
)); 1235 for(i
=0; i
<gdth_ctr_count
; ++i
) { 1236 ha
=HADATA(gdth_ctr_tab
[i
]); 1237 if(ha
->irq
!= (unchar
)irq
)/* check IRQ */ 1239 if(ha
->type
== GDT_EISA
) 1240 *pIStatus
=inb((ushort
)ha
->bmic
+ EDOORREG
); 1241 else if(ha
->type
== GDT_ISA
) 1243 gdth_readb(&((gdt2_dpram_str
*)ha
->brd
)->u
.ic
.Cmd_Index
); 1244 else if(ha
->type
== GDT_PCI
) 1246 gdth_readb(&((gdt6_dpram_str
*)ha
->brd
)->u
.ic
.Cmd_Index
); 1247 else if(ha
->type
== GDT_PCINEW
) 1248 *pIStatus
=inb(PTR2USHORT(&ha
->plx
->edoor_reg
)); 1249 else if(ha
->type
== GDT_PCIMPR
) 1251 gdth_readb(&((gdt6m_dpram_str
*)ha
->brd
)->i960r
.edoor_reg
); 1254 return i
;/* board found */ 1260 static intgdth_test_busy(int hanum
) 1262 register gdth_ha_str
*ha
; 1263 registerint gdtsema0
=0; 1265 TRACE(("gdth_test_busy() hanum %d\n",hanum
)); 1267 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1268 if(ha
->type
== GDT_EISA
) 1269 gdtsema0
= (int)inb(ha
->bmic
+ SEMA0REG
); 1270 else if(ha
->type
== GDT_ISA
) 1271 gdtsema0
= (int)gdth_readb(&((gdt2_dpram_str
*)ha
->brd
)->u
.ic
.Sema0
); 1272 else if(ha
->type
== GDT_PCI
) 1273 gdtsema0
= (int)gdth_readb(&((gdt6_dpram_str
*)ha
->brd
)->u
.ic
.Sema0
); 1274 else if(ha
->type
== GDT_PCINEW
) 1275 gdtsema0
= (int)inb(PTR2USHORT(&ha
->plx
->sema0_reg
)); 1276 else if(ha
->type
== GDT_PCIMPR
) 1278 (int)gdth_readb(&((gdt6m_dpram_str
*)ha
->brd
)->i960r
.sema0_reg
); 1280 return(gdtsema0
&1); 1284 static intgdth_get_cmd_index(int hanum
) 1286 register gdth_ha_str
*ha
; 1289 TRACE(("gdth_get_cmd_index() hanum %d\n",hanum
)); 1291 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1292 for(i
=0; i
<GDTH_MAXCMDS
; ++i
) { 1293 if(ha
->cmd_tab
[i
].cmnd
== UNUSED_CMND
) { 1294 ha
->cmd_tab
[i
].cmnd
= ha
->pccb
->RequestBuffer
; 1295 ha
->cmd_tab
[i
].service
= ha
->pccb
->Service
; 1296 ha
->pccb
->CommandIndex
= (ulong32
)i
+2; 1304 static voidgdth_set_sema0(int hanum
) 1306 register gdth_ha_str
*ha
; 1308 TRACE(("gdth_set_sema0() hanum %d\n",hanum
)); 1310 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1311 if(ha
->type
== GDT_EISA
) { 1312 outb(1, ha
->bmic
+ SEMA0REG
); 1313 }else if(ha
->type
== GDT_ISA
) { 1314 gdth_writeb(1, &((gdt2_dpram_str
*)ha
->brd
)->u
.ic
.Sema0
); 1315 }else if(ha
->type
== GDT_PCI
) { 1316 gdth_writeb(1, &((gdt6_dpram_str
*)ha
->brd
)->u
.ic
.Sema0
); 1317 }else if(ha
->type
== GDT_PCINEW
) { 1318 outb(1,PTR2USHORT(&ha
->plx
->sema0_reg
)); 1319 }else if(ha
->type
== GDT_PCIMPR
) { 1320 gdth_writeb(1, &((gdt6m_dpram_str
*)ha
->brd
)->i960r
.sema0_reg
); 1325 static voidgdth_copy_command(int hanum
) 1327 register gdth_ha_str
*ha
; 1328 register gdth_cmd_str
*cmd_ptr
; 1329 register gdt6m_dpram_str
*dp6m_ptr
; 1330 register gdt6c_dpram_str
*dp6c_ptr
; 1331 gdt6_dpram_str
*dp6_ptr
; 1332 gdt2_dpram_str
*dp2_ptr
; 1333 ushort cp_count
,dp_offset
,cmd_no
; 1335 TRACE(("gdth_copy_command() hanum %d\n",hanum
)); 1337 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1338 cp_count
= ha
->cmd_len
; 1339 dp_offset
= ha
->cmd_offs_dpmem
; 1340 cmd_no
= ha
->cmd_cnt
; 1344 if(ha
->type
== GDT_EISA
) 1345 return;/* no DPMEM, no copy */ 1347 /* set cpcount dword aligned */ 1349 cp_count
+= (4- (cp_count
&3)); 1351 ha
->cmd_offs_dpmem
+= cp_count
; 1353 /* set offset and service, copy command to DPMEM */ 1354 if(ha
->type
== GDT_ISA
) { 1355 dp2_ptr
= (gdt2_dpram_str
*)ha
->brd
; 1356 gdth_writew(dp_offset
+ DPMEM_COMMAND_OFFSET
, 1357 &dp2_ptr
->u
.ic
.comm_queue
[cmd_no
].offset
); 1358 gdth_writew((ushort
)cmd_ptr
->Service
, 1359 &dp2_ptr
->u
.ic
.comm_queue
[cmd_no
].serv_id
); 1360 memcpy_toio(&dp2_ptr
->u
.ic
.gdt_dpr_cmd
[dp_offset
],cmd_ptr
,cp_count
); 1361 }else if(ha
->type
== GDT_PCI
) { 1362 dp6_ptr
= (gdt6_dpram_str
*)ha
->brd
; 1363 gdth_writew(dp_offset
+ DPMEM_COMMAND_OFFSET
, 1364 &dp6_ptr
->u
.ic
.comm_queue
[cmd_no
].offset
); 1365 gdth_writew((ushort
)cmd_ptr
->Service
, 1366 &dp6_ptr
->u
.ic
.comm_queue
[cmd_no
].serv_id
); 1367 memcpy_toio(&dp6_ptr
->u
.ic
.gdt_dpr_cmd
[dp_offset
],cmd_ptr
,cp_count
); 1368 }else if(ha
->type
== GDT_PCINEW
) { 1369 dp6c_ptr
= (gdt6c_dpram_str
*)ha
->brd
; 1370 gdth_writew(dp_offset
+ DPMEM_COMMAND_OFFSET
, 1371 &dp6c_ptr
->u
.ic
.comm_queue
[cmd_no
].offset
); 1372 gdth_writew((ushort
)cmd_ptr
->Service
, 1373 &dp6c_ptr
->u
.ic
.comm_queue
[cmd_no
].serv_id
); 1374 memcpy_toio(&dp6c_ptr
->u
.ic
.gdt_dpr_cmd
[dp_offset
],cmd_ptr
,cp_count
); 1375 }else if(ha
->type
== GDT_PCIMPR
) { 1376 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
; 1377 gdth_writew(dp_offset
+ DPMEM_COMMAND_OFFSET
, 1378 &dp6m_ptr
->u
.ic
.comm_queue
[cmd_no
].offset
); 1379 gdth_writew((ushort
)cmd_ptr
->Service
, 1380 &dp6m_ptr
->u
.ic
.comm_queue
[cmd_no
].serv_id
); 1381 memcpy_toio(&dp6m_ptr
->u
.ic
.gdt_dpr_cmd
[dp_offset
],cmd_ptr
,cp_count
); 1386 static voidgdth_release_event(int hanum
) 1388 register gdth_ha_str
*ha
; 1390 TRACE(("gdth_release_event() hanum %d\n",hanum
)); 1391 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1393 #ifdef GDTH_STATISTICS 1396 for(i
=0,j
=0; j
<GDTH_MAXCMDS
; ++j
) { 1397 if(ha
->cmd_tab
[j
].cmnd
!= UNUSED_CMND
) 1402 TRACE3(("GDT: max_index = %d\n",(ushort
)i
)); 1407 if(ha
->pccb
->OpCode
== GDT_INIT
) 1408 ha
->pccb
->Service
|=0x80; 1410 if(ha
->type
== GDT_EISA
) { 1411 if(ha
->pccb
->OpCode
== GDT_INIT
)/* store DMA buffer */ 1412 outl(virt_to_bus(ha
->pccb
), ha
->bmic
+ MAILBOXREG
); 1413 outb(ha
->pccb
->Service
, ha
->bmic
+ LDOORREG
); 1414 }else if(ha
->type
== GDT_ISA
) { 1415 gdth_writeb(0, &((gdt2_dpram_str
*)ha
->brd
)->io
.event
); 1416 }else if(ha
->type
== GDT_PCI
) { 1417 gdth_writeb(0, &((gdt6_dpram_str
*)ha
->brd
)->io
.event
); 1418 }else if(ha
->type
== GDT_PCINEW
) { 1419 outb(1,PTR2USHORT(&ha
->plx
->ldoor_reg
)); 1420 }else if(ha
->type
== GDT_PCIMPR
) { 1421 gdth_writeb(1, &((gdt6m_dpram_str
*)ha
->brd
)->i960r
.ldoor_reg
); 1426 static intgdth_wait(int hanum
,int index
,ulong32 time
) 1429 int answer_found
= FALSE
; 1431 TRACE(("gdth_wait() hanum %d index %d time %d\n",hanum
,index
,time
)); 1433 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1435 return1;/* no wait required */ 1437 gdth_from_wait
= TRUE
; 1439 #if LINUX_VERSION_CODE >= 0x010346 1440 gdth_interrupt((int)ha
->irq
,ha
,NULL
); 1442 gdth_interrupt((int)ha
->irq
,NULL
); 1444 if(wait_hanum
==hanum
&& wait_index
==index
) { 1445 answer_found
= TRUE
; 1450 gdth_from_wait
= FALSE
; 1452 while(gdth_test_busy(hanum
)) 1455 return(answer_found
); 1459 static intgdth_internal_cmd(int hanum
,unchar service
,ushort opcode
,ulong32 p1
, 1460 ulong32 p2
,ulong32 p3
) 1462 register gdth_ha_str
*ha
; 1463 register gdth_cmd_str
*cmd_ptr
; 1466 TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service
,opcode
)); 1468 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1470 memset((char*)cmd_ptr
,0,sizeof(gdth_cmd_str
)); 1473 for(retries
= INIT_RETRIES
;;) { 1474 cmd_ptr
->Service
= service
; 1475 cmd_ptr
->RequestBuffer
= INTERNAL_CMND
; 1476 if(!(index
=gdth_get_cmd_index(hanum
))) { 1477 TRACE(("GDT: No free command index found\n")); 1480 gdth_set_sema0(hanum
); 1481 cmd_ptr
->OpCode
= opcode
; 1482 cmd_ptr
->BoardNode
= LOCALBOARD
; 1483 if(service
== CACHESERVICE
) { 1484 if(opcode
== GDT_IOCTL
) { 1485 cmd_ptr
->u
.ioctl
.subfunc
= p1
; 1486 cmd_ptr
->u
.ioctl
.channel
= p2
; 1487 cmd_ptr
->u
.ioctl
.param_size
= (ushort
)p3
; 1488 cmd_ptr
->u
.ioctl
.p_param
=virt_to_bus(ha
->pscratch
); 1490 cmd_ptr
->u
.cache
.DeviceNo
= (ushort
)p1
; 1491 cmd_ptr
->u
.cache
.BlockNo
= p2
; 1493 }else if(service
== SCSIRAWSERVICE
) { 1494 cmd_ptr
->u
.raw
.direction
= p1
; 1495 cmd_ptr
->u
.raw
.bus
= (unchar
)p2
; 1496 cmd_ptr
->u
.raw
.target
= (unchar
)p3
; 1497 cmd_ptr
->u
.raw
.lun
= (unchar
)(p3
>>8); 1499 ha
->cmd_len
=sizeof(gdth_cmd_str
); 1500 ha
->cmd_offs_dpmem
=0; 1502 gdth_copy_command(hanum
); 1503 gdth_release_event(hanum
); 1505 if(!gdth_wait(hanum
,index
,INIT_TIMEOUT
)) { 1506 printk("GDT: Initialization error (timeout service %d)\n",service
); 1509 if(ha
->status
!= S_BSY
|| --retries
==0) 1514 return(ha
->status
!= S_OK
?0:1); 1518 /* search for devices */ 1520 static int __init
gdth_search_drives(int hanum
) 1522 register gdth_ha_str
*ha
; 1524 int drv_cyls
, drv_hds
, drv_secs
; 1526 ulong32 drv_cnt
, drv_no
, j
; 1527 gdth_getch_str
*chn
; 1528 gdth_drlist_str
*drl
; 1529 gdth_iochan_str
*ioc
; 1530 gdth_raw_iochan_str
*iocr
; 1531 gdth_arraylist_str
*alst
; 1533 TRACE(("gdth_search_drives() hanum %d\n",hanum
)); 1534 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1536 /* initialize controller services, at first: screen service */ 1537 if(!gdth_internal_cmd(hanum
,SCREENSERVICE
,GDT_INIT
,0,0,0)) { 1538 printk("GDT: Initialization error screen service (code %d)\n", 1542 TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n")); 1544 /* initialize cache service */ 1545 if(!gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_INIT
,LINUX_OS
,0,0)) { 1546 printk("GDT: Initialization error cache service (code %d)\n", 1550 TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n")); 1551 cdev_cnt
= (ushort
)ha
->info
; 1553 /* mount all cache devices */ 1554 gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_MOUNT
,0xffff,1,0); 1555 TRACE2(("gdth_search_drives(): mountall CACHESERVICE OK\n")); 1557 /* initialize cache service after mountall */ 1558 if(!gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_INIT
,LINUX_OS
,0,0)) { 1559 printk("GDT: Initialization error cache service (code %d)\n", 1563 TRACE2(("gdth_search_drives() CACHES. init. after mountall\n")); 1564 cdev_cnt
= (ushort
)ha
->info
; 1566 /* detect number of buses - try new IOCTL */ 1567 iocr
= (gdth_raw_iochan_str
*)ha
->pscratch
; 1568 iocr
->hdr
.version
=0xffffffff; 1569 iocr
->hdr
.list_entries
= MAXBUS
; 1570 iocr
->hdr
.first_chan
=0; 1571 iocr
->hdr
.last_chan
= MAXBUS
-1; 1572 iocr
->hdr
.list_offset
=GDTOFFSOF(gdth_raw_iochan_str
, list
[0]); 1573 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,IOCHAN_RAW_DESC
, 1574 INVALID_CHANNEL
,sizeof(gdth_raw_iochan_str
))) { 1575 TRACE2(("IOCHAN_RAW_DESC supported!\n")); 1576 ha
->bus_cnt
= iocr
->hdr
.chan_count
; 1577 for(bus_no
=0; bus_no
< ha
->bus_cnt
; ++bus_no
) { 1578 if(iocr
->list
[bus_no
].proc_id
< MAXID
) 1579 ha
->bus_id
[bus_no
] = iocr
->list
[bus_no
].proc_id
; 1581 ha
->bus_id
[bus_no
] =0xff; 1585 chn
= (gdth_getch_str
*)ha
->pscratch
; 1586 for(bus_no
=0; bus_no
< MAXBUS
; ++bus_no
) { 1587 chn
->channel_no
= bus_no
; 1588 if(!gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
, 1589 SCSI_CHAN_CNT
| L_CTRL_PATTERN
, 1590 IO_CHANNEL
| INVALID_CHANNEL
, 1591 sizeof(gdth_getch_str
))) { 1593 printk("GDT: Error detecting channel count (0x%x)\n", 1599 if(chn
->siop_id
< MAXID
) 1600 ha
->bus_id
[bus_no
] = chn
->siop_id
; 1602 ha
->bus_id
[bus_no
] =0xff; 1604 ha
->bus_cnt
= (unchar
)bus_no
; 1606 TRACE2(("gdth_search_drives() %d channels\n",ha
->bus_cnt
)); 1608 /* read cache configuration */ 1609 if(!gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,CACHE_INFO
, 1610 INVALID_CHANNEL
,sizeof(gdth_cinfo_str
))) { 1611 printk("GDT: Initialization error cache service (code %d)\n", 1615 ha
->cpar
= ((gdth_cinfo_str
*)ha
->pscratch
)->cpar
; 1616 TRACE2(("gdth_search_drives() cinfo: vs %x sta %d str %d dw %d b %d\n", 1617 ha
->cpar
.version
,ha
->cpar
.state
,ha
->cpar
.strategy
, 1618 ha
->cpar
.write_back
,ha
->cpar
.block_size
)); 1620 /* read board info and features */ 1621 ha
->more_proc
= FALSE
; 1622 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,BOARD_INFO
, 1623 INVALID_CHANNEL
,sizeof(gdth_binfo_str
))) { 1624 ha
->binfo
= *(gdth_binfo_str
*)ha
->pscratch
; 1625 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,BOARD_FEATURES
, 1626 INVALID_CHANNEL
,sizeof(gdth_bfeat_str
))) { 1627 TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n")); 1628 ha
->bfeat
= *(gdth_bfeat_str
*)ha
->pscratch
; 1629 ha
->more_proc
= TRUE
; 1632 TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n")); 1633 strcpy(ha
->binfo
.type_string
,gdth_ctr_name(hanum
)); 1635 TRACE2(("Controller name: %s\n",ha
->binfo
.type_string
)); 1637 /* read more informations */ 1639 /* physical drives, channel addresses */ 1640 ioc
= (gdth_iochan_str
*)ha
->pscratch
; 1641 ioc
->hdr
.version
=0xffffffff; 1642 ioc
->hdr
.list_entries
= MAXBUS
; 1643 ioc
->hdr
.first_chan
=0; 1644 ioc
->hdr
.last_chan
= MAXBUS
-1; 1645 ioc
->hdr
.list_offset
=GDTOFFSOF(gdth_iochan_str
, list
[0]); 1646 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,IOCHAN_DESC
, 1647 INVALID_CHANNEL
,sizeof(gdth_iochan_str
))) { 1648 for(bus_no
=0; bus_no
< ha
->bus_cnt
; ++bus_no
) { 1649 ha
->raw
[bus_no
].address
= ioc
->list
[bus_no
].address
; 1650 ha
->raw
[bus_no
].local_no
= ioc
->list
[bus_no
].local_no
; 1653 for(bus_no
=0; bus_no
< ha
->bus_cnt
; ++bus_no
) { 1654 ha
->raw
[bus_no
].address
= IO_CHANNEL
; 1655 ha
->raw
[bus_no
].local_no
= bus_no
; 1658 for(bus_no
=0; bus_no
< ha
->bus_cnt
; ++bus_no
) { 1659 chn
= (gdth_getch_str
*)ha
->pscratch
; 1660 chn
->channel_no
= ha
->raw
[bus_no
].local_no
; 1661 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
, 1662 SCSI_CHAN_CNT
| L_CTRL_PATTERN
, 1663 ha
->raw
[bus_no
].address
| INVALID_CHANNEL
, 1664 sizeof(gdth_getch_str
))) { 1665 ha
->raw
[bus_no
].pdev_cnt
= chn
->drive_cnt
; 1666 TRACE2(("Channel %d: %d phys. drives\n", 1667 bus_no
,chn
->drive_cnt
)); 1669 if(ha
->raw
[bus_no
].pdev_cnt
>0) { 1670 drl
= (gdth_drlist_str
*)ha
->pscratch
; 1671 drl
->sc_no
= ha
->raw
[bus_no
].local_no
; 1672 drl
->sc_cnt
= ha
->raw
[bus_no
].pdev_cnt
; 1673 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
, 1674 SCSI_DR_LIST
| L_CTRL_PATTERN
, 1675 ha
->raw
[bus_no
].address
| INVALID_CHANNEL
, 1676 sizeof(gdth_drlist_str
))) { 1677 for(j
=0; j
< ha
->raw
[bus_no
].pdev_cnt
; ++j
) 1678 ha
->raw
[bus_no
].id_list
[j
] = drl
->sc_list
[j
]; 1680 ha
->raw
[bus_no
].pdev_cnt
=0; 1685 /* logical drives */ 1686 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,CACHE_DRV_CNT
, 1687 INVALID_CHANNEL
,sizeof(ulong32
))) { 1688 drv_cnt
= *(ulong32
*)ha
->pscratch
; 1689 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
,CACHE_DRV_LIST
, 1690 INVALID_CHANNEL
,drv_cnt
*sizeof(ulong32
))) { 1691 for(j
=0; j
< drv_cnt
; ++j
) { 1692 drv_no
= ((ulong32
*)ha
->pscratch
)[j
]; 1693 if(drv_no
< MAX_HDRIVES
) { 1694 ha
->hdr
[drv_no
].is_logdrv
= TRUE
; 1695 TRACE2(("Drive %d is log. drive\n",drv_no
)); 1699 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_IOCTL
, 1700 ARRAY_DRV_LIST
| LA_CTRL_PATTERN
, 1701 0,35*sizeof(gdth_arraylist_str
))) { 1702 for(j
=0; j
<35; ++j
) { 1703 alst
= &((gdth_arraylist_str
*)ha
->pscratch
)[j
]; 1704 ha
->hdr
[j
].is_arraydrv
= alst
->is_arrayd
; 1705 ha
->hdr
[j
].is_master
= alst
->is_master
; 1706 ha
->hdr
[j
].is_parity
= alst
->is_parity
; 1707 ha
->hdr
[j
].is_hotfix
= alst
->is_hotfix
; 1708 ha
->hdr
[j
].master_no
= alst
->cd_handle
; 1714 /* initialize raw service */ 1715 if(!gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_INIT
,0,0,0)) { 1716 printk("GDT: Initialization error raw service (code %d)\n", 1720 TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n")); 1722 /* set/get features raw service (scatter/gather) */ 1724 if(gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_SET_FEAT
,SCATTER_GATHER
, 1726 TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n")); 1727 if(gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_GET_FEAT
,0,0,0)) { 1728 TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n", 1730 ha
->raw_feat
= (ushort
)ha
->info
; 1734 /* set/get features cache service (equal to raw service) */ 1735 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_SET_FEAT
,0, 1736 SCATTER_GATHER
,0)) { 1737 TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n")); 1738 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_GET_FEAT
,0,0,0)) { 1739 TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n", 1741 ha
->cache_feat
= (ushort
)ha
->info
; 1745 /* reserve drives for raw service */ 1746 if(reserve_mode
!=0) { 1747 gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_RESERVE_ALL
, 1748 reserve_mode
==1?1:3,0,0); 1749 TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", 1752 for(i
=0; i
< MAX_RES_ARGS
; i
+=4) { 1753 if(reserve_list
[i
] == hanum
&& reserve_list
[i
+1] < ha
->bus_cnt
&& 1754 reserve_list
[i
+2] < ha
->tid_cnt
&& reserve_list
[i
+3] < MAXLUN
) { 1755 TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n", 1756 reserve_list
[i
], reserve_list
[i
+1], 1757 reserve_list
[i
+2], reserve_list
[i
+3])); 1758 if(!gdth_internal_cmd(hanum
,SCSIRAWSERVICE
,GDT_RESERVE
,0, 1759 reserve_list
[i
+1], reserve_list
[i
+2] | 1760 (reserve_list
[i
+3] <<8))) { 1761 printk("GDT: Error raw service (RESERVE, code %d)\n", 1767 /* scanning for cache devices */ 1768 for(i
=0; i
<cdev_cnt
&& i
<MAX_HDRIVES
; ++i
) { 1769 TRACE(("gdth_search_drives() cachedev. %d\n",i
)); 1770 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_INFO
,i
,0,0)) { 1771 /* static relation between host drive number and Bus/ID */ 1772 TRACE(("gdth_search_dr() drive %d mapped to bus/id %d/%d\n", 1775 ha
->hdr
[i
].present
= TRUE
; 1776 ha
->hdr
[i
].size
= ha
->info
; 1778 /* evaluate mapping (sectors per head, heads per cylinder) */ 1779 ha
->hdr
[i
].size
&= ~SECS32
; 1781 gdth_eval_mapping(ha
->hdr
[i
].size
,&drv_cyls
,&drv_hds
,&drv_secs
); 1783 drv_hds
= ha
->info2
&0xff; 1784 drv_secs
= (ha
->info2
>>8) &0xff; 1785 drv_cyls
= ha
->hdr
[i
].size
/drv_hds
/drv_secs
; 1787 ha
->hdr
[i
].heads
= (unchar
)drv_hds
; 1788 ha
->hdr
[i
].secs
= (unchar
)drv_secs
; 1790 ha
->hdr
[i
].size
= drv_cyls
* drv_hds
* drv_secs
; 1791 TRACE2(("gdth_search_dr() cdr. %d size %d hds %d scs %d\n", 1792 i
,ha
->hdr
[i
].size
,drv_hds
,drv_secs
)); 1794 /* get informations about device */ 1795 if(gdth_internal_cmd(hanum
,CACHESERVICE
,GDT_DEVTYPE
,i
, 1797 TRACE(("gdth_search_dr() cache drive %d devtype %d\n", 1799 ha
->hdr
[i
].devtype
= (ushort
)ha
->info
; 1804 TRACE(("gdth_search_drives() OK\n")); 1809 /* command queueing/sending functions */ 1811 static voidgdth_putq(int hanum
,Scsi_Cmnd
*scp
,unchar priority
) 1813 register gdth_ha_str
*ha
; 1814 register Scsi_Cmnd
*pscp
; 1815 register Scsi_Cmnd
*nscp
; 1819 TRACE(("gdth_putq() priority %d\n",priority
)); 1820 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1821 GDTH_LOCK_HA(ha
, flags
); 1823 scp
->SCp
.this_residual
= (int)priority
; 1824 #if LINUX_VERSION_CODE >= 0x020000 1827 b
=NUMDATA(nscp
->host
)->busnum
; 1830 #if LINUX_VERSION_CODE >= 0x010300 1831 if(priority
>= DEFAULT_PRI
) { 1832 if((b
!= ha
->virt_bus
&& ha
->raw
[BUS_L2P(ha
,b
)].lock
) || 1833 (b
== ha
->virt_bus
&& t
< MAX_HDRIVES
&& ha
->hdr
[t
].lock
)) { 1834 TRACE2(("gdth_putq(): locked IO -> update_timeout()\n")); 1835 scp
->SCp
.buffers_residual
=gdth_update_timeout(hanum
, scp
,0); 1840 if(ha
->req_first
==NULL
) { 1841 ha
->req_first
= scp
;/* queue was empty */ 1842 scp
->SCp
.ptr
= NULL
; 1843 }else{/* queue not empty */ 1844 pscp
= ha
->req_first
; 1845 nscp
= (Scsi_Cmnd
*)pscp
->SCp
.ptr
; 1846 /* priority: 0-highest,..,0xff-lowest */ 1847 while(nscp
&& (unchar
)nscp
->SCp
.this_residual
<= priority
) { 1849 nscp
= (Scsi_Cmnd
*)pscp
->SCp
.ptr
; 1851 pscp
->SCp
.ptr
= (char*)scp
; 1852 scp
->SCp
.ptr
= (char*)nscp
; 1854 GDTH_UNLOCK_HA(ha
, flags
); 1856 #ifdef GDTH_STATISTICS 1858 for(nscp
=ha
->req_first
; nscp
; nscp
=(Scsi_Cmnd
*)nscp
->SCp
.ptr
) 1860 if(max_rq
< flags
) { 1862 TRACE3(("GDT: max_rq = %d\n",(ushort
)max_rq
)); 1867 static voidgdth_next(int hanum
) 1869 register gdth_ha_str
*ha
; 1870 register Scsi_Cmnd
*pscp
; 1871 register Scsi_Cmnd
*nscp
; 1872 unchar b
, t
, firsttime
; 1873 unchar this_cmd
, next_cmd
; 1877 TRACE(("gdth_next() hanum %d\n",hanum
)); 1878 ha
=HADATA(gdth_ctr_tab
[hanum
]); 1879 GDTH_LOCK_HA(ha
, flags
); 1881 ha
->cmd_cnt
= ha
->cmd_offs_dpmem
=0; 1882 this_cmd
= firsttime
= TRUE
; 1883 next_cmd
= gdth_polling
? FALSE
:TRUE
; 1886 for(nscp
= pscp
= ha
->req_first
; nscp
; nscp
= (Scsi_Cmnd
*)nscp
->SCp
.ptr
) { 1887 if(nscp
!= pscp
&& nscp
!= (Scsi_Cmnd
*)pscp
->SCp
.ptr
) 1888 pscp
= (Scsi_Cmnd
*)pscp
->SCp
.ptr
; 1889 #if LINUX_VERSION_CODE >= 0x020000 1892 b
=NUMDATA(nscp
->host
)->busnum
; 1895 if(nscp
->SCp
.this_residual
>= DEFAULT_PRI
) { 1896 if((b
!= ha
->virt_bus
&& ha
->raw
[BUS_L2P(ha
,b
)].lock
) || 1897 (b
== ha
->virt_bus
&& t
< MAX_HDRIVES
&& ha
->hdr
[t
].lock
)) 1902 if(gdth_test_busy(hanum
)) {/* controller busy ? */ 1903 TRACE(("gdth_next() controller %d busy !\n",hanum
)); 1905 GDTH_UNLOCK_HA(ha
, flags
); 1908 while(gdth_test_busy(hanum
)) 1914 #if LINUX_VERSION_CODE >= 0x010300 1915 if(nscp
->done
!= gdth_scsi_done
) 1918 if(nscp
->SCp
.phase
== -1) { 1919 nscp
->SCp
.phase
= SCSIRAWSERVICE
;/* default: raw svc. */ 1920 if(nscp
->cmnd
[0] == TEST_UNIT_READY
) { 1921 TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", 1923 /* TEST_UNIT_READY -> set scan mode */ 1924 if((ha
->scan_mode
&0x0f) ==0) { 1925 if(b
==0&& t
==0&& nscp
->lun
==0) { 1927 TRACE2(("Scan mode: 0x%x\n", ha
->scan_mode
)); 1929 }else if((ha
->scan_mode
&0x0f) ==1) { 1930 if(b
==0&& ((t
==0&& nscp
->lun
==1) || 1931 (t
==1&& nscp
->lun
==0))) { 1932 nscp
->SCp
.Status
= GDT_SCAN_START
; 1933 nscp
->SCp
.phase
|= ((ha
->scan_mode
&0x10?1:0) <<8); 1934 ha
->scan_mode
=0x12; 1935 TRACE2(("Scan mode: 0x%x (SCAN_START)\n", 1938 ha
->scan_mode
&=0x10; 1939 TRACE2(("Scan mode: 0x%x\n", ha
->scan_mode
)); 1941 }else if(ha
->scan_mode
==0x12) { 1942 if(b
== ha
->bus_cnt
&& t
== ha
->tid_cnt
-1) { 1943 nscp
->SCp
.Status
= GDT_SCAN_END
; 1944 ha
->scan_mode
&=0x10; 1945 TRACE2(("Scan mode: 0x%x (SCAN_END)\n", 1953 if(nscp
->SCp
.Status
!= -1) { 1954 if((nscp
->SCp
.phase
&0xff) == SCSIRAWSERVICE
) { 1955 if(!(cmd_index
=gdth_fill_raw_cmd(hanum
,nscp
,BUS_L2P(ha
,b
)))) 1961 #if LINUX_VERSION_CODE >= 0x010300 1962 if(nscp
->done
== gdth_scsi_done
) { 1963 if(!(cmd_index
=gdth_special_cmd(hanum
,nscp
))) 1968 if(b
!= ha
->virt_bus
) { 1969 if(ha
->raw
[BUS_L2P(ha
,b
)].io_cnt
[t
] >= GDTH_MAX_RAW
|| 1970 !(cmd_index
=gdth_fill_raw_cmd(hanum
,nscp
,BUS_L2P(ha
,b
)))) 1973 ha
->raw
[BUS_L2P(ha
,b
)].io_cnt
[t
]++; 1974 }else if(t
>= MAX_HDRIVES
|| !ha
->hdr
[t
].present
|| nscp
->lun
!=0) { 1975 TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", 1976 nscp
->cmnd
[0], b
, t
, nscp
->lun
)); 1977 nscp
->result
= DID_BAD_TARGET
<<16; 1978 GDTH_UNLOCK_HA(ha
,flags
); 1979 /* io_request_lock already active ! */ 1980 nscp
->scsi_done(nscp
); 1981 GDTH_LOCK_HA(ha
,flags
); 1983 switch(nscp
->cmnd
[0]) { 1984 case TEST_UNIT_READY
: 1991 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp
->cmnd
[0], 1992 nscp
->cmnd
[1],nscp
->cmnd
[2],nscp
->cmnd
[3], 1993 nscp
->cmnd
[4],nscp
->cmnd
[5])); 1994 if(gdth_internal_cache_cmd(hanum
,nscp
)) { 1995 GDTH_UNLOCK_HA(ha
,flags
); 1996 /* io_request_lock already active ! */ 1997 nscp
->scsi_done(nscp
); 1998 GDTH_LOCK_HA(ha
,flags
); 2002 case ALLOW_MEDIUM_REMOVAL
: 2003 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp
->cmnd
[0], 2004 nscp
->cmnd
[1],nscp
->cmnd
[2],nscp
->cmnd
[3], 2005 nscp
->cmnd
[4],nscp
->cmnd
[5])); 2006 if( (nscp
->cmnd
[4]&1) && !(ha
->hdr
[t
].devtype
&1) ) { 2007 TRACE(("Prevent r. nonremov. drive->do nothing\n")); 2008 nscp
->result
= DID_OK
<<16; 2009 if(!nscp
->SCp
.have_data_in
) 2010 nscp
->SCp
.have_data_in
++; 2012 GDTH_UNLOCK_HA(ha
,flags
); 2013 /* io_request_lock already active ! */ 2014 nscp
->scsi_done(nscp
); 2015 GDTH_LOCK_HA(ha
,flags
); 2018 nscp
->cmnd
[3] = (ha
->hdr
[t
].devtype
&1) ?1:0; 2019 TRACE(("Prevent/allow r. %d rem. drive %d\n", 2020 nscp
->cmnd
[4],nscp
->cmnd
[3])); 2021 if(!(cmd_index
=gdth_fill_cache_cmd(hanum
,nscp
,t
))) 2030 if(!(cmd_index
=gdth_fill_cache_cmd(hanum
,nscp
,t
))) 2035 TRACE2(("cache cmd %x/%x/%x/%x/%x/%x unknown\n",nscp
->cmnd
[0], 2036 nscp
->cmnd
[1],nscp
->cmnd
[2],nscp
->cmnd
[3], 2037 nscp
->cmnd
[4],nscp
->cmnd
[5])); 2038 printk("GDT: Unknown SCSI command 0x%x to cache service !\n", 2040 nscp
->result
= DID_ABORT
<<16; 2041 if(!nscp
->SCp
.have_data_in
) 2042 nscp
->SCp
.have_data_in
++; 2044 GDTH_UNLOCK_HA(ha
,flags
); 2045 /* io_request_lock already active ! */ 2046 nscp
->scsi_done(nscp
); 2047 GDTH_LOCK_HA(ha
,flags
); 2055 if(nscp
== ha
->req_first
) 2056 ha
->req_first
= pscp
= (Scsi_Cmnd
*)nscp
->SCp
.ptr
; 2058 pscp
->SCp
.ptr
= nscp
->SCp
.ptr
; 2063 if(ha
->cmd_cnt
>0) { 2064 gdth_release_event(hanum
); 2067 GDTH_UNLOCK_HA(ha
, flags
); 2069 if(gdth_polling
&& ha
->cmd_cnt
>0) { 2070 if(!gdth_wait(hanum
,cmd_index
,POLL_TIMEOUT
)) 2071 printk("GDT: Controller %d: Command %d timed out !\n", 2076 static voidgdth_copy_internal_data(Scsi_Cmnd
*scp
,char*buffer
,ushort count
) 2080 struct scatterlist
*sl
; 2082 cpcount
= count
<=(ushort
)scp
->bufflen
? count
:(ushort
)scp
->bufflen
; 2084 sl
= (struct scatterlist
*)scp
->request_buffer
; 2085 for(i
=0,cpsum
=0; i
<scp
->use_sg
; ++i
,++sl
) { 2086 cpnow
= (ushort
)sl
->length
; 2087 TRACE(("copy_internal() now %d sum %d count %d %d\n", 2088 cpnow
,cpsum
,cpcount
,(ushort
)scp
->bufflen
)); 2089 if(cpsum
+cpnow
> cpcount
) 2090 cpnow
= cpcount
- cpsum
; 2092 memcpy((char*)sl
->address
,buffer
,cpnow
); 2093 if(cpsum
== cpcount
) 2098 TRACE(("copy_internal() count %d\n",cpcount
)); 2099 memcpy((char*)scp
->request_buffer
,buffer
,cpcount
); 2103 static intgdth_internal_cache_cmd(int hanum
,Scsi_Cmnd
*scp
) 2105 register gdth_ha_str
*ha
; 2108 gdth_rdcap_data rdc
; 2110 gdth_modep_data mpd
; 2112 ha
=HADATA(gdth_ctr_tab
[hanum
]); 2114 TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", 2117 switch(scp
->cmnd
[0]) { 2118 case TEST_UNIT_READY
: 2121 TRACE2(("Test/Verify/Start hdrive %d\n",t
)); 2125 TRACE2(("Inquiry hdrive %d devtype %d\n", 2126 t
,ha
->hdr
[t
].devtype
)); 2127 inq
.type_qual
= (ha
->hdr
[t
].devtype
&4) ? TYPE_ROM
:TYPE_DISK
; 2128 /* you can here set all disks to removable, if you want to do 2129 a flush using the ALLOW_MEDIUM_REMOVAL command */ 2130 inq
.modif_rmb
= ha
->hdr
[t
].devtype
&1?0x80:0x00; 2134 strcpy(inq
.vendor
,"ICP "); 2135 sprintf(inq
.product
,"Host Drive #%02d",t
); 2136 strcpy(inq
.revision
," "); 2137 gdth_copy_internal_data(scp
,(char*)&inq
,sizeof(gdth_inq_data
)); 2141 TRACE2(("Request sense hdrive %d\n",t
)); 2147 gdth_copy_internal_data(scp
,(char*)&sd
,sizeof(gdth_sense_data
)); 2151 TRACE2(("Mode sense hdrive %d\n",t
)); 2152 memset((char*)&mpd
,0,sizeof(gdth_modep_data
)); 2153 mpd
.hd
.data_length
=sizeof(gdth_modep_data
); 2154 mpd
.hd
.dev_par
= (ha
->hdr
[t
].devtype
&2) ?0x80:0; 2155 mpd
.hd
.bd_length
=sizeof(mpd
.bd
); 2156 mpd
.bd
.block_length
[0] = (SECTOR_SIZE
&0x00ff0000) >>16; 2157 mpd
.bd
.block_length
[1] = (SECTOR_SIZE
&0x0000ff00) >>8; 2158 mpd
.bd
.block_length
[2] = (SECTOR_SIZE
&0x000000ff); 2159 gdth_copy_internal_data(scp
,(char*)&mpd
,sizeof(gdth_modep_data
)); 2163 TRACE2(("Read capacity hdrive %d\n",t
)); 2164 rdc
.last_block_no
=ntohl(ha
->hdr
[t
].size
-1); 2165 rdc
.block_length
=ntohl(SECTOR_SIZE
); 2166 gdth_copy_internal_data(scp
,(char*)&rdc
,sizeof(gdth_rdcap_data
)); 2170 TRACE2(("Internal cache cmd 0x%x unknown\n",scp
->cmnd
[0])); 2173 scp
->result
= DID_OK
<<16; 2175 if(!scp
->SCp
.have_data_in
) 2176 scp
->SCp
.have_data_in
++; 2183 static intgdth_fill_cache_cmd(int hanum
,Scsi_Cmnd
*scp
,ushort hdrive
) 2185 register gdth_ha_str
*ha
; 2186 register gdth_cmd_str
*cmdp
; 2187 struct scatterlist
*sl
; 2191 ha
=HADATA(gdth_ctr_tab
[hanum
]); 2193 TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", 2194 scp
->cmnd
[0],scp
->cmd_len
,hdrive
)); 2196 if(ha
->type
==GDT_EISA
&& ha
->cmd_cnt
>0) 2199 cmdp
->Service
= CACHESERVICE
; 2200 cmdp
->RequestBuffer
= scp
; 2201 /* search free command index */ 2202 if(!(cmd_index
=gdth_get_cmd_index(hanum
))) { 2203 TRACE(("GDT: No free command index found\n")); 2206 /* if it's the first command, set command semaphore */ 2208 gdth_set_sema0(hanum
); 2211 if(scp
->cmnd
[0]==ALLOW_MEDIUM_REMOVAL
) { 2212 if(scp
->cmnd
[4] &1)/* prevent ? */ 2213 cmdp
->OpCode
= GDT_MOUNT
; 2214 else if(scp
->cmnd
[3] &1)/* removable drive ? */ 2215 cmdp
->OpCode
= GDT_UNMOUNT
; 2217 cmdp
->OpCode
= GDT_FLUSH
; 2219 if(scp
->cmnd
[0]==WRITE_6
|| scp
->cmnd
[0]==WRITE_10
) { 2220 if(gdth_write_through
) 2221 cmdp
->OpCode
= GDT_WRITE_THR
; 2223 cmdp
->OpCode
= GDT_WRITE
; 2225 cmdp
->OpCode
= GDT_READ
; 2229 cmdp
->BoardNode
= LOCALBOARD
; 2230 cmdp
->u
.cache
.DeviceNo
= hdrive
; 2232 if(scp
->cmnd
[0]==ALLOW_MEDIUM_REMOVAL
) { 2233 cmdp
->u
.cache
.BlockNo
=1; 2234 cmdp
->u
.cache
.sg_canz
=0; 2236 if(scp
->cmd_len
!=6) { 2237 cmdp
->u
.cache
.BlockNo
=ntohl(*(ulong32
*)&scp
->cmnd
[2]); 2238 cmdp
->u
.cache
.BlockCnt
= (ulong32
)ntohs(*(ushort
*)&scp
->cmnd
[7]); 2240 cmdp
->u
.cache
.BlockNo
= 2241 ntohl(*(ulong32
*)&scp
->cmnd
[0]) &0x001fffffUL
; 2242 cmdp
->u
.cache
.BlockCnt
= scp
->cmnd
[4]==0?0x100: scp
->cmnd
[4]; 2246 cmdp
->u
.cache
.DestAddr
=0xffffffff; 2247 sl
= (struct scatterlist
*)scp
->request_buffer
; 2248 for(i
=0; i
<scp
->use_sg
; ++i
,++sl
) { 2249 cmdp
->u
.cache
.sg_lst
[i
].sg_ptr
=virt_to_bus(sl
->address
); 2250 cmdp
->u
.cache
.sg_lst
[i
].sg_len
= (ulong32
)sl
->length
; 2252 cmdp
->u
.cache
.sg_canz
= (ulong32
)i
; 2254 #ifdef GDTH_STATISTICS 2255 if(max_sg
< (ulong32
)i
) { 2256 max_sg
= (ulong32
)i
; 2257 TRACE3(("GDT: max_sg = %d\n",i
)); 2261 cmdp
->u
.cache
.sg_lst
[i
].sg_len
=0; 2263 if(ha
->cache_feat
& SCATTER_GATHER
) { 2264 cmdp
->u
.cache
.DestAddr
=0xffffffff; 2265 cmdp
->u
.cache
.sg_canz
=1; 2266 cmdp
->u
.cache
.sg_lst
[0].sg_ptr
= 2267 virt_to_bus(scp
->request_buffer
); 2268 cmdp
->u
.cache
.sg_lst
[0].sg_len
= scp
->request_bufflen
; 2269 cmdp
->u
.cache
.sg_lst
[1].sg_len
=0; 2271 cmdp
->u
.cache
.DestAddr
=virt_to_bus(scp
->request_buffer
); 2272 cmdp
->u
.cache
.sg_canz
=0; 2276 TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", 2277 cmdp
->u
.cache
.DestAddr
,cmdp
->u
.cache
.sg_canz
, 2278 cmdp
->u
.cache
.sg_lst
[0].sg_ptr
, 2279 cmdp
->u
.cache
.sg_lst
[0].sg_len
)); 2280 TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n", 2281 cmdp
->OpCode
,cmdp
->u
.cache
.BlockNo
,cmdp
->u
.cache
.BlockCnt
)); 2283 /* evaluate command size, check space */ 2284 ha
->cmd_len
=GDTOFFSOF(gdth_cmd_str
,u
.cache
.sg_lst
) + 2285 (ushort
)cmdp
->u
.cache
.sg_canz
*sizeof(gdth_sg_str
); 2287 ha
->cmd_len
+= (4- (ha
->cmd_len
&3)); 2289 if(ha
->cmd_cnt
>0) { 2290 if((ha
->cmd_offs_dpmem
+ ha
->cmd_len
+ DPMEM_COMMAND_OFFSET
) > 2292 TRACE2(("gdth_fill_cache() DPMEM overflow\n")); 2293 ha
->cmd_tab
[cmd_index
-2].cmnd
= UNUSED_CMND
; 2299 gdth_copy_command(hanum
); 2303 static intgdth_fill_raw_cmd(int hanum
,Scsi_Cmnd
*scp
,unchar b
) 2305 register gdth_ha_str
*ha
; 2306 register gdth_cmd_str
*cmdp
; 2307 struct scatterlist
*sl
; 2312 ha
=HADATA(gdth_ctr_tab
[hanum
]); 2316 TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n", 2317 scp
->cmnd
[0],b
,t
,l
)); 2319 if(ha
->type
==GDT_EISA
&& ha
->cmd_cnt
>0) 2322 cmdp
->Service
= SCSIRAWSERVICE
; 2323 cmdp
->RequestBuffer
= scp
; 2324 /* search free command index */ 2325 if(!(cmd_index
=gdth_get_cmd_index(hanum
))) { 2326 TRACE(("GDT: No free command index found\n")); 2329 /* if it's the first command, set command semaphore */ 2331 gdth_set_sema0(hanum
); 2334 if(scp
->SCp
.Status
!= -1) { 2335 cmdp
->OpCode
= scp
->SCp
.Status
;/* special raw cmd. */ 2336 cmdp
->BoardNode
= LOCALBOARD
; 2337 cmdp
->u
.raw
.direction
= (scp
->SCp
.phase
>>8); 2338 TRACE2(("special raw cmd 0x%x param 0x%x\n", 2339 cmdp
->OpCode
, cmdp
->u
.raw
.direction
)); 2341 /* evaluate command size */ 2342 ha
->cmd_len
=GDTOFFSOF(gdth_cmd_str
,u
.raw
.sg_lst
); 2344 cmdp
->OpCode
= GDT_WRITE
;/* always */ 2345 cmdp
->BoardNode
= LOCALBOARD
; 2346 cmdp
->u
.raw
.reserved
=0; 2347 cmdp
->u
.raw
.mdisc_time
=0; 2348 cmdp
->u
.raw
.mcon_time
=0; 2349 cmdp
->u
.raw
.clen
= scp
->cmd_len
; 2350 cmdp
->u
.raw
.target
= t
; 2351 cmdp
->u
.raw
.lun
= l
; 2352 cmdp
->u
.raw
.bus
= b
; 2353 cmdp
->u
.raw
.priority
=0; 2354 cmdp
->u
.raw
.link_p
= NULL
; 2355 cmdp
->u
.raw
.sdlen
= scp
->request_bufflen
; 2356 cmdp
->u
.raw
.sense_len
=16; 2357 cmdp
->u
.raw
.sense_data
=virt_to_bus(scp
->sense_buffer
); 2358 cmdp
->u
.raw
.direction
= 2359 gdth_direction_tab
[scp
->cmnd
[0]]==DOU
? DATA_OUT
: DATA_IN
; 2360 memcpy(cmdp
->u
.raw
.cmd
,scp
->cmnd
,12); 2363 cmdp
->u
.raw
.sdata
=0xffffffff; 2364 sl
= (struct scatterlist
*)scp
->request_buffer
; 2365 for(i
=0; i
<scp
->use_sg
; ++i
,++sl
) { 2366 cmdp
->u
.raw
.sg_lst
[i
].sg_ptr
=virt_to_bus(sl
->address
); 2367 cmdp
->u
.raw
.sg_lst
[i
].sg_len
= (ulong32
)sl
->length
; 2369 cmdp
->u
.raw
.sg_ranz
= (ulong32
)i
; 2371 #ifdef GDTH_STATISTICS 2372 if(max_sg
< (ulong32
)i
) { 2373 max_sg
= (ulong32
)i
; 2374 TRACE3(("GDT: max_sg = %d\n",i
)); 2378 cmdp
->u
.raw
.sg_lst
[i
].sg_len
=0; 2380 if(ha
->raw_feat
& SCATTER_GATHER
) { 2381 cmdp
->u
.raw
.sdata
=0xffffffff; 2382 cmdp
->u
.raw
.sg_ranz
=1; 2383 cmdp
->u
.raw
.sg_lst
[0].sg_ptr
=virt_to_bus(scp
->request_buffer
); 2384 cmdp
->u
.raw
.sg_lst
[0].sg_len
= scp
->request_bufflen
; 2385 cmdp
->u
.raw
.sg_lst
[1].sg_len
=0; 2387 cmdp
->u
.raw
.sdata
=virt_to_bus(scp
->request_buffer
); 2388 cmdp
->u
.raw
.sg_ranz
=0; 2391 TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", 2392 cmdp
->u
.raw
.sdata
,cmdp
->u
.raw
.sg_ranz
, 2393 cmdp
->u
.raw
.sg_lst
[0].sg_ptr
, 2394 cmdp
->u
.raw
.sg_lst
[0].sg_len
)); 2396 /* evaluate command size */ 2397 ha
->cmd_len
=GDTOFFSOF(gdth_cmd_str
,u
.raw
.sg_lst
) + 2398 (ushort
)cmdp
->u
.raw
.sg_ranz
*sizeof(gdth_sg_str
); 2402 ha
->cmd_len
+= (4- (ha
->cmd_len
&3)); 2404 if(ha
->cmd_cnt
>0) { 2405 if((ha
->cmd_offs_dpmem
+ ha
->cmd_len
+ DPMEM_COMMAND_OFFSET
) > 2407 TRACE2(("gdth_fill_raw() DPMEM overflow\n")); 2408 ha
->cmd_tab
[cmd_index
-2].cmnd
= UNUSED_CMND
; 2414 gdth_copy_command(hanum
); 2418 static intgdth_special_cmd(int hanum
,Scsi_Cmnd
*scp
) 2420 register gdth_ha_str
*ha
; 2421 register gdth_cmd_str
*cmdp
; 2424 ha
=HADATA(gdth_ctr_tab
[hanum
]); 2426 TRACE2(("gdth_special_cmd(): ")); 2428 if(ha
->type
==GDT_EISA
&& ha
->cmd_cnt
>0) 2431 memcpy( cmdp
, scp
->request_buffer
,sizeof(gdth_cmd_str
)); 2432 cmdp
->RequestBuffer
= scp
; 2434 /* search free command index */ 2435 if(!(cmd_index
=gdth_get_cmd_index(hanum
))) { 2436 TRACE(("GDT: No free command index found\n")); 2440 /* if it's the first command, set command semaphore */ 2442 gdth_set_sema0(hanum
); 2444 /* evaluate command size, check space */ 2445 if(cmdp
->OpCode
== GDT_IOCTL
) { 2446 TRACE2(("IOCTL\n")); 2448 GDTOFFSOF(gdth_cmd_str
,u
.ioctl
.p_param
) +sizeof(ulong32
); 2449 }else if(cmdp
->Service
== CACHESERVICE
) { 2450 TRACE2(("cache command %d\n",cmdp
->OpCode
)); 2452 GDTOFFSOF(gdth_cmd_str
,u
.cache
.sg_lst
) +sizeof(gdth_sg_str
); 2453 }else if(cmdp
->Service
== SCSIRAWSERVICE
) { 2454 TRACE2(("raw command %d/%d\n",cmdp
->OpCode
,cmdp
->u
.raw
.cmd
[0])); 2456 GDTOFFSOF(gdth_cmd_str
,u
.raw
.sg_lst
) +sizeof(gdth_sg_str
); 2460 ha
->cmd_len
+= (4- (ha
->cmd_len
&3)); 2462 if(ha
->cmd_cnt
>0) { 2463 if((ha
->cmd_offs_dpmem
+ ha
->cmd_len
+ DPMEM_COMMAND_OFFSET
) > 2465 TRACE2(("gdth_special_cmd() DPMEM overflow\n")); 2466 ha
->cmd_tab
[cmd_index
-2].cmnd
= UNUSED_CMND
; 2472 gdth_copy_command(hanum
); 2477 /* Controller event handling functions */ 2478 static gdth_evt_str
*gdth_store_event(gdth_ha_str
*ha
, ushort source
, 2479 ushort idx
, gdth_evt_data
*evt
) 2484 /* no GDTH_LOCK_HA() ! */ 2485 TRACE2(("gdth_store_event() source %d idx %d\n", source
, idx
)); 2486 if(source
==0)/* no source -> no event */ 2489 if(ebuffer
[elastidx
].event_source
== source
&& 2490 ebuffer
[elastidx
].event_idx
== idx
&& 2491 !memcmp((char*)&ebuffer
[elastidx
].event_data
.eu
, 2492 (char*)&evt
->eu
, evt
->size
)) { 2493 e
= &ebuffer
[elastidx
]; 2494 do_gettimeofday(&tv
); 2495 e
->last_stamp
= tv
.tv_sec
; 2498 if(ebuffer
[elastidx
].event_source
!=0) {/* entry not free ? */ 2500 if(elastidx
== MAX_EVENTS
) 2502 if(elastidx
== eoldidx
) {/* reached mark ? */ 2504 if(eoldidx
== MAX_EVENTS
) 2508 e
= &ebuffer
[elastidx
]; 2509 e
->event_source
= source
; 2511 do_gettimeofday(&tv
); 2512 e
->first_stamp
= e
->last_stamp
= tv
.tv_sec
; 2514 e
->event_data
= *evt
; 2519 static intgdth_read_event(gdth_ha_str
*ha
,int handle
, gdth_evt_str
*estr
) 2525 TRACE2(("gdth_read_event() handle %d\n", handle
)); 2526 GDTH_LOCK_HA(ha
, flags
); 2531 estr
->event_source
=0; 2533 if(eindex
>= MAX_EVENTS
) { 2534 GDTH_UNLOCK_HA(ha
, flags
); 2537 e
= &ebuffer
[eindex
]; 2538 if(e
->event_source
!=0) { 2539 if(eindex
!= elastidx
) { 2540 if(++eindex
== MAX_EVENTS
) 2545 memcpy(estr
, e
,sizeof(gdth_evt_str
)); 2547 GDTH_UNLOCK_HA(ha
, flags
); 2551 static voidgdth_readapp_event(gdth_ha_str
*ha
, 2552 unchar application
, gdth_evt_str
*estr
) 2557 unchar found
= FALSE
; 2559 TRACE2(("gdth_readapp_event() app. %d\n", application
)); 2560 GDTH_LOCK_HA(ha
, flags
); 2563 e
= &ebuffer
[eindex
]; 2564 if(e
->event_source
==0) 2566 if((e
->application
& application
) ==0) { 2567 e
->application
|= application
; 2571 if(eindex
== elastidx
) 2573 if(++eindex
== MAX_EVENTS
) 2577 memcpy(estr
, e
,sizeof(gdth_evt_str
)); 2579 estr
->event_source
=0; 2580 GDTH_UNLOCK_HA(ha
, flags
); 2583 static voidgdth_clear_events() 2585 TRACE(("gdth_clear_events()")); 2587 eoldidx
= elastidx
=0; 2588 ebuffer
[0].event_source
=0; 2592 /* SCSI interface functions */ 2594 #if LINUX_VERSION_CODE >= 0x010346 2595 static voidgdth_interrupt(int irq
,void*dev_id
,struct pt_regs
*regs
) 2597 static voidgdth_interrupt(int irq
,struct pt_regs
*regs
) 2600 register gdth_ha_str
*ha
; 2601 gdt6m_dpram_str
*dp6m_ptr
; 2602 gdt6_dpram_str
*dp6_ptr
; 2603 gdt2_dpram_str
*dp2_ptr
; 2607 ushort CmdStatus
, Service
=0; 2608 ulong32 InfoBytes
, InfoBytes2
=0; 2612 TRACE(("gdth_interrupt() IRQ %d\n",irq
)); 2614 /* if polling and not from gdth_wait() -> return */ 2616 if(!gdth_from_wait
) { 2622 GDTH_LOCK_HA((gdth_ha_str
*)dev_id
,flags
); 2625 /* search controller */ 2626 if((hanum
=gdth_get_status(&IStatus
,irq
)) == -1) { 2628 TRACE2(("gdth_interrupt(): Spurious interrupt received\n")); 2631 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
); 2635 #ifdef GDTH_STATISTICS 2639 ha
=HADATA(gdth_ctr_tab
[hanum
]); 2640 if(ha
->type
== GDT_EISA
) { 2641 if(IStatus
&0x80) {/* error flag */ 2643 CmdStatus
=inw(ha
->bmic
+ MAILBOXREG
+8); 2644 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
)); 2645 if(IStatus
== ASYNCINDEX
) {/* async. event ? */ 2646 Service
=inw(ha
->bmic
+ MAILBOXREG
+10); 2647 InfoBytes2
=inl(ha
->bmic
+ MAILBOXREG
+4); 2651 InfoBytes
=inl(ha
->bmic
+ MAILBOXREG
+12); 2652 if(gdth_polling
)/* init. -> more info */ 2653 InfoBytes2
=inl(ha
->bmic
+ MAILBOXREG
+4); 2654 outb(0xff, ha
->bmic
+ EDOORREG
);/* acknowledge interrupt */ 2655 outb(0x00, ha
->bmic
+ SEMA1REG
);/* reset status semaphore */ 2656 }else if(ha
->type
== GDT_ISA
) { 2657 dp2_ptr
= (gdt2_dpram_str
*)ha
->brd
; 2658 if(IStatus
&0x80) {/* error flag */ 2660 CmdStatus
=gdth_readw(&dp2_ptr
->u
.ic
.Status
); 2661 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
)); 2662 if(IStatus
== ASYNCINDEX
) {/* async. event ? */ 2663 Service
=gdth_readw(&dp2_ptr
->u
.ic
.Service
); 2664 InfoBytes2
=gdth_readl(&dp2_ptr
->u
.ic
.Info
[1]); 2668 InfoBytes
=gdth_readl(&dp2_ptr
->u
.ic
.Info
[0]); 2669 if(gdth_polling
)/* init. -> more info */ 2670 InfoBytes2
=gdth_readl(&dp2_ptr
->u
.ic
.Info
[1]); 2671 gdth_writeb(0xff, &dp2_ptr
->io
.irqdel
);/* acknowledge interrupt */ 2672 gdth_writeb(0, &dp2_ptr
->u
.ic
.Cmd_Index
);/* reset command index */ 2673 gdth_writeb(0, &dp2_ptr
->io
.Sema1
);/* reset status semaphore */ 2674 }else if(ha
->type
== GDT_PCI
) { 2675 dp6_ptr
= (gdt6_dpram_str
*)ha
->brd
; 2676 if(IStatus
&0x80) {/* error flag */ 2678 CmdStatus
=gdth_readw(&dp6_ptr
->u
.ic
.Status
); 2679 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
)); 2680 if(IStatus
== ASYNCINDEX
) {/* async. event ? */ 2681 Service
=gdth_readw(&dp6_ptr
->u
.ic
.Service
); 2682 InfoBytes2
=gdth_readl(&dp6_ptr
->u
.ic
.Info
[1]); 2686 InfoBytes
=gdth_readl(&dp6_ptr
->u
.ic
.Info
[0]); 2687 if(gdth_polling
)/* init. -> more info */ 2688 InfoBytes2
=gdth_readl(&dp6_ptr
->u
.ic
.Info
[1]); 2689 gdth_writeb(0xff, &dp6_ptr
->io
.irqdel
);/* acknowledge interrupt */ 2690 gdth_writeb(0, &dp6_ptr
->u
.ic
.Cmd_Index
);/* reset command index */ 2691 gdth_writeb(0, &dp6_ptr
->io
.Sema1
);/* reset status semaphore */ 2692 }else if(ha
->type
== GDT_PCINEW
) { 2693 if(IStatus
&0x80) {/* error flag */ 2695 CmdStatus
=inw(PTR2USHORT(&ha
->plx
->status
)); 2696 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
)); 2697 if(IStatus
== ASYNCINDEX
) {/* async. event ? */ 2698 Service
=inw(PTR2USHORT(&ha
->plx
->service
)); 2699 InfoBytes2
=inl(PTR2USHORT(&ha
->plx
->info
[1])); 2704 InfoBytes
=inl(PTR2USHORT(&ha
->plx
->info
[0])); 2705 if(gdth_polling
)/* init. -> more info */ 2706 InfoBytes2
=inl(PTR2USHORT(&ha
->plx
->info
[1])); 2707 outb(0xff,PTR2USHORT(&ha
->plx
->edoor_reg
)); 2708 outb(0x00,PTR2USHORT(&ha
->plx
->sema1_reg
)); 2709 }else if(ha
->type
== GDT_PCIMPR
) { 2710 dp6m_ptr
= (gdt6m_dpram_str
*)ha
->brd
; 2711 if(IStatus
&0x80) {/* error flag */ 2713 CmdStatus
=gdth_readw(&dp6m_ptr
->i960r
.status
); 2714 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus
,CmdStatus
)); 2715 if(IStatus
== ASYNCINDEX
) {/* async. event ? */ 2716 Service
=gdth_readw(&dp6m_ptr
->i960r
.service
); 2717 InfoBytes2
=gdth_readl(&dp6m_ptr
->i960r
.info
[1]); 2721 InfoBytes
=gdth_readl(&dp6m_ptr
->i960r
.info
[0]); 2722 if(gdth_polling
)/* init. -> more info */ 2723 InfoBytes2
=gdth_readl(&dp6m_ptr
->i960r
.info
[1]); 2724 gdth_writeb(0xff, &dp6m_ptr
->i960r
.edoor_reg
); 2725 gdth_writeb(0, &dp6m_ptr
->i960r
.sema1_reg
); 2727 TRACE2(("gdth_interrupt() unknown controller type\n")); 2729 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
); 2733 TRACE(("gdth_interrupt() index %d stat %d info %d\n", 2734 IStatus
,CmdStatus
,InfoBytes
)); 2735 ha
->status
= CmdStatus
; 2736 ha
->info
= InfoBytes
; 2737 ha
->info2
= InfoBytes2
; 2739 if(gdth_from_wait
) { 2741 wait_index
= (int)IStatus
; 2744 if(IStatus
== ASYNCINDEX
) { 2745 TRACE2(("gdth_interrupt() async. event\n")); 2746 gdth_async_event(hanum
,Service
); 2748 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
); 2753 if(IStatus
== SPEZINDEX
) { 2754 TRACE2(("Service unknown or not initialized !\n")); 2755 dvr
.size
=sizeof(dvr
.eu
.driver
); 2756 dvr
.eu
.driver
.ionode
= hanum
; 2757 gdth_store_event(ha
, ES_DRIVER
,4, &dvr
); 2759 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
); 2762 scp
= ha
->cmd_tab
[IStatus
-2].cmnd
; 2763 Service
= ha
->cmd_tab
[IStatus
-2].service
; 2764 ha
->cmd_tab
[IStatus
-2].cmnd
= UNUSED_CMND
; 2765 if(scp
== UNUSED_CMND
) { 2766 TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus
)); 2767 dvr
.size
=sizeof(dvr
.eu
.driver
); 2768 dvr
.eu
.driver
.ionode
= hanum
; 2769 dvr
.eu
.driver
.index
= IStatus
; 2770 gdth_store_event(ha
, ES_DRIVER
,1, &dvr
); 2772 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
); 2775 if(scp
== INTERNAL_CMND
) { 2776 TRACE(("gdth_interrupt() answer to internal command\n")); 2778 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
); 2782 TRACE(("gdth_interrupt() sync. status\n")); 2783 rval
=gdth_sync_event(hanum
,Service
,IStatus
,scp
); 2785 GDTH_UNLOCK_HA((gdth_ha_str
*)dev_id
,flags
); 2787 gdth_putq(hanum
,scp
,scp
->SCp
.this_residual
); 2788 }else if(rval
==1) { 2789 GDTH_LOCK_SCSI_DONE(flags
); 2790 scp
->scsi_done(scp
); 2791 GDTH_UNLOCK_SCSI_DONE(flags
); 2796 static intgdth_sync_event(int hanum
,int service
,unchar index
,Scsi_Cmnd
*scp
) 2798 register gdth_ha_str
*ha
; 2805 ha
=HADATA(gdth_ctr_tab
[hanum
]); 2807 TRACE(("gdth_sync_event() serv %d status %d\n", 2808 service
,ha
->status
)); 2810 if(service
== SCREENSERVICE
) { 2811 msg
= (gdth_msg_str
*)ha
->pscratch
; 2812 ha
->scratch_busy
= FALSE
; 2813 TRACE(("len: %d, answer: %d, ext: %d, alen: %d\n", 2814 msg
->msg_len
,msg
->msg_answer
,msg
->msg_ext
,msg
->msg_alen
)); 2816 if(!(msg
->msg_answer
&& msg
->msg_ext
)) { 2817 msg
->msg_text
[msg
->msg_len
] ='\0'; 2818 printk("%s",msg
->msg_text
); 2821 if(msg
->msg_ext
&& !msg
->msg_answer
) { 2822 while(gdth_test_busy(hanum
)) 2824 cmdp
->Service
= SCREENSERVICE
; 2825 cmdp
->RequestBuffer
= SCREEN_CMND
; 2826 gdth_get_cmd_index(hanum
); 2827 gdth_set_sema0(hanum
); 2828 cmdp
->OpCode
= GDT_READ
; 2829 cmdp
->BoardNode
= LOCALBOARD
; 2830 cmdp
->u
.screen
.reserved
=0; 2831 cmdp
->u
.screen
.msg_handle
= msg
->msg_handle
; 2832 cmdp
->u
.screen
.msg_addr
=virt_to_bus(msg
); 2833 ha
->scratch_busy
= TRUE
; 2834 ha
->cmd_offs_dpmem
=0; 2835 ha
->cmd_len
=GDTOFFSOF(gdth_cmd_str
,u
.screen
.msg_addr
) 2838 gdth_copy_command(hanum
); 2839 gdth_release_event(hanum
); 2843 if(msg
->msg_answer
&& msg
->msg_alen
) { 2844 for(i
=0; i
<msg
->msg_alen
&& i
<MSGLEN
; ++i
) { 2849 msg
->msg_text
[i
] = c
; 2852 if(c
!='\r'&& msg
->msg_alen
!=0) { 2860 while(gdth_test_busy(hanum
)) 2862 cmdp
->Service
= SCREENSERVICE
; 2863 cmdp
->RequestBuffer
= SCREEN_CMND
; 2864 gdth_get_cmd_index(hanum
); 2865 gdth_set_sema0(hanum
); 2866 cmdp
->OpCode
= GDT_WRITE
; 2867 cmdp
->BoardNode
= LOCALBOARD
; 2868 cmdp
->u
.screen
.reserved
=0; 2869 cmdp
->u
.screen
.msg_handle
= msg
->msg_handle
; 2870 cmdp
->u
.screen
.msg_addr
=virt_to_bus(msg
); 2871 ha
->scratch_busy
= TRUE
; 2872 ha
->cmd_offs_dpmem
=0; 2873 ha
->cmd_len
=GDTOFFSOF(gdth_cmd_str
,u
.screen
.msg_addr
) 2876 gdth_copy_command(hanum
); 2877 gdth_release_event(hanum
); 2883 if(scp
->SCp
.Status
== -1&& scp
->channel
!= ha
->virt_bus
) { 2884 ha
->raw
[BUS_L2P(ha
,scp
->channel
)].io_cnt
[scp
->target
]--; 2886 /* cache or raw service */ 2887 if(ha
->status
== S_OK
) { 2888 scp
->SCp
.Message
= S_OK
; 2889 if(scp
->SCp
.Status
!= -1) { 2890 TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n", 2892 scp
->SCp
.Status
= -1; 2893 scp
->SCp
.this_residual
= HIGH_PRI
; 2896 scp
->result
= DID_OK
<<16; 2897 }else if(ha
->status
== S_BSY
) { 2898 TRACE2(("Controller busy -> retry !\n")); 2899 scp
->SCp
.Message
= S_BSY
; 2902 scp
->SCp
.Message
= (int)((ha
->info
<<16)|ha
->status
); 2903 if(scp
->SCp
.Status
!= -1) { 2904 TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n", 2905 scp
->SCp
.Status
, ha
->status
)); 2906 scp
->SCp
.Status
= -1; 2907 scp
->SCp
.this_residual
= HIGH_PRI
; 2910 if(service
== CACHESERVICE
) { 2911 memset((char*)scp
->sense_buffer
,0,16); 2912 scp
->sense_buffer
[0] =0x70; 2913 scp
->sense_buffer
[2] = NOT_READY
; 2914 scp
->result
= (DID_OK
<<16) | (CHECK_CONDITION
<<1); 2916 #if LINUX_VERSION_CODE >= 0x010300 2917 if(scp
->done
!= gdth_scsi_done
) 2920 dvr
.size
=sizeof(dvr
.eu
.sync
); 2921 dvr
.eu
.sync
.ionode
= hanum
; 2922 dvr
.eu
.sync
.service
= service
; 2923 dvr
.eu
.sync
.status
= ha
->status
; 2924 dvr
.eu
.sync
.info
= ha
->info
; 2925 dvr
.eu
.sync
.hostdrive
= scp
->target
; 2926 if(ha
->status
>=0x8000) 2927 gdth_store_event(ha
, ES_SYNC
,0, &dvr
); 2929 gdth_store_event(ha
, ES_SYNC
, service
, &dvr
); 2932 if(ha
->status
!=S_RAW_SCSI
|| ha
->info
>=0x100) { 2933 scp
->result
= DID_BAD_TARGET
<<16; 2935 scp
->result
= (DID_OK
<<16) | ha
->info
; 2939 if(!scp
->SCp
.have_data_in
) 2940 scp
->SCp
.have_data_in
++; 2948 static char*async_cache_tab
[] = { 2949 /* 0*/"\011\000\002\002\002\004\002\006\004" 2950 "GDT HA %u, service %u, async. status %u/%lu unknown", 2951 /* 1*/"\011\000\002\002\002\004\002\006\004" 2952 "GDT HA %u, service %u, async. status %u/%lu unknown", 2953 /* 2*/"\005\000\002\006\004" 2954 "GDT HA %u, Host Drive %lu not ready", 2955 /* 3*/"\005\000\002\006\004" 2956 "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", 2957 /* 4*/"\005\000\002\006\004" 2958 "GDT HA %u, mirror update on Host Drive %lu failed", 2959 /* 5*/"\005\000\002\006\004" 2960 "GDT HA %u, Mirror Drive %lu failed", 2961 /* 6*/"\005\000\002\006\004" 2962 "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", 2963 /* 7*/"\005\000\002\006\004" 2964 "GDT HA %u, Host Drive %lu write protected", 2965 /* 8*/"\005\000\002\006\004" 2966 "GDT HA %u, media changed in Host Drive %lu", 2967 /* 9*/"\005\000\002\006\004" 2968 "GDT HA %u, Host Drive %lu is offline", 2969 /*10*/"\005\000\002\006\004" 2970 "GDT HA %u, media change of Mirror Drive %lu", 2971 /*11*/"\005\000\002\006\004" 2972 "GDT HA %u, Mirror Drive %lu is write protected", 2973 /*12*/"\005\000\002\006\004" 2974 "GDT HA %u, general error on Host Drive %lu. Please check the devices of this drive!", 2975 /*13*/"\007\000\002\006\002\010\002" 2976 "GDT HA %u, Array Drive %u: Cache Drive %u failed", 2977 /*14*/"\005\000\002\006\002" 2978 "GDT HA %u, Array Drive %u: FAIL state entered", 2979 /*15*/"\005\000\002\006\002" 2980 "GDT HA %u, Array Drive %u: error", 2981 /*16*/"\007\000\002\006\002\010\002" 2982 "GDT HA %u, Array Drive %u: failed drive replaced by Cache Drive %u", 2983 /*17*/"\005\000\002\006\002" 2984 "GDT HA %u, Array Drive %u: parity build failed", 2985 /*18*/"\005\000\002\006\002" 2986 "GDT HA %u, Array Drive %u: drive rebuild failed", 2987 /*19*/"\005\000\002\010\002" 2988 "GDT HA %u, Test of Hot Fix %u failed", 2989 /*20*/"\005\000\002\006\002" 2990 "GDT HA %u, Array Drive %u: drive build finished successfully", 2991 /*21*/"\005\000\002\006\002" 2992 "GDT HA %u, Array Drive %u: drive rebuild finished successfully", 2993 /*22*/"\007\000\002\006\002\010\002" 2994 "GDT HA %u, Array Drive %u: Hot Fix %u activated", 2995 /*23*/"\005\000\002\006\002" 2996 "GDT HA %u, Host Drive %u: processing of i/o aborted due to serious drive error", 2997 /*24*/"\005\000\002\010\002" 2998 "GDT HA %u, mirror update on Cache Drive %u completed", 2999 /*25*/"\005\000\002\010\002" 3000 "GDT HA %u, mirror update on Cache Drive %lu failed", 3001 /*26*/"\005\000\002\006\002" 3002 "GDT HA %u, Array Drive %u: drive rebuild started", 3003 /*27*/"\005\000\002\012\001" 3004 "GDT HA %u, Fault bus %u: SHELF OK detected", 3005 /*28*/"\005\000\002\012\001" 3006 "GDT HA %u, Fault bus %u: SHELF not OK detected", 3007 /*29*/"\007\000\002\012\001\013\001" 3008 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug started", 3009 /*30*/"\007\000\002\012\001\013\001" 3010 "GDT HA %u, Fault bus %u, ID %u: new disk detected", 3011 /*31*/"\007\000\002\012\001\013\001" 3012 "GDT HA %u, Fault bus %u, ID %u: old disk detected", 3013 /*32*/"\007\000\002\012\001\013\001" 3014 "GDT HA %u, Fault bus %u, ID %u: plugging an active disk is illegal", 3015 /*33*/"\007\000\002\012\001\013\001" 3016 "GDT HA %u, Fault bus %u, ID %u: illegal device detected", 3017 /*34*/"\011\000\002\012\001\013\001\006\004" 3018 "GDT HA %u, Fault bus %u, ID %u: insufficient disk capacity (%lu MB required)", 3019 /*35*/"\007\000\002\012\001\013\001" 3020 "GDT HA %u, Fault bus %u, ID %u: disk write protected", 3021 /*36*/"\007\000\002\012\001\013\001" 3022 "GDT HA %u, Fault bus %u, ID %u: disk not available", 3023 /*37*/"\007\000\002\012\001\006\004" 3024 "GDT HA %u, Fault bus %u: swap detected (%lu)", 3025 /*38*/"\007\000\002\012\001\013\001" 3026 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug finished successfully", 3027 /*39*/"\007\000\002\012\001\013\001" 3028 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted due to user Hot Plug", 3029 /*40*/"\007\000\002\012\001\013\001" 3030 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted", 3031 /*41*/"\007\000\002\012\001\013\001" 3032 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug for Hot Fix started", 3033 /*42*/"\005\000\002\006\002" 3034 "GDT HA %u, Array Drive %u: drive build started", 3035 /*43*/"\003\000\002" 3036 "GDT HA %u, DRAM parity error detected", 3037 /*44*/"\005\000\002\006\002" 3038 "GDT HA %u, Mirror Drive %u: update started", 3039 /*45*/"\007\000\002\006\002\010\002" 3040 "GDT HA %u, Mirror Drive %u: Hot Fix %u activated", 3041 /*46*/"\005\000\002\006\002" 3042 "GDT HA %u, Array Drive %u: no matching Pool Hot Fix Drive available", 3043 /*47*/"\005\000\002\006\002" 3044 "GDT HA %u, Array Drive %u: Pool Hot Fix Drive available", 3045 /*48*/"\005\000\002\006\002" 3046 "GDT HA %u, Mirror Drive %u: no matching Pool Hot Fix Drive available", 3047 /*49*/"\005\000\002\006\002" 3048 "GDT HA %u, Mirror Drive %u: Pool Hot Fix Drive available", 3049 /*50*/"\007\000\002\012\001\013\001" 3050 "GDT HA %u, SCSI bus %u, ID %u: IGNORE_WIDE_RESIDUE message received", 3051 /*51*/"\005\000\002\006\002" 3052 "GDT HA %u, Array Drive %u: expand started", 3053 /*52*/"\005\000\002\006\002" 3054 "GDT HA %u, Array Drive %u: expand finished successfully", 3055 /*53*/"\005\000\002\006\002" 3056 "GDT HA %u, Array Drive %u: expand failed", 3057 /*54*/"\003\000\002" 3058 "GDT HA %u, CPU temperature critical", 3059 /*55*/"\003\000\002" 3060 "GDT HA %u, CPU temperature OK", 3061 /*56*/"\005\000\002\006\004" 3062 "GDT HA %u, Host drive %lu created", 3063 /*57*/"\005\000\002\006\002" 3064 "GDT HA %u, Array Drive %u: expand restarted", 3065 /*58*/"\005\000\002\006\002" 3066 "GDT HA %u, Array Drive %u: expand stopped", 3067 /*59*/"\005\000\002\010\002" 3068 "GDT HA %u, Mirror Drive %u: drive build quited", 3069 /*60*/"\005\000\002\006\002" 3070 "GDT HA %u, Array Drive %u: parity build quited", 3071 /*61*/"\005\000\002\006\002" 3072 "GDT HA %u, Array Drive %u: drive rebuild quited", 3073 /*62*/"\005\000\002\006\002" 3074 "GDT HA %u, Array Drive %u: parity verify started", 3075 /*63*/"\005\000\002\006\002" 3076 "GDT HA %u, Array Drive %u: parity verify done", 3077 /*64*/"\005\000\002\006\002" 3078 "GDT HA %u, Array Drive %u: parity verify failed", 3079 /*65*/"\005\000\002\006\002" 3080 "GDT HA %u, Array Drive %u: parity error detected", 3081 /*66*/"\005\000\002\006\002" 3082 "GDT HA %u, Array Drive %u: parity verify quited", 3083 /*67*/"\005\000\002\006\002" 3084 "GDT HA %u, Host Drive %u reserved", 3085 /*68*/"\005\000\002\006\002" 3086 "GDT HA %u, Host Drive %u mounted and released", 3087 /*69*/"\005\000\002\006\002" 3088 "GDT HA %u, Host Drive %u released", 3089 /*70*/"\003\000\002" 3090 "GDT HA %u, DRAM error detected and corrected with ECC", 3091 /*71*/"\003\000\002" 3092 "GDT HA %u, Uncorrectable DRAM error detected with ECC", 3093 /*72*/"\011\000\002\012\001\013\001\014\001" 3094 "GDT HA %u, SCSI bus %u, ID %u, LUN %u: reassigning block", 3098 static intgdth_async_event(int hanum
,int service
) 3106 ha
=HADATA(gdth_ctr_tab
[hanum
]); 3108 msg
= (gdth_msg_str
*)ha
->pscratch
; 3109 TRACE2(("gdth_async_event() ha %d serv %d\n", 3112 if(service
== SCREENSERVICE
) { 3113 if(ha
->status
== MSG_REQUEST
) { 3114 while(gdth_test_busy(hanum
)) 3116 cmdp
->Service
= SCREENSERVICE
; 3117 cmdp
->RequestBuffer
= SCREEN_CMND
; 3118 cmd_index
=gdth_get_cmd_index(hanum
); 3119 gdth_set_sema0(hanum
); 3120 cmdp
->OpCode
= GDT_READ
; 3121 cmdp
->BoardNode
= LOCALBOARD
; 3122 cmdp
->u
.screen
.reserved
=0; 3123 cmdp
->u
.screen
.msg_handle
= MSG_INV_HANDLE
; 3124 cmdp
->u
.screen
.msg_addr
=virt_to_bus(msg
); 3125 ha
->scratch_busy
= TRUE
; 3126 ha
->cmd_offs_dpmem
=0; 3127 ha
->cmd_len
=GDTOFFSOF(gdth_cmd_str
,u
.screen
.msg_addr
) 3130 gdth_copy_command(hanum
); 3131 if(ha
->type
== GDT_EISA
) 3132 printk("[EISA slot %d] ",(ushort
)ha
->brd_phys
); 3133 else if(ha
->type
== GDT_ISA
) 3134 printk("[DPMEM 0x%4X] ",(ushort
)ha
->brd_phys
); 3136 printk("[PCI %d/%d] ",(ushort
)(ha
->brd_phys
>>8), 3137 (ushort
)((ha
->brd_phys
>>3)&0x1f)); 3138 gdth_release_event(hanum
); 3142 dvr
.size
=sizeof(dvr
.eu
.async
); 3143 dvr
.eu
.async
.ionode
= hanum
; 3144 dvr
.eu
.async
.service
= service
; 3145 dvr
.eu
.async
.status
= ha
->status
; 3146 dvr
.eu
.async
.info
= ha
->info
; 3147 *(ulong32
*)dvr
.eu
.async
.scsi_coord
= ha
->info2
; 3148 gdth_store_event(ha
, ES_ASYNC
, service
, &dvr
); 3149 gdth_log_event( &dvr
, NULL
); 3154 static voidgdth_log_event(gdth_evt_data
*dvr
,char*buffer
) 3156 gdth_stackframe stack
; 3160 TRACE2(("gdth_log_event()\n")); 3161 if(dvr
->eu
.async
.service
== CACHESERVICE
&& 3162 INDEX_OK(dvr
->eu
.async
.status
, async_cache_tab
)) { 3163 TRACE2(("GDT: Async. event cache service, event no.: %d\n", 3164 dvr
->eu
.async
.status
)); 3166 f
= async_cache_tab
[dvr
->eu
.async
.status
]; 3168 /* i: parameter to push, j: stack element to fill */ 3169 for(j
=0,i
=1; i
< f
[0]; i
+=2) { 3172 stack
.b
[j
++] = *(ulong32
*)&dvr
->eu
.stream
[(int)f
[i
]]; 3175 stack
.b
[j
++] = *(ushort
*)&dvr
->eu
.stream
[(int)f
[i
]]; 3178 stack
.b
[j
++] = *(unchar
*)&dvr
->eu
.stream
[(int)f
[i
]]; 3185 if(buffer
== NULL
) { 3186 printk(&f
[(int)f
[0]],stack
); 3189 sprintf(buffer
,&f
[(int)f
[0]],stack
); 3193 if(buffer
== NULL
) { 3194 printk("GDT HA %u, Unknown async. event service %d event no. %d\n", 3195 dvr
->eu
.async
.ionode
,dvr
->eu
.async
.service
,dvr
->eu
.async
.status
); 3197 sprintf(buffer
,"GDT HA %u, Unknown async. event service %d event no. %d", 3198 dvr
->eu
.async
.ionode
,dvr
->eu
.async
.service
,dvr
->eu
.async
.status
); 3203 #ifdef GDTH_STATISTICS 3204 voidgdth_timeout(ulong data
) 3212 ha
=HADATA(gdth_ctr_tab
[hanum
]); 3213 GDTH_LOCK_HA(ha
, flags
); 3215 for(act_stats
=0,i
=0; i
<GDTH_MAXCMDS
; ++i
) 3216 if(ha
->cmd_tab
[i
].cmnd
!= UNUSED_CMND
) 3219 for(act_rq
=0,nscp
=ha
->req_first
; nscp
; nscp
=(Scsi_Cmnd
*)nscp
->SCp
.ptr
) 3222 TRACE2(("gdth_to(): ints %d, ios %d, act_stats %d, act_rq %d\n", 3223 act_ints
, act_ios
, act_stats
, act_rq
)); 3224 act_ints
= act_ios
=0; 3226 gdth_timer
.expires
= jiffies
+30* HZ
; 3227 add_timer(&gdth_timer
); 3228 GDTH_UNLOCK_HA(ha
, flags
); 3233 int __init
gdth_detect(Scsi_Host_Template
*shtp
) 3235 struct Scsi_Host
*shp
; 3239 int i
,hanum
,cnt
,ctr
; 3244 printk("GDT: This driver contains debugging information !! Trace level = %d\n", 3246 printk(" Destination of debugging information: "); 3249 printk("Serial port COM2\n"); 3251 printk("Serial port COM1\n"); 3254 printk("Console\n"); 3259 TRACE(("gdth_detect()\n")); 3262 printk("GDT: Controller driver disabled from command line !\n"); 3266 /* initializations */ 3267 gdth_polling
= TRUE
; b
=0; 3268 gdth_clear_events(); 3270 /* scanning for controllers, at first: ISA controller */ 3271 for(isa_bios
=0xc8000UL
; isa_bios
<=0xd8000UL
; isa_bios
+=0x8000UL
) { 3272 if(gdth_ctr_count
>= MAXHA
) 3274 if(gdth_search_isa(isa_bios
)) {/* controller found */ 3275 shp
=scsi_register(shtp
,sizeof(gdth_ext_str
)); 3277 if(!gdth_init_isa(isa_bios
,ha
)) { 3278 scsi_unregister(shp
); 3281 /* controller found and initialized */ 3282 printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", 3283 isa_bios
,ha
->irq
,ha
->drq
); 3285 #if LINUX_VERSION_CODE >= 0x010346 3286 if(request_irq(ha
->irq
,gdth_interrupt
,SA_INTERRUPT
,"gdth",ha
)) 3288 if(request_irq(ha
->irq
,gdth_interrupt
,SA_INTERRUPT
,"gdth")) 3291 printk("GDT-ISA: Unable to allocate IRQ\n"); 3292 scsi_unregister(shp
); 3295 if(request_dma(ha
->drq
,"gdth")) { 3296 printk("GDT-ISA: Unable to allocate DMA channel\n"); 3297 #if LINUX_VERSION_CODE >= 0x010346 3298 free_irq(ha
->irq
,NULL
); 3302 scsi_unregister(shp
); 3305 set_dma_mode(ha
->drq
,DMA_MODE_CASCADE
); 3306 enable_dma(ha
->drq
); 3307 shp
->unchecked_isa_dma
=1; 3309 shp
->dma_channel
= ha
->drq
; 3310 hanum
= gdth_ctr_count
; 3311 gdth_ctr_tab
[gdth_ctr_count
++] = shp
; 3312 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
; 3314 NUMDATA(shp
)->hanum
= (ushort
)hanum
; 3315 NUMDATA(shp
)->busnum
=0; 3317 ha
->pccb
=CMDDATA(shp
); 3318 ha
->pscratch
=scsi_init_malloc(GDTH_SCRATCH
, GFP_ATOMIC
| GFP_DMA
); 3319 ha
->scratch_busy
= FALSE
; 3320 ha
->req_first
= NULL
; 3321 ha
->tid_cnt
= MAX_HDRIVES
; 3322 if(max_ids
>0&& max_ids
< ha
->tid_cnt
) 3323 ha
->tid_cnt
= max_ids
; 3324 for(i
=0; i
<GDTH_MAXCMDS
; ++i
) 3325 ha
->cmd_tab
[i
].cmnd
= UNUSED_CMND
; 3326 ha
->scan_mode
= rescan
?0x10:0; 3328 if(ha
->pscratch
== NULL
|| !gdth_search_drives(hanum
)) { 3329 printk("GDT-ISA: Error during device scan\n"); 3332 if(ha
->pscratch
!= NULL
) 3333 scsi_init_free((void*)ha
->pscratch
, GDTH_SCRATCH
); 3334 #if LINUX_VERSION_CODE >= 0x010346 3335 free_irq(ha
->irq
,NULL
); 3339 scsi_unregister(shp
); 3342 if(hdr_channel
<0|| hdr_channel
> ha
->bus_cnt
) 3343 hdr_channel
= ha
->bus_cnt
; 3344 ha
->virt_bus
= hdr_channel
; 3346 #if LINUX_VERSION_CODE >= 0x020000 3347 shp
->max_id
= ha
->tid_cnt
; 3348 shp
->max_lun
= MAXLUN
; 3349 shp
->max_channel
= ha
->bus_cnt
; 3351 /* register addit. SCSI channels as virtual controllers */ 3352 for(b
=1; b
<ha
->bus_cnt
+1; ++b
) { 3353 shp
=scsi_register(shtp
,sizeof(gdth_num_str
)); 3354 shp
->unchecked_isa_dma
=1; 3356 shp
->dma_channel
= ha
->drq
; 3357 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
; 3358 NUMDATA(shp
)->hanum
= (ushort
)hanum
; 3359 NUMDATA(shp
)->busnum
= b
; 3362 GDTH_INIT_LOCK_HA(ha
); 3363 gdth_enable_int(hanum
); 3367 /* scanning for EISA controllers */ 3368 for(eisa_slot
=0x1000; eisa_slot
<=0x8000; eisa_slot
+=0x1000) { 3369 if(gdth_ctr_count
>= MAXHA
) 3371 if(gdth_search_eisa(eisa_slot
)) {/* controller found */ 3372 shp
=scsi_register(shtp
,sizeof(gdth_ext_str
)); 3374 if(!gdth_init_eisa(eisa_slot
,ha
)) { 3375 scsi_unregister(shp
); 3378 /* controller found and initialized */ 3379 printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", 3380 eisa_slot
>>12,ha
->irq
); 3382 #if LINUX_VERSION_CODE >= 0x010346 3383 if(request_irq(ha
->irq
,gdth_interrupt
,SA_INTERRUPT
,"gdth",ha
)) 3385 if(request_irq(ha
->irq
,gdth_interrupt
,SA_INTERRUPT
,"gdth")) 3388 printk("GDT-EISA: Unable to allocate IRQ\n"); 3389 scsi_unregister(shp
); 3392 shp
->unchecked_isa_dma
=0; 3394 shp
->dma_channel
=0xff; 3395 hanum
= gdth_ctr_count
; 3396 gdth_ctr_tab
[gdth_ctr_count
++] = shp
; 3397 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
; 3399 NUMDATA(shp
)->hanum
= (ushort
)hanum
; 3400 NUMDATA(shp
)->busnum
=0; 3401 TRACE2(("EISA detect Bus 0: hanum %d\n", 3402 NUMDATA(shp
)->hanum
)); 3404 ha
->pccb
=CMDDATA(shp
); 3405 ha
->pscratch
=scsi_init_malloc(GDTH_SCRATCH
, GFP_ATOMIC
| GFP_DMA
); 3406 ha
->scratch_busy
= FALSE
; 3407 ha
->req_first
= NULL
; 3408 ha
->tid_cnt
= MAX_HDRIVES
; 3409 if(max_ids
>0&& max_ids
< ha
->tid_cnt
) 3410 ha
->tid_cnt
= max_ids
; 3411 for(i
=0; i
<GDTH_MAXCMDS
; ++i
) 3412 ha
->cmd_tab
[i
].cmnd
= UNUSED_CMND
; 3413 ha
->scan_mode
= rescan
?0x10:0; 3415 if(ha
->pscratch
== NULL
|| !gdth_search_drives(hanum
)) { 3416 printk("GDT-EISA: Error during device scan\n"); 3419 if(ha
->pscratch
!= NULL
) 3420 scsi_init_free((void*)ha
->pscratch
, GDTH_SCRATCH
); 3421 #if LINUX_VERSION_CODE >= 0x010346 3422 free_irq(ha
->irq
,NULL
); 3426 scsi_unregister(shp
); 3429 if(hdr_channel
<0|| hdr_channel
> ha
->bus_cnt
) 3430 hdr_channel
= ha
->bus_cnt
; 3431 ha
->virt_bus
= hdr_channel
; 3433 #if LINUX_VERSION_CODE >= 0x020000 3434 shp
->max_id
= ha
->tid_cnt
; 3435 shp
->max_lun
= MAXLUN
; 3436 shp
->max_channel
= ha
->bus_cnt
; 3438 /* register addit. SCSI channels as virtual controllers */ 3439 for(b
=1; b
<ha
->bus_cnt
+1; ++b
) { 3440 shp
=scsi_register(shtp
,sizeof(gdth_num_str
)); 3441 shp
->unchecked_isa_dma
=0; 3443 shp
->dma_channel
=0xff; 3444 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
; 3445 NUMDATA(shp
)->hanum
= (ushort
)hanum
; 3446 NUMDATA(shp
)->busnum
= b
; 3447 TRACE2(("EISA detect Bus %d: shp %x hanum %d\n", 3448 NUMDATA(shp
)->busnum
,(ulong32
)shp
, 3449 NUMDATA(shp
)->hanum
)); 3452 GDTH_INIT_LOCK_HA(ha
); 3453 gdth_enable_int(hanum
); 3457 /* scanning for PCI controllers */ 3458 #if LINUX_VERSION_CODE >= 0x2015C 3461 if(pcibios_present()) 3464 gdth_pci_str pcistr
[MAXHA
]; 3466 cnt
=gdth_search_pci(pcistr
); 3467 gdth_sort_pci(pcistr
,cnt
); 3468 for(ctr
=0; ctr
< cnt
; ++ctr
) { 3469 if(gdth_ctr_count
>= MAXHA
) 3471 shp
=scsi_register(shtp
,sizeof(gdth_ext_str
)); 3473 if(!gdth_init_pci(&pcistr
[ctr
],ha
)) { 3474 scsi_unregister(shp
); 3477 /* controller found and initialized */ 3478 printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", 3479 pcistr
[ctr
].bus
,PCI_SLOT(pcistr
[ctr
].device_fn
),ha
->irq
); 3481 #if LINUX_VERSION_CODE >= 0x010346 3482 if(request_irq(ha
->irq
, gdth_interrupt
, 3483 SA_INTERRUPT
|SA_SHIRQ
,"gdth", ha
)) 3485 if(request_irq(ha
->irq
, gdth_interrupt
, 3486 SA_INTERRUPT
|SA_SHIRQ
,"gdth")) 3489 printk("GDT-PCI: Unable to allocate IRQ\n"); 3490 scsi_unregister(shp
); 3493 shp
->unchecked_isa_dma
=0; 3495 shp
->dma_channel
=0xff; 3496 hanum
= gdth_ctr_count
; 3497 gdth_ctr_tab
[gdth_ctr_count
++] = shp
; 3498 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
; 3500 NUMDATA(shp
)->hanum
= (ushort
)hanum
; 3501 NUMDATA(shp
)->busnum
=0; 3503 ha
->pccb
=CMDDATA(shp
); 3504 ha
->pscratch
=scsi_init_malloc(GDTH_SCRATCH
, GFP_ATOMIC
| GFP_DMA
); 3505 ha
->scratch_busy
= FALSE
; 3506 ha
->req_first
= NULL
; 3507 ha
->tid_cnt
= pcistr
[ctr
].device_id
>=0x200? MAXID
: MAX_HDRIVES
; 3508 if(max_ids
>0&& max_ids
< ha
->tid_cnt
) 3509 ha
->tid_cnt
= max_ids
; 3510 for(i
=0; i
<GDTH_MAXCMDS
; ++i
) 3511 ha
->cmd_tab
[i
].cmnd
= UNUSED_CMND
; 3512 ha
->scan_mode
= rescan
?0x10:0; 3514 if(ha
->pscratch
== NULL
|| !gdth_search_drives(hanum
)) { 3515 printk("GDT-PCI: Error during device scan\n"); 3518 if(ha
->pscratch
!= NULL
) 3519 scsi_init_free((void*)ha
->pscratch
, GDTH_SCRATCH
); 3520 #if LINUX_VERSION_CODE >= 0x010346 3521 free_irq(ha
->irq
,NULL
); 3525 scsi_unregister(shp
); 3528 if(hdr_channel
<0|| hdr_channel
> ha
->bus_cnt
) 3529 hdr_channel
= ha
->bus_cnt
; 3530 ha
->virt_bus
= hdr_channel
; 3532 #if LINUX_VERSION_CODE >= 0x020000 3533 shp
->max_id
= ha
->tid_cnt
; 3534 shp
->max_lun
= MAXLUN
; 3535 shp
->max_channel
= ha
->bus_cnt
; 3537 /* register addit. SCSI channels as virtual controllers */ 3538 for(b
=1; b
<ha
->bus_cnt
+1; ++b
) { 3539 shp
=scsi_register(shtp
,sizeof(gdth_num_str
)); 3540 shp
->unchecked_isa_dma
=0; 3542 shp
->dma_channel
=0xff; 3543 gdth_ctr_vtab
[gdth_ctr_vcount
++] = shp
; 3544 NUMDATA(shp
)->hanum
= (ushort
)hanum
; 3545 NUMDATA(shp
)->busnum
= b
; 3548 GDTH_INIT_LOCK_HA(ha
); 3549 gdth_enable_int(hanum
); 3553 TRACE2(("gdth_detect() %d controller detected\n",gdth_ctr_count
)); 3554 if(gdth_ctr_count
>0) { 3555 #ifdef GDTH_STATISTICS 3556 TRACE2(("gdth_detect(): Initializing timer !\n")); 3557 init_timer(&gdth_timer
); 3558 gdth_timer
.expires
= jiffies
+ HZ
; 3559 gdth_timer
.data
=0L; 3560 gdth_timer
.function
= gdth_timeout
; 3561 add_timer(&gdth_timer
); 3563 #if LINUX_VERSION_CODE >= 0x020100 3564 register_reboot_notifier(&gdth_notifier
); 3567 gdth_polling
= FALSE
; 3568 return gdth_ctr_vcount
; 3572 intgdth_release(struct Scsi_Host
*shp
) 3577 TRACE2(("gdth_release()\n")); 3578 if(NUMDATA(shp
)->busnum
==0) { 3579 hanum
=NUMDATA(shp
)->hanum
; 3580 ha
=HADATA(gdth_ctr_tab
[hanum
]); 3581 #if LINUX_VERSION_CODE >= 0x010300 3586 #if LINUX_VERSION_CODE >= 0x010346 3587 free_irq(shp
->irq
,NULL
); 3592 if(shp
->dma_channel
!=0xff) { 3593 free_dma(shp
->dma_channel
); 3595 scsi_init_free((void*)ha
->pscratch
, GDTH_SCRATCH
); 3596 gdth_ctr_released
++; 3597 TRACE2(("gdth_release(): HA %d of %d\n", 3598 gdth_ctr_released
, gdth_ctr_count
)); 3600 if(gdth_ctr_released
== gdth_ctr_count
) { 3601 #ifdef GDTH_STATISTICS 3602 del_timer(&gdth_timer
); 3604 #if LINUX_VERSION_CODE >= 0x020100 3605 unregister_reboot_notifier(&gdth_notifier
); 3610 scsi_unregister(shp
); 3615 static const char*gdth_ctr_name(int hanum
) 3619 TRACE2(("gdth_ctr_name()\n")); 3621 ha
=HADATA(gdth_ctr_tab
[hanum
]); 3623 if(ha
->type
== GDT_EISA
) { 3626 return("GDT3000/3020"); 3628 return("GDT3000A/3020A/3050A"); 3630 return("GDT3000B/3010A"); 3632 }else if(ha
->type
== GDT_ISA
) { 3633 return("GDT2000/2020"); 3634 }else if(ha
->type
== GDT_PCI
) { 3636 case PCI_DEVICE_ID_VORTEX_GDT60x0
: 3637 return("GDT6000/6020/6050"); 3638 case PCI_DEVICE_ID_VORTEX_GDT6000B
: 3639 return("GDT6000B/6010"); 3642 /* new controllers (GDT_PCINEW, GDT_PCIMPR, ..) use board_info IOCTL! */ 3647 const char*gdth_info(struct Scsi_Host
*shp
) 3652 TRACE2(("gdth_info()\n")); 3653 hanum
=NUMDATA(shp
)->hanum
; 3654 ha
=HADATA(gdth_ctr_tab
[hanum
]); 3656 return((const char*)ha
->binfo
.type_string
); 3659 /* old error handling */ 3660 intgdth_abort(Scsi_Cmnd
*scp
) 3662 TRACE2(("gdth_abort() reason %d\n",scp
->abort_reason
)); 3663 return SCSI_ABORT_SNOOZE
; 3666 #if LINUX_VERSION_CODE >= 0x010346 3667 intgdth_reset(Scsi_Cmnd
*scp
,unsigned int reset_flags
) 3669 intgdth_reset(Scsi_Cmnd
*scp
) 3672 TRACE2(("gdth_reset()\n")); 3673 return SCSI_RESET_PUNT
; 3676 #if LINUX_VERSION_CODE >= 0x02015F 3677 /* new error handling */ 3678 intgdth_eh_abort(Scsi_Cmnd
*scp
) 3680 TRACE2(("gdth_eh_abort()\n")); 3684 intgdth_eh_device_reset(Scsi_Cmnd
*scp
) 3686 TRACE2(("gdth_eh_device_reset()\n")); 3690 intgdth_eh_bus_reset(Scsi_Cmnd
*scp
) 3697 TRACE2(("gdth_eh_bus_reset()\n")); 3698 hanum
=NUMDATA(scp
->host
)->hanum
; 3699 ha
=HADATA(gdth_ctr_tab
[hanum
]); 3700 if(scp
->channel
== ha
->virt_bus
) 3703 GDTH_LOCK_HA(ha
, flags
); 3704 for(i
=0; i
< MAXID
; ++i
) 3705 ha
->raw
[BUS_L2P(ha
,scp
->channel
)].io_cnt
[i
] =0; 3706 for(i
=0; i
< GDTH_MAXCMDS
; ++i
) { 3707 cmnd
= ha
->cmd_tab
[i
].cmnd
; 3708 if(!SPECIAL_SCP(cmnd
) && cmnd
->channel
== scp
->channel
) 3709 ha
->cmd_tab
[i
].cmnd
= UNUSED_CMND
; 3711 gdth_polling
= TRUE
; 3712 while(gdth_test_busy(hanum
)) 3714 gdth_internal_cmd(hanum
, SCSIRAWSERVICE
, GDT_RESET_BUS
, 3715 BUS_L2P(ha
,scp
->channel
),0,0); 3716 gdth_polling
= FALSE
; 3717 GDTH_UNLOCK_HA(ha
, flags
); 3721 intgdth_eh_host_reset(Scsi_Cmnd
*scp
) 3723 TRACE2(("gdth_eh_host_reset()\n")); 3728 #if LINUX_VERSION_CODE >= 0x010300 3729 intgdth_bios_param(Disk
*disk
,kdev_t dev
,int*ip
) 3731 intgdth_bios_param(Disk
*disk
,int dev
,int*ip
) 3738 hanum
=NUMDATA(disk
->device
->host
)->hanum
; 3739 t
= disk
->device
->id
; 3740 TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", 3741 hanum
, disk
->device
->channel
, t
)); 3742 ha
=HADATA(gdth_ctr_tab
[hanum
]); 3744 if(disk
->device
->channel
!= ha
->virt_bus
|| ha
->hdr
[t
].heads
==0) { 3745 /* raw device or host drive without mapping information */ 3746 TRACE2(("Evaluate mapping\n")); 3747 gdth_eval_mapping(disk
->capacity
,&ip
[2],&ip
[0],&ip
[1]); 3749 ip
[0] = ha
->hdr
[t
].heads
; 3750 ip
[1] = ha
->hdr
[t
].secs
; 3751 ip
[2] = disk
->capacity
/ ip
[0] / ip
[1]; 3754 TRACE2(("gdth_bios_param(): %d heads, %d secs, %d cyls\n", 3755 ip
[0],ip
[1],ip
[2])); 3760 static voidinternal_done(Scsi_Cmnd
*scp
) 3762 scp
->SCp
.sent_command
++; 3765 intgdth_command(Scsi_Cmnd
*scp
) 3767 TRACE2(("gdth_command()\n")); 3769 scp
->SCp
.sent_command
=0; 3770 gdth_queuecommand(scp
,internal_done
); 3772 while(!scp
->SCp
.sent_command
) 3778 intgdth_queuecommand(Scsi_Cmnd
*scp
,void(*done
)(Scsi_Cmnd
*)) 3783 TRACE(("gdth_queuecommand() cmd 0x%x id %d lun %d\n", 3784 scp
->cmnd
[0],scp
->target
,scp
->lun
)); 3786 scp
->scsi_done
= (void*)done
; 3787 scp
->SCp
.have_data_in
=1; 3788 scp
->SCp
.phase
= -1; 3789 scp
->SCp
.Status
= -1; 3790 hanum
=NUMDATA(scp
->host
)->hanum
; 3791 #ifdef GDTH_STATISTICS 3795 priority
= DEFAULT_PRI
; 3796 #if LINUX_VERSION_CODE >= 0x010300 3797 if(scp
->done
== gdth_scsi_done
) 3798 priority
= scp
->SCp
.this_residual
; 3800 gdth_update_timeout(hanum
, scp
, scp
->timeout_per_command
*6); 3801 gdth_putq( hanum
, scp
, priority
); 3806 #if LINUX_VERSION_CODE >= 0x010300 3808 static voidgdth_flush(int hanum
) 3814 gdth_cmd_str gdtcmd
; 3816 TRACE2(("gdth_flush() hanum %d\n",hanum
)); 3817 ha
=HADATA(gdth_ctr_tab
[hanum
]); 3818 memset(&sdev
,0,sizeof(Scsi_Device
)); 3819 memset(&scp
,0,sizeof(Scsi_Cmnd
)); 3820 sdev
.host
= gdth_ctr_tab
[hanum
]; 3821 sdev
.id
= sdev
.host
->this_id
; 3823 scp
.host
= gdth_ctr_tab
[hanum
]; 3824 scp
.target
= sdev
.host
->this_id
; 3828 for(i
=0; i
< MAX_HDRIVES
; ++i
) { 3829 if(ha
->hdr
[i
].present
) { 3830 gdtcmd
.BoardNode
= LOCALBOARD
; 3831 gdtcmd
.Service
= CACHESERVICE
; 3832 gdtcmd
.OpCode
= GDT_FLUSH
; 3833 gdtcmd
.u
.cache
.DeviceNo
= i
; 3834 gdtcmd
.u
.cache
.BlockNo
=1; 3835 gdtcmd
.u
.cache
.sg_canz
=0; 3836 TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum
, i
)); 3837 gdth_do_cmd(&scp
, &gdtcmd
,30); 3842 /* shutdown routine */ 3843 #if LINUX_VERSION_CODE >= 0x020100 3844 static intgdth_halt(struct notifier_block
*nb
, ulong event
,void*buf
) 3853 gdth_cmd_str gdtcmd
; 3856 #if LINUX_VERSION_CODE >= 0x020100 3857 TRACE2(("gdth_halt() event %d\n",event
)); 3858 if(event
!= SYS_RESTART
&& event
!= SYS_HALT
&& event
!= SYS_POWER_OFF
) 3861 TRACE2(("gdth_halt()\n")); 3863 TRACE2(("already called\n")); 3868 printk("GDT: Flushing all host drives .. "); 3869 for(hanum
=0; hanum
< gdth_ctr_count
; ++hanum
) { 3873 /* controller reset */ 3874 memset(&sdev
,0,sizeof(Scsi_Device
)); 3875 memset(&scp
,0,sizeof(Scsi_Cmnd
)); 3876 sdev
.host
= gdth_ctr_tab
[hanum
]; 3877 sdev
.id
= sdev
.host
->this_id
; 3879 scp
.host
= gdth_ctr_tab
[hanum
]; 3880 scp
.target
= sdev
.host
->this_id
; 3884 gdtcmd
.BoardNode
= LOCALBOARD
; 3885 gdtcmd
.Service
= CACHESERVICE
; 3886 gdtcmd
.OpCode
= GDT_RESET
; 3887 TRACE2(("gdth_halt(): reset controller %d\n", hanum
)); 3888 gdth_do_cmd(&scp
, &gdtcmd
,10); 3893 #ifdef GDTH_STATISTICS 3894 del_timer(&gdth_timer
); 3896 #if LINUX_VERSION_CODE >= 0x020100 3897 unregister_reboot_notifier(&gdth_notifier
); 3904 /* called from init/main.c */ 3905 void __init
gdth_setup(char*str
,int*ints
) 3908 char*cur_str
, *argv
; 3910 TRACE2(("gdth_setup() str %s ints[0] %d\n", 3911 str
? str
:"NULL", ints
? ints
[0]:0)); 3913 /* read irq[] from ints[] */ 3919 for(i
=0; i
< argc
; ++i
) 3924 /* analyse string */ 3926 while(argv
&& (cur_str
=strchr(argv
,':'))) { 3927 int val
=0, c
= *++cur_str
; 3929 if(c
=='n'|| c
=='N') 3931 else if(c
=='y'|| c
=='Y') 3934 val
= (int)simple_strtoul(cur_str
, NULL
,0); 3936 if(!strncmp(argv
,"disable:",8)) 3938 else if(!strncmp(argv
,"reserve_mode:",13)) 3940 else if(!strncmp(argv
,"reverse_scan:",13)) 3942 else if(!strncmp(argv
,"hdr_channel:",12)) 3944 else if(!strncmp(argv
,"max_ids:",8)) 3946 else if(!strncmp(argv
,"rescan:",7)) 3948 else if(!strncmp(argv
,"reserve_list:",13)) { 3949 reserve_list
[0] = val
; 3950 for(i
=1; i
< MAX_RES_ARGS
; i
++) { 3951 cur_str
=strchr(cur_str
,','); 3954 if(!isdigit((int)*++cur_str
)) { 3959 (int)simple_strtoul(cur_str
, NULL
,0); 3967 if((argv
=strchr(argv
,','))) 3974 Scsi_Host_Template driver_template
= GDTH
; 3975 #include"scsi_module.c"