Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.25-rc1 5252 lines 182 kB view raw
1/************************************************************************ 2 * Linux driver for * 3 * ICP vortex GmbH: GDT ISA/EISA/PCI Disk Array Controllers * 4 * Intel Corporation: Storage RAID Controllers * 5 * * 6 * gdth.c * 7 * Copyright (C) 1995-06 ICP vortex GmbH, Achim Leubner * 8 * Copyright (C) 2002-04 Intel Corporation * 9 * Copyright (C) 2003-06 Adaptec Inc. * 10 * <achim_leubner@adaptec.com> * 11 * * 12 * Additions/Fixes: * 13 * Boji Tony Kannanthanam <boji.t.kannanthanam@intel.com> * 14 * Johannes Dinner <johannes_dinner@adaptec.com> * 15 * * 16 * This program is free software; you can redistribute it and/or modify * 17 * it under the terms of the GNU General Public License as published * 18 * by the Free Software Foundation; either version 2 of the License, * 19 * or (at your option) any later version. * 20 * * 21 * This program is distributed in the hope that it will be useful, * 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 24 * GNU General Public License for more details. * 25 * * 26 * You should have received a copy of the GNU General Public License * 27 * along with this kernel; if not, write to the Free Software * 28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 29 * * 30 * Linux kernel 2.6.x supported * 31 * * 32 ************************************************************************/ 33 34/* All GDT Disk Array Controllers are fully supported by this driver. 35 * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the 36 * PCI Fibre Channel Disk Array Controllers. See gdth.h for a complete 37 * list of all controller types. 38 * 39 * If you have one or more GDT3000/3020 EISA controllers with 40 * controller BIOS disabled, you have to set the IRQ values with the 41 * command line option "gdth=irq1,irq2,...", where the irq1,irq2,... are 42 * the IRQ values for the EISA controllers. 43 * 44 * After the optional list of IRQ values, other possible 45 * command line options are: 46 * disable:Y disable driver 47 * disable:N enable driver 48 * reserve_mode:0 reserve no drives for the raw service 49 * reserve_mode:1 reserve all not init., removable drives 50 * reserve_mode:2 reserve all not init. drives 51 * reserve_list:h,b,t,l,h,b,t,l,... reserve particular drive(s) with 52 * h- controller no., b- channel no., 53 * t- target ID, l- LUN 54 * reverse_scan:Y reverse scan order for PCI controllers 55 * reverse_scan:N scan PCI controllers like BIOS 56 * max_ids:x x - target ID count per channel (1..MAXID) 57 * rescan:Y rescan all channels/IDs 58 * rescan:N use all devices found until now 59 * hdr_channel:x x - number of virtual bus for host drives 60 * shared_access:Y disable driver reserve/release protocol to 61 * access a shared resource from several nodes, 62 * appropriate controller firmware required 63 * shared_access:N enable driver reserve/release protocol 64 * probe_eisa_isa:Y scan for EISA/ISA controllers 65 * probe_eisa_isa:N do not scan for EISA/ISA controllers 66 * force_dma32:Y use only 32 bit DMA mode 67 * force_dma32:N use 64 bit DMA mode, if supported 68 * 69 * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N, 70 * max_ids:127,rescan:N,hdr_channel:0, 71 * shared_access:Y,probe_eisa_isa:N,force_dma32:N". 72 * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y". 73 * 74 * When loading the gdth driver as a module, the same options are available. 75 * You can set the IRQs with "IRQ=...". However, the syntax to specify the 76 * options changes slightly. You must replace all ',' between options 77 * with ' ' and all ':' with '=' and you must use 78 * '1' in place of 'Y' and '0' in place of 'N'. 79 * 80 * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0 81 * max_ids=127 rescan=0 hdr_channel=0 shared_access=0 82 * probe_eisa_isa=0 force_dma32=0" 83 * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1". 84 */ 85 86/* The meaning of the Scsi_Pointer members in this driver is as follows: 87 * ptr: Chaining 88 * this_residual: gdth_bufflen 89 * buffer: gdth_sglist 90 * dma_handle: unused 91 * buffers_residual: gdth_sg_count 92 * Status: unused 93 * Message: unused 94 * have_data_in: unused 95 * sent_command: unused 96 * phase: unused 97 */ 98 99 100/* interrupt coalescing */ 101/* #define INT_COAL */ 102 103/* statistics */ 104#define GDTH_STATISTICS 105 106#include <linux/module.h> 107 108#include <linux/version.h> 109#include <linux/kernel.h> 110#include <linux/types.h> 111#include <linux/pci.h> 112#include <linux/string.h> 113#include <linux/ctype.h> 114#include <linux/ioport.h> 115#include <linux/delay.h> 116#include <linux/interrupt.h> 117#include <linux/in.h> 118#include <linux/proc_fs.h> 119#include <linux/time.h> 120#include <linux/timer.h> 121#include <linux/dma-mapping.h> 122#include <linux/list.h> 123 124#ifdef GDTH_RTC 125#include <linux/mc146818rtc.h> 126#endif 127#include <linux/reboot.h> 128 129#include <asm/dma.h> 130#include <asm/system.h> 131#include <asm/io.h> 132#include <asm/uaccess.h> 133#include <linux/spinlock.h> 134#include <linux/blkdev.h> 135#include <linux/scatterlist.h> 136 137#include "scsi.h" 138#include <scsi/scsi_host.h> 139#include "gdth.h" 140 141static void gdth_delay(int milliseconds); 142static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); 143static irqreturn_t gdth_interrupt(int irq, void *dev_id); 144static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, 145 int gdth_from_wait, int* pIndex); 146static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, 147 Scsi_Cmnd *scp); 148static int gdth_async_event(gdth_ha_str *ha); 149static void gdth_log_event(gdth_evt_data *dvr, char *buffer); 150 151static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority); 152static void gdth_next(gdth_ha_str *ha); 153static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b); 154static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); 155static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, 156 ushort idx, gdth_evt_data *evt); 157static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr); 158static void gdth_readapp_event(gdth_ha_str *ha, unchar application, 159 gdth_evt_str *estr); 160static void gdth_clear_events(void); 161 162static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, 163 char *buffer, ushort count, int to_buffer); 164static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); 165static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); 166 167static void gdth_enable_int(gdth_ha_str *ha); 168static int gdth_test_busy(gdth_ha_str *ha); 169static int gdth_get_cmd_index(gdth_ha_str *ha); 170static void gdth_release_event(gdth_ha_str *ha); 171static int gdth_wait(gdth_ha_str *ha, int index,ulong32 time); 172static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, 173 ulong32 p1, ulong64 p2,ulong64 p3); 174static int gdth_search_drives(gdth_ha_str *ha); 175static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive); 176 177static const char *gdth_ctr_name(gdth_ha_str *ha); 178 179static int gdth_open(struct inode *inode, struct file *filep); 180static int gdth_close(struct inode *inode, struct file *filep); 181static int gdth_ioctl(struct inode *inode, struct file *filep, 182 unsigned int cmd, unsigned long arg); 183 184static void gdth_flush(gdth_ha_str *ha); 185static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); 186static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); 187static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, 188 struct gdth_cmndinfo *cmndinfo); 189static void gdth_scsi_done(struct scsi_cmnd *scp); 190 191#ifdef DEBUG_GDTH 192static unchar DebugState = DEBUG_GDTH; 193 194#ifdef __SERIAL__ 195#define MAX_SERBUF 160 196static void ser_init(void); 197static void ser_puts(char *str); 198static void ser_putc(char c); 199static int ser_printk(const char *fmt, ...); 200static char strbuf[MAX_SERBUF+1]; 201#ifdef __COM2__ 202#define COM_BASE 0x2f8 203#else 204#define COM_BASE 0x3f8 205#endif 206static void ser_init() 207{ 208 unsigned port=COM_BASE; 209 210 outb(0x80,port+3); 211 outb(0,port+1); 212 /* 19200 Baud, if 9600: outb(12,port) */ 213 outb(6, port); 214 outb(3,port+3); 215 outb(0,port+1); 216 /* 217 ser_putc('I'); 218 ser_putc(' '); 219 */ 220} 221 222static void ser_puts(char *str) 223{ 224 char *ptr; 225 226 ser_init(); 227 for (ptr=str;*ptr;++ptr) 228 ser_putc(*ptr); 229} 230 231static void ser_putc(char c) 232{ 233 unsigned port=COM_BASE; 234 235 while ((inb(port+5) & 0x20)==0); 236 outb(c,port); 237 if (c==0x0a) 238 { 239 while ((inb(port+5) & 0x20)==0); 240 outb(0x0d,port); 241 } 242} 243 244static int ser_printk(const char *fmt, ...) 245{ 246 va_list args; 247 int i; 248 249 va_start(args,fmt); 250 i = vsprintf(strbuf,fmt,args); 251 ser_puts(strbuf); 252 va_end(args); 253 return i; 254} 255 256#define TRACE(a) {if (DebugState==1) {ser_printk a;}} 257#define TRACE2(a) {if (DebugState==1 || DebugState==2) {ser_printk a;}} 258#define TRACE3(a) {if (DebugState!=0) {ser_printk a;}} 259 260#else /* !__SERIAL__ */ 261#define TRACE(a) {if (DebugState==1) {printk a;}} 262#define TRACE2(a) {if (DebugState==1 || DebugState==2) {printk a;}} 263#define TRACE3(a) {if (DebugState!=0) {printk a;}} 264#endif 265 266#else /* !DEBUG */ 267#define TRACE(a) 268#define TRACE2(a) 269#define TRACE3(a) 270#endif 271 272#ifdef GDTH_STATISTICS 273static ulong32 max_rq=0, max_index=0, max_sg=0; 274#ifdef INT_COAL 275static ulong32 max_int_coal=0; 276#endif 277static ulong32 act_ints=0, act_ios=0, act_stats=0, act_rq=0; 278static struct timer_list gdth_timer; 279#endif 280 281#define PTR2USHORT(a) (ushort)(ulong)(a) 282#define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) 283#define INDEX_OK(i,t) ((i)<ARRAY_SIZE(t)) 284 285#define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) 286 287#ifdef CONFIG_ISA 288static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ 289#endif 290#if defined(CONFIG_EISA) || defined(CONFIG_ISA) 291static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ 292#endif 293static unchar gdth_polling; /* polling if TRUE */ 294static int gdth_ctr_count = 0; /* controller count */ 295static LIST_HEAD(gdth_instances); /* controller list */ 296static unchar gdth_write_through = FALSE; /* write through */ 297static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ 298static int elastidx; 299static int eoldidx; 300static int major; 301 302#define DIN 1 /* IN data direction */ 303#define DOU 2 /* OUT data direction */ 304#define DNO DIN /* no data transfer */ 305#define DUN DIN /* unknown data direction */ 306static unchar gdth_direction_tab[0x100] = { 307 DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN, 308 DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN, 309 DIN,DUN,DIN,DUN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU, 310 DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU, 311 DOU,DOU,DIN,DIN,DIN,DNO,DUN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DUN,DUN, 312 DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DIN,DUN,DUN,DUN,DUN,DUN, 313 DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, 314 DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, 315 DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DIN,DUN,DOU,DUN,DUN,DUN,DUN,DUN, 316 DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DIN,DUN, 317 DUN,DUN,DUN,DUN,DUN,DNO,DNO,DUN,DIN,DNO,DOU,DUN,DNO,DUN,DOU,DOU, 318 DOU,DOU,DOU,DNO,DUN,DIN,DOU,DIN,DIN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, 319 DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, 320 DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, 321 DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN, 322 DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN 323}; 324 325/* LILO and modprobe/insmod parameters */ 326/* IRQ list for GDT3000/3020 EISA controllers */ 327static int irq[MAXHA] __initdata = 328{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 329 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 330/* disable driver flag */ 331static int disable __initdata = 0; 332/* reserve flag */ 333static int reserve_mode = 1; 334/* reserve list */ 335static int reserve_list[MAX_RES_ARGS] = 336{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 337 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 338 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 339/* scan order for PCI controllers */ 340static int reverse_scan = 0; 341/* virtual channel for the host drives */ 342static int hdr_channel = 0; 343/* max. IDs per channel */ 344static int max_ids = MAXID; 345/* rescan all IDs */ 346static int rescan = 0; 347/* shared access */ 348static int shared_access = 1; 349/* enable support for EISA and ISA controllers */ 350static int probe_eisa_isa = 0; 351/* 64 bit DMA mode, support for drives > 2 TB, if force_dma32 = 0 */ 352static int force_dma32 = 0; 353 354/* parameters for modprobe/insmod */ 355module_param_array(irq, int, NULL, 0); 356module_param(disable, int, 0); 357module_param(reserve_mode, int, 0); 358module_param_array(reserve_list, int, NULL, 0); 359module_param(reverse_scan, int, 0); 360module_param(hdr_channel, int, 0); 361module_param(max_ids, int, 0); 362module_param(rescan, int, 0); 363module_param(shared_access, int, 0); 364module_param(probe_eisa_isa, int, 0); 365module_param(force_dma32, int, 0); 366MODULE_AUTHOR("Achim Leubner"); 367MODULE_LICENSE("GPL"); 368 369/* ioctl interface */ 370static const struct file_operations gdth_fops = { 371 .ioctl = gdth_ioctl, 372 .open = gdth_open, 373 .release = gdth_close, 374}; 375 376/* 377 * gdth scsi_command access wrappers. 378 * below 6 functions are used throughout the driver to access scsi_command's 379 * io parameters. The reason we do not use the regular accessors from 380 * scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for 381 * llds to directly set scsi_cmnd's IO members. This driver will use SCp 382 * members for IO parameters, and will copy scsi_cmnd's members to Scp 383 * members in queuecommand. For internal commands through gdth_execute() 384 * SCp's members will be set directly. 385 */ 386static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd) 387{ 388 return (unsigned)cmd->SCp.this_residual; 389} 390 391static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen) 392{ 393 cmd->SCp.this_residual = bufflen; 394} 395 396static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd) 397{ 398 return (unsigned)cmd->SCp.buffers_residual; 399} 400 401static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count) 402{ 403 cmd->SCp.buffers_residual = sg_count; 404} 405 406static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd) 407{ 408 return cmd->SCp.buffer; 409} 410 411static inline void gdth_set_sglist(struct scsi_cmnd *cmd, 412 struct scatterlist *sglist) 413{ 414 cmd->SCp.buffer = sglist; 415} 416 417#include "gdth_proc.h" 418#include "gdth_proc.c" 419 420/* notifier block to get a notify on system shutdown/halt/reboot */ 421static struct notifier_block gdth_notifier = { 422 gdth_halt, NULL, 0 423}; 424static int notifier_disabled = 0; 425 426static gdth_ha_str *gdth_find_ha(int hanum) 427{ 428 gdth_ha_str *ha; 429 430 list_for_each_entry(ha, &gdth_instances, list) 431 if (hanum == ha->hanum) 432 return ha; 433 434 return NULL; 435} 436 437static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) 438{ 439 struct gdth_cmndinfo *priv = NULL; 440 ulong flags; 441 int i; 442 443 spin_lock_irqsave(&ha->smp_lock, flags); 444 445 for (i=0; i<GDTH_MAXCMDS; ++i) { 446 if (ha->cmndinfo[i].index == 0) { 447 priv = &ha->cmndinfo[i]; 448 priv->index = i+1; 449 memset(priv, 0, sizeof(*priv)); 450 break; 451 } 452 } 453 454 spin_unlock_irqrestore(&ha->smp_lock, flags); 455 456 return priv; 457} 458 459static void gdth_put_cmndinfo(struct gdth_cmndinfo *priv) 460{ 461 BUG_ON(!priv); 462 priv->index = 0; 463} 464 465static void gdth_delay(int milliseconds) 466{ 467 if (milliseconds == 0) { 468 udelay(1); 469 } else { 470 mdelay(milliseconds); 471 } 472} 473 474static void gdth_scsi_done(struct scsi_cmnd *scp) 475{ 476 struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); 477 int internal_command = cmndinfo->internal_command; 478 479 TRACE2(("gdth_scsi_done()\n")); 480 481 gdth_put_cmndinfo(cmndinfo); 482 scp->host_scribble = NULL; 483 484 if (internal_command) 485 complete((struct completion *)scp->request); 486 else 487 scp->scsi_done(scp); 488} 489 490int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, 491 int timeout, u32 *info) 492{ 493 gdth_ha_str *ha = shost_priv(sdev->host); 494 Scsi_Cmnd *scp; 495 struct gdth_cmndinfo cmndinfo; 496 struct scatterlist one_sg; 497 DECLARE_COMPLETION_ONSTACK(wait); 498 int rval; 499 500 scp = kzalloc(sizeof(*scp), GFP_KERNEL); 501 if (!scp) 502 return -ENOMEM; 503 504 scp->device = sdev; 505 memset(&cmndinfo, 0, sizeof(cmndinfo)); 506 507 /* use request field to save the ptr. to completion struct. */ 508 scp->request = (struct request *)&wait; 509 scp->timeout_per_command = timeout*HZ; 510 sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd)); 511 gdth_set_sglist(scp, &one_sg); 512 gdth_set_sg_count(scp, 1); 513 gdth_set_bufflen(scp, sizeof(*gdtcmd)); 514 scp->cmd_len = 12; 515 memcpy(scp->cmnd, cmnd, 12); 516 cmndinfo.priority = IOCTL_PRI; 517 cmndinfo.internal_command = 1; 518 519 TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); 520 __gdth_queuecommand(ha, scp, &cmndinfo); 521 522 wait_for_completion(&wait); 523 524 rval = cmndinfo.status; 525 if (info) 526 *info = cmndinfo.info; 527 kfree(scp); 528 return rval; 529} 530 531int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, 532 int timeout, u32 *info) 533{ 534 struct scsi_device *sdev = scsi_get_host_dev(shost); 535 int rval = __gdth_execute(sdev, gdtcmd, cmnd, timeout, info); 536 537 scsi_free_host_dev(sdev); 538 return rval; 539} 540 541static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs) 542{ 543 *cyls = size /HEADS/SECS; 544 if (*cyls <= MAXCYLS) { 545 *heads = HEADS; 546 *secs = SECS; 547 } else { /* too high for 64*32 */ 548 *cyls = size /MEDHEADS/MEDSECS; 549 if (*cyls <= MAXCYLS) { 550 *heads = MEDHEADS; 551 *secs = MEDSECS; 552 } else { /* too high for 127*63 */ 553 *cyls = size /BIGHEADS/BIGSECS; 554 *heads = BIGHEADS; 555 *secs = BIGSECS; 556 } 557 } 558} 559 560/* controller search and initialization functions */ 561#ifdef CONFIG_EISA 562static int __init gdth_search_eisa(ushort eisa_adr) 563{ 564 ulong32 id; 565 566 TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr)); 567 id = inl(eisa_adr+ID0REG); 568 if (id == GDT3A_ID || id == GDT3B_ID) { /* GDT3000A or GDT3000B */ 569 if ((inb(eisa_adr+EISAREG) & 8) == 0) 570 return 0; /* not EISA configured */ 571 return 1; 572 } 573 if (id == GDT3_ID) /* GDT3000 */ 574 return 1; 575 576 return 0; 577} 578#endif /* CONFIG_EISA */ 579 580#ifdef CONFIG_ISA 581static int __init gdth_search_isa(ulong32 bios_adr) 582{ 583 void __iomem *addr; 584 ulong32 id; 585 586 TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr)); 587 if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) { 588 id = readl(addr); 589 iounmap(addr); 590 if (id == GDT2_ID) /* GDT2000 */ 591 return 1; 592 } 593 return 0; 594} 595#endif /* CONFIG_ISA */ 596 597#ifdef CONFIG_PCI 598static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, 599 ushort vendor, ushort dev); 600 601static int __init gdth_search_pci(gdth_pci_str *pcistr) 602{ 603 ushort device, cnt; 604 605 TRACE(("gdth_search_pci()\n")); 606 607 cnt = 0; 608 for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device) 609 gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device); 610 for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP; 611 device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device) 612 gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device); 613 gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, 614 PCI_DEVICE_ID_VORTEX_GDTNEWRX); 615 gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, 616 PCI_DEVICE_ID_VORTEX_GDTNEWRX2); 617 gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL, 618 PCI_DEVICE_ID_INTEL_SRC); 619 gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL, 620 PCI_DEVICE_ID_INTEL_SRC_XSCALE); 621 return cnt; 622} 623 624/* Vortex only makes RAID controllers. 625 * We do not really want to specify all 550 ids here, so wildcard match. 626 */ 627static struct pci_device_id gdthtable[] __maybe_unused = { 628 {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID}, 629 {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, 630 {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, 631 {0} 632}; 633MODULE_DEVICE_TABLE(pci,gdthtable); 634 635static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, 636 ushort vendor, ushort device) 637{ 638 ulong base0, base1, base2; 639 struct pci_dev *pdev; 640 641 TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n", 642 *cnt, vendor, device)); 643 644 pdev = NULL; 645 while ((pdev = pci_find_device(vendor, device, pdev)) 646 != NULL) { 647 if (pci_enable_device(pdev)) 648 continue; 649 if (*cnt >= MAXHA) 650 return; 651 /* GDT PCI controller found, resources are already in pdev */ 652 pcistr[*cnt].pdev = pdev; 653 pcistr[*cnt].irq = pdev->irq; 654 base0 = pci_resource_flags(pdev, 0); 655 base1 = pci_resource_flags(pdev, 1); 656 base2 = pci_resource_flags(pdev, 2); 657 if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ 658 device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ 659 if (!(base0 & IORESOURCE_MEM)) 660 continue; 661 pcistr[*cnt].dpmem = pci_resource_start(pdev, 0); 662 } else { /* GDT6110, GDT6120, .. */ 663 if (!(base0 & IORESOURCE_MEM) || 664 !(base2 & IORESOURCE_MEM) || 665 !(base1 & IORESOURCE_IO)) 666 continue; 667 pcistr[*cnt].dpmem = pci_resource_start(pdev, 2); 668 pcistr[*cnt].io_mm = pci_resource_start(pdev, 0); 669 pcistr[*cnt].io = pci_resource_start(pdev, 1); 670 } 671 TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", 672 pcistr[*cnt].pdev->bus->number, 673 PCI_SLOT(pcistr[*cnt].pdev->devfn), 674 pcistr[*cnt].irq, pcistr[*cnt].dpmem)); 675 (*cnt)++; 676 } 677} 678 679static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) 680{ 681 gdth_pci_str temp; 682 int i, changed; 683 684 TRACE(("gdth_sort_pci() cnt %d\n",cnt)); 685 if (cnt == 0) 686 return; 687 688 do { 689 changed = FALSE; 690 for (i = 0; i < cnt-1; ++i) { 691 if (!reverse_scan) { 692 if ((pcistr[i].pdev->bus->number > pcistr[i+1].pdev->bus->number) || 693 (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number && 694 PCI_SLOT(pcistr[i].pdev->devfn) > 695 PCI_SLOT(pcistr[i+1].pdev->devfn))) { 696 temp = pcistr[i]; 697 pcistr[i] = pcistr[i+1]; 698 pcistr[i+1] = temp; 699 changed = TRUE; 700 } 701 } else { 702 if ((pcistr[i].pdev->bus->number < pcistr[i+1].pdev->bus->number) || 703 (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number && 704 PCI_SLOT(pcistr[i].pdev->devfn) < 705 PCI_SLOT(pcistr[i+1].pdev->devfn))) { 706 temp = pcistr[i]; 707 pcistr[i] = pcistr[i+1]; 708 pcistr[i+1] = temp; 709 changed = TRUE; 710 } 711 } 712 } 713 } while (changed); 714} 715#endif /* CONFIG_PCI */ 716 717#ifdef CONFIG_EISA 718static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) 719{ 720 ulong32 retries,id; 721 unchar prot_ver,eisacf,i,irq_found; 722 723 TRACE(("gdth_init_eisa() adr. %x\n",eisa_adr)); 724 725 /* disable board interrupts, deinitialize services */ 726 outb(0xff,eisa_adr+EDOORREG); 727 outb(0x00,eisa_adr+EDENABREG); 728 outb(0x00,eisa_adr+EINTENABREG); 729 730 outb(0xff,eisa_adr+LDOORREG); 731 retries = INIT_RETRIES; 732 gdth_delay(20); 733 while (inb(eisa_adr+EDOORREG) != 0xff) { 734 if (--retries == 0) { 735 printk("GDT-EISA: Initialization error (DEINIT failed)\n"); 736 return 0; 737 } 738 gdth_delay(1); 739 TRACE2(("wait for DEINIT: retries=%d\n",retries)); 740 } 741 prot_ver = inb(eisa_adr+MAILBOXREG); 742 outb(0xff,eisa_adr+EDOORREG); 743 if (prot_ver != PROTOCOL_VERSION) { 744 printk("GDT-EISA: Illegal protocol version\n"); 745 return 0; 746 } 747 ha->bmic = eisa_adr; 748 ha->brd_phys = (ulong32)eisa_adr >> 12; 749 750 outl(0,eisa_adr+MAILBOXREG); 751 outl(0,eisa_adr+MAILBOXREG+4); 752 outl(0,eisa_adr+MAILBOXREG+8); 753 outl(0,eisa_adr+MAILBOXREG+12); 754 755 /* detect IRQ */ 756 if ((id = inl(eisa_adr+ID0REG)) == GDT3_ID) { 757 ha->oem_id = OEM_ID_ICP; 758 ha->type = GDT_EISA; 759 ha->stype = id; 760 outl(1,eisa_adr+MAILBOXREG+8); 761 outb(0xfe,eisa_adr+LDOORREG); 762 retries = INIT_RETRIES; 763 gdth_delay(20); 764 while (inb(eisa_adr+EDOORREG) != 0xfe) { 765 if (--retries == 0) { 766 printk("GDT-EISA: Initialization error (get IRQ failed)\n"); 767 return 0; 768 } 769 gdth_delay(1); 770 } 771 ha->irq = inb(eisa_adr+MAILBOXREG); 772 outb(0xff,eisa_adr+EDOORREG); 773 TRACE2(("GDT3000/3020: IRQ=%d\n",ha->irq)); 774 /* check the result */ 775 if (ha->irq == 0) { 776 TRACE2(("Unknown IRQ, use IRQ table from cmd line !\n")); 777 for (i = 0, irq_found = FALSE; 778 i < MAXHA && irq[i] != 0xff; ++i) { 779 if (irq[i]==10 || irq[i]==11 || irq[i]==12 || irq[i]==14) { 780 irq_found = TRUE; 781 break; 782 } 783 } 784 if (irq_found) { 785 ha->irq = irq[i]; 786 irq[i] = 0; 787 printk("GDT-EISA: Can not detect controller IRQ,\n"); 788 printk("Use IRQ setting from command line (IRQ = %d)\n", 789 ha->irq); 790 } else { 791 printk("GDT-EISA: Initialization error (unknown IRQ), Enable\n"); 792 printk("the controller BIOS or use command line parameters\n"); 793 return 0; 794 } 795 } 796 } else { 797 eisacf = inb(eisa_adr+EISAREG) & 7; 798 if (eisacf > 4) /* level triggered */ 799 eisacf -= 4; 800 ha->irq = gdth_irq_tab[eisacf]; 801 ha->oem_id = OEM_ID_ICP; 802 ha->type = GDT_EISA; 803 ha->stype = id; 804 } 805 806 ha->dma64_support = 0; 807 return 1; 808} 809#endif /* CONFIG_EISA */ 810 811#ifdef CONFIG_ISA 812static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) 813{ 814 register gdt2_dpram_str __iomem *dp2_ptr; 815 int i; 816 unchar irq_drq,prot_ver; 817 ulong32 retries; 818 819 TRACE(("gdth_init_isa() bios adr. %x\n",bios_adr)); 820 821 ha->brd = ioremap(bios_adr, sizeof(gdt2_dpram_str)); 822 if (ha->brd == NULL) { 823 printk("GDT-ISA: Initialization error (DPMEM remap error)\n"); 824 return 0; 825 } 826 dp2_ptr = ha->brd; 827 writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */ 828 /* reset interface area */ 829 memset_io(&dp2_ptr->u, 0, sizeof(dp2_ptr->u)); 830 if (readl(&dp2_ptr->u) != 0) { 831 printk("GDT-ISA: Initialization error (DPMEM write error)\n"); 832 iounmap(ha->brd); 833 return 0; 834 } 835 836 /* disable board interrupts, read DRQ and IRQ */ 837 writeb(0xff, &dp2_ptr->io.irqdel); 838 writeb(0x00, &dp2_ptr->io.irqen); 839 writeb(0x00, &dp2_ptr->u.ic.S_Status); 840 writeb(0x00, &dp2_ptr->u.ic.Cmd_Index); 841 842 irq_drq = readb(&dp2_ptr->io.rq); 843 for (i=0; i<3; ++i) { 844 if ((irq_drq & 1)==0) 845 break; 846 irq_drq >>= 1; 847 } 848 ha->drq = gdth_drq_tab[i]; 849 850 irq_drq = readb(&dp2_ptr->io.rq) >> 3; 851 for (i=1; i<5; ++i) { 852 if ((irq_drq & 1)==0) 853 break; 854 irq_drq >>= 1; 855 } 856 ha->irq = gdth_irq_tab[i]; 857 858 /* deinitialize services */ 859 writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]); 860 writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx); 861 writeb(0, &dp2_ptr->io.event); 862 retries = INIT_RETRIES; 863 gdth_delay(20); 864 while (readb(&dp2_ptr->u.ic.S_Status) != 0xff) { 865 if (--retries == 0) { 866 printk("GDT-ISA: Initialization error (DEINIT failed)\n"); 867 iounmap(ha->brd); 868 return 0; 869 } 870 gdth_delay(1); 871 } 872 prot_ver = (unchar)readl(&dp2_ptr->u.ic.S_Info[0]); 873 writeb(0, &dp2_ptr->u.ic.Status); 874 writeb(0xff, &dp2_ptr->io.irqdel); 875 if (prot_ver != PROTOCOL_VERSION) { 876 printk("GDT-ISA: Illegal protocol version\n"); 877 iounmap(ha->brd); 878 return 0; 879 } 880 881 ha->oem_id = OEM_ID_ICP; 882 ha->type = GDT_ISA; 883 ha->ic_all_size = sizeof(dp2_ptr->u); 884 ha->stype= GDT2_ID; 885 ha->brd_phys = bios_adr >> 4; 886 887 /* special request to controller BIOS */ 888 writel(0x00, &dp2_ptr->u.ic.S_Info[0]); 889 writel(0x00, &dp2_ptr->u.ic.S_Info[1]); 890 writel(0x01, &dp2_ptr->u.ic.S_Info[2]); 891 writel(0x00, &dp2_ptr->u.ic.S_Info[3]); 892 writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx); 893 writeb(0, &dp2_ptr->io.event); 894 retries = INIT_RETRIES; 895 gdth_delay(20); 896 while (readb(&dp2_ptr->u.ic.S_Status) != 0xfe) { 897 if (--retries == 0) { 898 printk("GDT-ISA: Initialization error\n"); 899 iounmap(ha->brd); 900 return 0; 901 } 902 gdth_delay(1); 903 } 904 writeb(0, &dp2_ptr->u.ic.Status); 905 writeb(0xff, &dp2_ptr->io.irqdel); 906 907 ha->dma64_support = 0; 908 return 1; 909} 910#endif /* CONFIG_ISA */ 911 912#ifdef CONFIG_PCI 913static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) 914{ 915 register gdt6_dpram_str __iomem *dp6_ptr; 916 register gdt6c_dpram_str __iomem *dp6c_ptr; 917 register gdt6m_dpram_str __iomem *dp6m_ptr; 918 ulong32 retries; 919 unchar prot_ver; 920 ushort command; 921 int i, found = FALSE; 922 923 TRACE(("gdth_init_pci()\n")); 924 925 if (pcistr->pdev->vendor == PCI_VENDOR_ID_INTEL) 926 ha->oem_id = OEM_ID_INTEL; 927 else 928 ha->oem_id = OEM_ID_ICP; 929 ha->brd_phys = (pcistr->pdev->bus->number << 8) | (pcistr->pdev->devfn & 0xf8); 930 ha->stype = (ulong32)pcistr->pdev->device; 931 ha->irq = pcistr->irq; 932 ha->pdev = pcistr->pdev; 933 934 if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ 935 TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); 936 ha->brd = ioremap(pcistr->dpmem, sizeof(gdt6_dpram_str)); 937 if (ha->brd == NULL) { 938 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 939 return 0; 940 } 941 /* check and reset interface area */ 942 dp6_ptr = ha->brd; 943 writel(DPMEM_MAGIC, &dp6_ptr->u); 944 if (readl(&dp6_ptr->u) != DPMEM_MAGIC) { 945 printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", 946 pcistr->dpmem); 947 found = FALSE; 948 for (i = 0xC8000; i < 0xE8000; i += 0x4000) { 949 iounmap(ha->brd); 950 ha->brd = ioremap(i, sizeof(ushort)); 951 if (ha->brd == NULL) { 952 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 953 return 0; 954 } 955 if (readw(ha->brd) != 0xffff) { 956 TRACE2(("init_pci_old() address 0x%x busy\n", i)); 957 continue; 958 } 959 iounmap(ha->brd); 960 pci_write_config_dword(pcistr->pdev, 961 PCI_BASE_ADDRESS_0, i); 962 ha->brd = ioremap(i, sizeof(gdt6_dpram_str)); 963 if (ha->brd == NULL) { 964 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 965 return 0; 966 } 967 dp6_ptr = ha->brd; 968 writel(DPMEM_MAGIC, &dp6_ptr->u); 969 if (readl(&dp6_ptr->u) == DPMEM_MAGIC) { 970 printk("GDT-PCI: Use free address at 0x%x\n", i); 971 found = TRUE; 972 break; 973 } 974 } 975 if (!found) { 976 printk("GDT-PCI: No free address found!\n"); 977 iounmap(ha->brd); 978 return 0; 979 } 980 } 981 memset_io(&dp6_ptr->u, 0, sizeof(dp6_ptr->u)); 982 if (readl(&dp6_ptr->u) != 0) { 983 printk("GDT-PCI: Initialization error (DPMEM write error)\n"); 984 iounmap(ha->brd); 985 return 0; 986 } 987 988 /* disable board interrupts, deinit services */ 989 writeb(0xff, &dp6_ptr->io.irqdel); 990 writeb(0x00, &dp6_ptr->io.irqen); 991 writeb(0x00, &dp6_ptr->u.ic.S_Status); 992 writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); 993 994 writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); 995 writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); 996 writeb(0, &dp6_ptr->io.event); 997 retries = INIT_RETRIES; 998 gdth_delay(20); 999 while (readb(&dp6_ptr->u.ic.S_Status) != 0xff) { 1000 if (--retries == 0) { 1001 printk("GDT-PCI: Initialization error (DEINIT failed)\n"); 1002 iounmap(ha->brd); 1003 return 0; 1004 } 1005 gdth_delay(1); 1006 } 1007 prot_ver = (unchar)readl(&dp6_ptr->u.ic.S_Info[0]); 1008 writeb(0, &dp6_ptr->u.ic.S_Status); 1009 writeb(0xff, &dp6_ptr->io.irqdel); 1010 if (prot_ver != PROTOCOL_VERSION) { 1011 printk("GDT-PCI: Illegal protocol version\n"); 1012 iounmap(ha->brd); 1013 return 0; 1014 } 1015 1016 ha->type = GDT_PCI; 1017 ha->ic_all_size = sizeof(dp6_ptr->u); 1018 1019 /* special command to controller BIOS */ 1020 writel(0x00, &dp6_ptr->u.ic.S_Info[0]); 1021 writel(0x00, &dp6_ptr->u.ic.S_Info[1]); 1022 writel(0x00, &dp6_ptr->u.ic.S_Info[2]); 1023 writel(0x00, &dp6_ptr->u.ic.S_Info[3]); 1024 writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); 1025 writeb(0, &dp6_ptr->io.event); 1026 retries = INIT_RETRIES; 1027 gdth_delay(20); 1028 while (readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { 1029 if (--retries == 0) { 1030 printk("GDT-PCI: Initialization error\n"); 1031 iounmap(ha->brd); 1032 return 0; 1033 } 1034 gdth_delay(1); 1035 } 1036 writeb(0, &dp6_ptr->u.ic.S_Status); 1037 writeb(0xff, &dp6_ptr->io.irqdel); 1038 1039 ha->dma64_support = 0; 1040 1041 } else if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6555) { /* GDT6110, ... */ 1042 ha->plx = (gdt6c_plx_regs *)pcistr->io; 1043 TRACE2(("init_pci_new() dpmem %lx irq %d\n", 1044 pcistr->dpmem,ha->irq)); 1045 ha->brd = ioremap(pcistr->dpmem, sizeof(gdt6c_dpram_str)); 1046 if (ha->brd == NULL) { 1047 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1048 iounmap(ha->brd); 1049 return 0; 1050 } 1051 /* check and reset interface area */ 1052 dp6c_ptr = ha->brd; 1053 writel(DPMEM_MAGIC, &dp6c_ptr->u); 1054 if (readl(&dp6c_ptr->u) != DPMEM_MAGIC) { 1055 printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", 1056 pcistr->dpmem); 1057 found = FALSE; 1058 for (i = 0xC8000; i < 0xE8000; i += 0x4000) { 1059 iounmap(ha->brd); 1060 ha->brd = ioremap(i, sizeof(ushort)); 1061 if (ha->brd == NULL) { 1062 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1063 return 0; 1064 } 1065 if (readw(ha->brd) != 0xffff) { 1066 TRACE2(("init_pci_plx() address 0x%x busy\n", i)); 1067 continue; 1068 } 1069 iounmap(ha->brd); 1070 pci_write_config_dword(pcistr->pdev, 1071 PCI_BASE_ADDRESS_2, i); 1072 ha->brd = ioremap(i, sizeof(gdt6c_dpram_str)); 1073 if (ha->brd == NULL) { 1074 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1075 return 0; 1076 } 1077 dp6c_ptr = ha->brd; 1078 writel(DPMEM_MAGIC, &dp6c_ptr->u); 1079 if (readl(&dp6c_ptr->u) == DPMEM_MAGIC) { 1080 printk("GDT-PCI: Use free address at 0x%x\n", i); 1081 found = TRUE; 1082 break; 1083 } 1084 } 1085 if (!found) { 1086 printk("GDT-PCI: No free address found!\n"); 1087 iounmap(ha->brd); 1088 return 0; 1089 } 1090 } 1091 memset_io(&dp6c_ptr->u, 0, sizeof(dp6c_ptr->u)); 1092 if (readl(&dp6c_ptr->u) != 0) { 1093 printk("GDT-PCI: Initialization error (DPMEM write error)\n"); 1094 iounmap(ha->brd); 1095 return 0; 1096 } 1097 1098 /* disable board interrupts, deinit services */ 1099 outb(0x00,PTR2USHORT(&ha->plx->control1)); 1100 outb(0xff,PTR2USHORT(&ha->plx->edoor_reg)); 1101 1102 writeb(0x00, &dp6c_ptr->u.ic.S_Status); 1103 writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); 1104 1105 writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); 1106 writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); 1107 1108 outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); 1109 1110 retries = INIT_RETRIES; 1111 gdth_delay(20); 1112 while (readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { 1113 if (--retries == 0) { 1114 printk("GDT-PCI: Initialization error (DEINIT failed)\n"); 1115 iounmap(ha->brd); 1116 return 0; 1117 } 1118 gdth_delay(1); 1119 } 1120 prot_ver = (unchar)readl(&dp6c_ptr->u.ic.S_Info[0]); 1121 writeb(0, &dp6c_ptr->u.ic.Status); 1122 if (prot_ver != PROTOCOL_VERSION) { 1123 printk("GDT-PCI: Illegal protocol version\n"); 1124 iounmap(ha->brd); 1125 return 0; 1126 } 1127 1128 ha->type = GDT_PCINEW; 1129 ha->ic_all_size = sizeof(dp6c_ptr->u); 1130 1131 /* special command to controller BIOS */ 1132 writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); 1133 writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); 1134 writel(0x00, &dp6c_ptr->u.ic.S_Info[2]); 1135 writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); 1136 writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); 1137 1138 outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); 1139 1140 retries = INIT_RETRIES; 1141 gdth_delay(20); 1142 while (readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { 1143 if (--retries == 0) { 1144 printk("GDT-PCI: Initialization error\n"); 1145 iounmap(ha->brd); 1146 return 0; 1147 } 1148 gdth_delay(1); 1149 } 1150 writeb(0, &dp6c_ptr->u.ic.S_Status); 1151 1152 ha->dma64_support = 0; 1153 1154 } else { /* MPR */ 1155 TRACE2(("init_pci_mpr() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); 1156 ha->brd = ioremap(pcistr->dpmem, sizeof(gdt6m_dpram_str)); 1157 if (ha->brd == NULL) { 1158 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1159 return 0; 1160 } 1161 1162 /* manipulate config. space to enable DPMEM, start RP controller */ 1163 pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command); 1164 command |= 6; 1165 pci_write_config_word(pcistr->pdev, PCI_COMMAND, command); 1166 if (pci_resource_start(pcistr->pdev, 8) == 1UL) 1167 pci_resource_start(pcistr->pdev, 8) = 0UL; 1168 i = 0xFEFF0001UL; 1169 pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i); 1170 gdth_delay(1); 1171 pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, 1172 pci_resource_start(pcistr->pdev, 8)); 1173 1174 dp6m_ptr = ha->brd; 1175 1176 /* Ensure that it is safe to access the non HW portions of DPMEM. 1177 * Aditional check needed for Xscale based RAID controllers */ 1178 while( ((int)readb(&dp6m_ptr->i960r.sema0_reg) ) & 3 ) 1179 gdth_delay(1); 1180 1181 /* check and reset interface area */ 1182 writel(DPMEM_MAGIC, &dp6m_ptr->u); 1183 if (readl(&dp6m_ptr->u) != DPMEM_MAGIC) { 1184 printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", 1185 pcistr->dpmem); 1186 found = FALSE; 1187 for (i = 0xC8000; i < 0xE8000; i += 0x4000) { 1188 iounmap(ha->brd); 1189 ha->brd = ioremap(i, sizeof(ushort)); 1190 if (ha->brd == NULL) { 1191 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1192 return 0; 1193 } 1194 if (readw(ha->brd) != 0xffff) { 1195 TRACE2(("init_pci_mpr() address 0x%x busy\n", i)); 1196 continue; 1197 } 1198 iounmap(ha->brd); 1199 pci_write_config_dword(pcistr->pdev, 1200 PCI_BASE_ADDRESS_0, i); 1201 ha->brd = ioremap(i, sizeof(gdt6m_dpram_str)); 1202 if (ha->brd == NULL) { 1203 printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); 1204 return 0; 1205 } 1206 dp6m_ptr = ha->brd; 1207 writel(DPMEM_MAGIC, &dp6m_ptr->u); 1208 if (readl(&dp6m_ptr->u) == DPMEM_MAGIC) { 1209 printk("GDT-PCI: Use free address at 0x%x\n", i); 1210 found = TRUE; 1211 break; 1212 } 1213 } 1214 if (!found) { 1215 printk("GDT-PCI: No free address found!\n"); 1216 iounmap(ha->brd); 1217 return 0; 1218 } 1219 } 1220 memset_io(&dp6m_ptr->u, 0, sizeof(dp6m_ptr->u)); 1221 1222 /* disable board interrupts, deinit services */ 1223 writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, 1224 &dp6m_ptr->i960r.edoor_en_reg); 1225 writeb(0xff, &dp6m_ptr->i960r.edoor_reg); 1226 writeb(0x00, &dp6m_ptr->u.ic.S_Status); 1227 writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); 1228 1229 writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); 1230 writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); 1231 writeb(1, &dp6m_ptr->i960r.ldoor_reg); 1232 retries = INIT_RETRIES; 1233 gdth_delay(20); 1234 while (readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { 1235 if (--retries == 0) { 1236 printk("GDT-PCI: Initialization error (DEINIT failed)\n"); 1237 iounmap(ha->brd); 1238 return 0; 1239 } 1240 gdth_delay(1); 1241 } 1242 prot_ver = (unchar)readl(&dp6m_ptr->u.ic.S_Info[0]); 1243 writeb(0, &dp6m_ptr->u.ic.S_Status); 1244 if (prot_ver != PROTOCOL_VERSION) { 1245 printk("GDT-PCI: Illegal protocol version\n"); 1246 iounmap(ha->brd); 1247 return 0; 1248 } 1249 1250 ha->type = GDT_PCIMPR; 1251 ha->ic_all_size = sizeof(dp6m_ptr->u); 1252 1253 /* special command to controller BIOS */ 1254 writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); 1255 writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); 1256 writel(0x00, &dp6m_ptr->u.ic.S_Info[2]); 1257 writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); 1258 writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); 1259 writeb(1, &dp6m_ptr->i960r.ldoor_reg); 1260 retries = INIT_RETRIES; 1261 gdth_delay(20); 1262 while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { 1263 if (--retries == 0) { 1264 printk("GDT-PCI: Initialization error\n"); 1265 iounmap(ha->brd); 1266 return 0; 1267 } 1268 gdth_delay(1); 1269 } 1270 writeb(0, &dp6m_ptr->u.ic.S_Status); 1271 1272 /* read FW version to detect 64-bit DMA support */ 1273 writeb(0xfd, &dp6m_ptr->u.ic.S_Cmd_Indx); 1274 writeb(1, &dp6m_ptr->i960r.ldoor_reg); 1275 retries = INIT_RETRIES; 1276 gdth_delay(20); 1277 while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfd) { 1278 if (--retries == 0) { 1279 printk("GDT-PCI: Initialization error (DEINIT failed)\n"); 1280 iounmap(ha->brd); 1281 return 0; 1282 } 1283 gdth_delay(1); 1284 } 1285 prot_ver = (unchar)(readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16); 1286 writeb(0, &dp6m_ptr->u.ic.S_Status); 1287 if (prot_ver < 0x2b) /* FW < x.43: no 64-bit DMA support */ 1288 ha->dma64_support = 0; 1289 else 1290 ha->dma64_support = 1; 1291 } 1292 1293 return 1; 1294} 1295#endif /* CONFIG_PCI */ 1296 1297/* controller protocol functions */ 1298 1299static void __init gdth_enable_int(gdth_ha_str *ha) 1300{ 1301 ulong flags; 1302 gdt2_dpram_str __iomem *dp2_ptr; 1303 gdt6_dpram_str __iomem *dp6_ptr; 1304 gdt6m_dpram_str __iomem *dp6m_ptr; 1305 1306 TRACE(("gdth_enable_int() hanum %d\n",ha->hanum)); 1307 spin_lock_irqsave(&ha->smp_lock, flags); 1308 1309 if (ha->type == GDT_EISA) { 1310 outb(0xff, ha->bmic + EDOORREG); 1311 outb(0xff, ha->bmic + EDENABREG); 1312 outb(0x01, ha->bmic + EINTENABREG); 1313 } else if (ha->type == GDT_ISA) { 1314 dp2_ptr = ha->brd; 1315 writeb(1, &dp2_ptr->io.irqdel); 1316 writeb(0, &dp2_ptr->u.ic.Cmd_Index); 1317 writeb(1, &dp2_ptr->io.irqen); 1318 } else if (ha->type == GDT_PCI) { 1319 dp6_ptr = ha->brd; 1320 writeb(1, &dp6_ptr->io.irqdel); 1321 writeb(0, &dp6_ptr->u.ic.Cmd_Index); 1322 writeb(1, &dp6_ptr->io.irqen); 1323 } else if (ha->type == GDT_PCINEW) { 1324 outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); 1325 outb(0x03, PTR2USHORT(&ha->plx->control1)); 1326 } else if (ha->type == GDT_PCIMPR) { 1327 dp6m_ptr = ha->brd; 1328 writeb(0xff, &dp6m_ptr->i960r.edoor_reg); 1329 writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, 1330 &dp6m_ptr->i960r.edoor_en_reg); 1331 } 1332 spin_unlock_irqrestore(&ha->smp_lock, flags); 1333} 1334 1335/* return IStatus if interrupt was from this card else 0 */ 1336static unchar gdth_get_status(gdth_ha_str *ha) 1337{ 1338 unchar IStatus = 0; 1339 1340 TRACE(("gdth_get_status() irq %d ctr_count %d\n", ha->irq, gdth_ctr_count)); 1341 1342 if (ha->type == GDT_EISA) 1343 IStatus = inb((ushort)ha->bmic + EDOORREG); 1344 else if (ha->type == GDT_ISA) 1345 IStatus = 1346 readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); 1347 else if (ha->type == GDT_PCI) 1348 IStatus = 1349 readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); 1350 else if (ha->type == GDT_PCINEW) 1351 IStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); 1352 else if (ha->type == GDT_PCIMPR) 1353 IStatus = 1354 readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); 1355 1356 return IStatus; 1357} 1358 1359static int gdth_test_busy(gdth_ha_str *ha) 1360{ 1361 register int gdtsema0 = 0; 1362 1363 TRACE(("gdth_test_busy() hanum %d\n", ha->hanum)); 1364 1365 if (ha->type == GDT_EISA) 1366 gdtsema0 = (int)inb(ha->bmic + SEMA0REG); 1367 else if (ha->type == GDT_ISA) 1368 gdtsema0 = (int)readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); 1369 else if (ha->type == GDT_PCI) 1370 gdtsema0 = (int)readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); 1371 else if (ha->type == GDT_PCINEW) 1372 gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg)); 1373 else if (ha->type == GDT_PCIMPR) 1374 gdtsema0 = 1375 (int)readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); 1376 1377 return (gdtsema0 & 1); 1378} 1379 1380 1381static int gdth_get_cmd_index(gdth_ha_str *ha) 1382{ 1383 int i; 1384 1385 TRACE(("gdth_get_cmd_index() hanum %d\n", ha->hanum)); 1386 1387 for (i=0; i<GDTH_MAXCMDS; ++i) { 1388 if (ha->cmd_tab[i].cmnd == UNUSED_CMND) { 1389 ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer; 1390 ha->cmd_tab[i].service = ha->pccb->Service; 1391 ha->pccb->CommandIndex = (ulong32)i+2; 1392 return (i+2); 1393 } 1394 } 1395 return 0; 1396} 1397 1398 1399static void gdth_set_sema0(gdth_ha_str *ha) 1400{ 1401 TRACE(("gdth_set_sema0() hanum %d\n", ha->hanum)); 1402 1403 if (ha->type == GDT_EISA) { 1404 outb(1, ha->bmic + SEMA0REG); 1405 } else if (ha->type == GDT_ISA) { 1406 writeb(1, &((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); 1407 } else if (ha->type == GDT_PCI) { 1408 writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); 1409 } else if (ha->type == GDT_PCINEW) { 1410 outb(1, PTR2USHORT(&ha->plx->sema0_reg)); 1411 } else if (ha->type == GDT_PCIMPR) { 1412 writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); 1413 } 1414} 1415 1416 1417static void gdth_copy_command(gdth_ha_str *ha) 1418{ 1419 register gdth_cmd_str *cmd_ptr; 1420 register gdt6m_dpram_str __iomem *dp6m_ptr; 1421 register gdt6c_dpram_str __iomem *dp6c_ptr; 1422 gdt6_dpram_str __iomem *dp6_ptr; 1423 gdt2_dpram_str __iomem *dp2_ptr; 1424 ushort cp_count,dp_offset,cmd_no; 1425 1426 TRACE(("gdth_copy_command() hanum %d\n", ha->hanum)); 1427 1428 cp_count = ha->cmd_len; 1429 dp_offset= ha->cmd_offs_dpmem; 1430 cmd_no = ha->cmd_cnt; 1431 cmd_ptr = ha->pccb; 1432 1433 ++ha->cmd_cnt; 1434 if (ha->type == GDT_EISA) 1435 return; /* no DPMEM, no copy */ 1436 1437 /* set cpcount dword aligned */ 1438 if (cp_count & 3) 1439 cp_count += (4 - (cp_count & 3)); 1440 1441 ha->cmd_offs_dpmem += cp_count; 1442 1443 /* set offset and service, copy command to DPMEM */ 1444 if (ha->type == GDT_ISA) { 1445 dp2_ptr = ha->brd; 1446 writew(dp_offset + DPMEM_COMMAND_OFFSET, 1447 &dp2_ptr->u.ic.comm_queue[cmd_no].offset); 1448 writew((ushort)cmd_ptr->Service, 1449 &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id); 1450 memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); 1451 } else if (ha->type == GDT_PCI) { 1452 dp6_ptr = ha->brd; 1453 writew(dp_offset + DPMEM_COMMAND_OFFSET, 1454 &dp6_ptr->u.ic.comm_queue[cmd_no].offset); 1455 writew((ushort)cmd_ptr->Service, 1456 &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id); 1457 memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); 1458 } else if (ha->type == GDT_PCINEW) { 1459 dp6c_ptr = ha->brd; 1460 writew(dp_offset + DPMEM_COMMAND_OFFSET, 1461 &dp6c_ptr->u.ic.comm_queue[cmd_no].offset); 1462 writew((ushort)cmd_ptr->Service, 1463 &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id); 1464 memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); 1465 } else if (ha->type == GDT_PCIMPR) { 1466 dp6m_ptr = ha->brd; 1467 writew(dp_offset + DPMEM_COMMAND_OFFSET, 1468 &dp6m_ptr->u.ic.comm_queue[cmd_no].offset); 1469 writew((ushort)cmd_ptr->Service, 1470 &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id); 1471 memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); 1472 } 1473} 1474 1475 1476static void gdth_release_event(gdth_ha_str *ha) 1477{ 1478 TRACE(("gdth_release_event() hanum %d\n", ha->hanum)); 1479 1480#ifdef GDTH_STATISTICS 1481 { 1482 ulong32 i,j; 1483 for (i=0,j=0; j<GDTH_MAXCMDS; ++j) { 1484 if (ha->cmd_tab[j].cmnd != UNUSED_CMND) 1485 ++i; 1486 } 1487 if (max_index < i) { 1488 max_index = i; 1489 TRACE3(("GDT: max_index = %d\n",(ushort)i)); 1490 } 1491 } 1492#endif 1493 1494 if (ha->pccb->OpCode == GDT_INIT) 1495 ha->pccb->Service |= 0x80; 1496 1497 if (ha->type == GDT_EISA) { 1498 if (ha->pccb->OpCode == GDT_INIT) /* store DMA buffer */ 1499 outl(ha->ccb_phys, ha->bmic + MAILBOXREG); 1500 outb(ha->pccb->Service, ha->bmic + LDOORREG); 1501 } else if (ha->type == GDT_ISA) { 1502 writeb(0, &((gdt2_dpram_str __iomem *)ha->brd)->io.event); 1503 } else if (ha->type == GDT_PCI) { 1504 writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event); 1505 } else if (ha->type == GDT_PCINEW) { 1506 outb(1, PTR2USHORT(&ha->plx->ldoor_reg)); 1507 } else if (ha->type == GDT_PCIMPR) { 1508 writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.ldoor_reg); 1509 } 1510} 1511 1512static int gdth_wait(gdth_ha_str *ha, int index, ulong32 time) 1513{ 1514 int answer_found = FALSE; 1515 int wait_index = 0; 1516 1517 TRACE(("gdth_wait() hanum %d index %d time %d\n", ha->hanum, index, time)); 1518 1519 if (index == 0) 1520 return 1; /* no wait required */ 1521 1522 do { 1523 __gdth_interrupt(ha, true, &wait_index); 1524 if (wait_index == index) { 1525 answer_found = TRUE; 1526 break; 1527 } 1528 gdth_delay(1); 1529 } while (--time); 1530 1531 while (gdth_test_busy(ha)) 1532 gdth_delay(0); 1533 1534 return (answer_found); 1535} 1536 1537 1538static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, 1539 ulong32 p1, ulong64 p2, ulong64 p3) 1540{ 1541 register gdth_cmd_str *cmd_ptr; 1542 int retries,index; 1543 1544 TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode)); 1545 1546 cmd_ptr = ha->pccb; 1547 memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str)); 1548 1549 /* make command */ 1550 for (retries = INIT_RETRIES;;) { 1551 cmd_ptr->Service = service; 1552 cmd_ptr->RequestBuffer = INTERNAL_CMND; 1553 if (!(index=gdth_get_cmd_index(ha))) { 1554 TRACE(("GDT: No free command index found\n")); 1555 return 0; 1556 } 1557 gdth_set_sema0(ha); 1558 cmd_ptr->OpCode = opcode; 1559 cmd_ptr->BoardNode = LOCALBOARD; 1560 if (service == CACHESERVICE) { 1561 if (opcode == GDT_IOCTL) { 1562 cmd_ptr->u.ioctl.subfunc = p1; 1563 cmd_ptr->u.ioctl.channel = (ulong32)p2; 1564 cmd_ptr->u.ioctl.param_size = (ushort)p3; 1565 cmd_ptr->u.ioctl.p_param = ha->scratch_phys; 1566 } else { 1567 if (ha->cache_feat & GDT_64BIT) { 1568 cmd_ptr->u.cache64.DeviceNo = (ushort)p1; 1569 cmd_ptr->u.cache64.BlockNo = p2; 1570 } else { 1571 cmd_ptr->u.cache.DeviceNo = (ushort)p1; 1572 cmd_ptr->u.cache.BlockNo = (ulong32)p2; 1573 } 1574 } 1575 } else if (service == SCSIRAWSERVICE) { 1576 if (ha->raw_feat & GDT_64BIT) { 1577 cmd_ptr->u.raw64.direction = p1; 1578 cmd_ptr->u.raw64.bus = (unchar)p2; 1579 cmd_ptr->u.raw64.target = (unchar)p3; 1580 cmd_ptr->u.raw64.lun = (unchar)(p3 >> 8); 1581 } else { 1582 cmd_ptr->u.raw.direction = p1; 1583 cmd_ptr->u.raw.bus = (unchar)p2; 1584 cmd_ptr->u.raw.target = (unchar)p3; 1585 cmd_ptr->u.raw.lun = (unchar)(p3 >> 8); 1586 } 1587 } else if (service == SCREENSERVICE) { 1588 if (opcode == GDT_REALTIME) { 1589 *(ulong32 *)&cmd_ptr->u.screen.su.data[0] = p1; 1590 *(ulong32 *)&cmd_ptr->u.screen.su.data[4] = (ulong32)p2; 1591 *(ulong32 *)&cmd_ptr->u.screen.su.data[8] = (ulong32)p3; 1592 } 1593 } 1594 ha->cmd_len = sizeof(gdth_cmd_str); 1595 ha->cmd_offs_dpmem = 0; 1596 ha->cmd_cnt = 0; 1597 gdth_copy_command(ha); 1598 gdth_release_event(ha); 1599 gdth_delay(20); 1600 if (!gdth_wait(ha, index, INIT_TIMEOUT)) { 1601 printk("GDT: Initialization error (timeout service %d)\n",service); 1602 return 0; 1603 } 1604 if (ha->status != S_BSY || --retries == 0) 1605 break; 1606 gdth_delay(1); 1607 } 1608 1609 return (ha->status != S_OK ? 0:1); 1610} 1611 1612 1613/* search for devices */ 1614 1615static int __init gdth_search_drives(gdth_ha_str *ha) 1616{ 1617 ushort cdev_cnt, i; 1618 int ok; 1619 ulong32 bus_no, drv_cnt, drv_no, j; 1620 gdth_getch_str *chn; 1621 gdth_drlist_str *drl; 1622 gdth_iochan_str *ioc; 1623 gdth_raw_iochan_str *iocr; 1624 gdth_arcdl_str *alst; 1625 gdth_alist_str *alst2; 1626 gdth_oem_str_ioctl *oemstr; 1627#ifdef INT_COAL 1628 gdth_perf_modes *pmod; 1629#endif 1630 1631#ifdef GDTH_RTC 1632 unchar rtc[12]; 1633 ulong flags; 1634#endif 1635 1636 TRACE(("gdth_search_drives() hanum %d\n", ha->hanum)); 1637 ok = 0; 1638 1639 /* initialize controller services, at first: screen service */ 1640 ha->screen_feat = 0; 1641 if (!force_dma32) { 1642 ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_X_INIT_SCR, 0, 0, 0); 1643 if (ok) 1644 ha->screen_feat = GDT_64BIT; 1645 } 1646 if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) 1647 ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_INIT, 0, 0, 0); 1648 if (!ok) { 1649 printk("GDT-HA %d: Initialization error screen service (code %d)\n", 1650 ha->hanum, ha->status); 1651 return 0; 1652 } 1653 TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n")); 1654 1655#ifdef GDTH_RTC 1656 /* read realtime clock info, send to controller */ 1657 /* 1. wait for the falling edge of update flag */ 1658 spin_lock_irqsave(&rtc_lock, flags); 1659 for (j = 0; j < 1000000; ++j) 1660 if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) 1661 break; 1662 for (j = 0; j < 1000000; ++j) 1663 if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) 1664 break; 1665 /* 2. read info */ 1666 do { 1667 for (j = 0; j < 12; ++j) 1668 rtc[j] = CMOS_READ(j); 1669 } while (rtc[0] != CMOS_READ(0)); 1670 spin_unlock_irqrestore(&rtc_lock, flags); 1671 TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0], 1672 *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8])); 1673 /* 3. send to controller firmware */ 1674 gdth_internal_cmd(ha, SCREENSERVICE, GDT_REALTIME, *(ulong32 *)&rtc[0], 1675 *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]); 1676#endif 1677 1678 /* unfreeze all IOs */ 1679 gdth_internal_cmd(ha, CACHESERVICE, GDT_UNFREEZE_IO, 0, 0, 0); 1680 1681 /* initialize cache service */ 1682 ha->cache_feat = 0; 1683 if (!force_dma32) { 1684 ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INIT_HOST, LINUX_OS, 1685 0, 0); 1686 if (ok) 1687 ha->cache_feat = GDT_64BIT; 1688 } 1689 if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) 1690 ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_INIT, LINUX_OS, 0, 0); 1691 if (!ok) { 1692 printk("GDT-HA %d: Initialization error cache service (code %d)\n", 1693 ha->hanum, ha->status); 1694 return 0; 1695 } 1696 TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n")); 1697 cdev_cnt = (ushort)ha->info; 1698 ha->fw_vers = ha->service; 1699 1700#ifdef INT_COAL 1701 if (ha->type == GDT_PCIMPR) { 1702 /* set perf. modes */ 1703 pmod = (gdth_perf_modes *)ha->pscratch; 1704 pmod->version = 1; 1705 pmod->st_mode = 1; /* enable one status buffer */ 1706 *((ulong64 *)&pmod->st_buff_addr1) = ha->coal_stat_phys; 1707 pmod->st_buff_indx1 = COALINDEX; 1708 pmod->st_buff_addr2 = 0; 1709 pmod->st_buff_u_addr2 = 0; 1710 pmod->st_buff_indx2 = 0; 1711 pmod->st_buff_size = sizeof(gdth_coal_status) * MAXOFFSETS; 1712 pmod->cmd_mode = 0; // disable all cmd buffers 1713 pmod->cmd_buff_addr1 = 0; 1714 pmod->cmd_buff_u_addr1 = 0; 1715 pmod->cmd_buff_indx1 = 0; 1716 pmod->cmd_buff_addr2 = 0; 1717 pmod->cmd_buff_u_addr2 = 0; 1718 pmod->cmd_buff_indx2 = 0; 1719 pmod->cmd_buff_size = 0; 1720 pmod->reserved1 = 0; 1721 pmod->reserved2 = 0; 1722 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, SET_PERF_MODES, 1723 INVALID_CHANNEL,sizeof(gdth_perf_modes))) { 1724 printk("GDT-HA %d: Interrupt coalescing activated\n", ha->hanum); 1725 } 1726 } 1727#endif 1728 1729 /* detect number of buses - try new IOCTL */ 1730 iocr = (gdth_raw_iochan_str *)ha->pscratch; 1731 iocr->hdr.version = 0xffffffff; 1732 iocr->hdr.list_entries = MAXBUS; 1733 iocr->hdr.first_chan = 0; 1734 iocr->hdr.last_chan = MAXBUS-1; 1735 iocr->hdr.list_offset = GDTOFFSOF(gdth_raw_iochan_str, list[0]); 1736 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_RAW_DESC, 1737 INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) { 1738 TRACE2(("IOCHAN_RAW_DESC supported!\n")); 1739 ha->bus_cnt = iocr->hdr.chan_count; 1740 for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { 1741 if (iocr->list[bus_no].proc_id < MAXID) 1742 ha->bus_id[bus_no] = iocr->list[bus_no].proc_id; 1743 else 1744 ha->bus_id[bus_no] = 0xff; 1745 } 1746 } else { 1747 /* old method */ 1748 chn = (gdth_getch_str *)ha->pscratch; 1749 for (bus_no = 0; bus_no < MAXBUS; ++bus_no) { 1750 chn->channel_no = bus_no; 1751 if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, 1752 SCSI_CHAN_CNT | L_CTRL_PATTERN, 1753 IO_CHANNEL | INVALID_CHANNEL, 1754 sizeof(gdth_getch_str))) { 1755 if (bus_no == 0) { 1756 printk("GDT-HA %d: Error detecting channel count (0x%x)\n", 1757 ha->hanum, ha->status); 1758 return 0; 1759 } 1760 break; 1761 } 1762 if (chn->siop_id < MAXID) 1763 ha->bus_id[bus_no] = chn->siop_id; 1764 else 1765 ha->bus_id[bus_no] = 0xff; 1766 } 1767 ha->bus_cnt = (unchar)bus_no; 1768 } 1769 TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt)); 1770 1771 /* read cache configuration */ 1772 if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_INFO, 1773 INVALID_CHANNEL,sizeof(gdth_cinfo_str))) { 1774 printk("GDT-HA %d: Initialization error cache service (code %d)\n", 1775 ha->hanum, ha->status); 1776 return 0; 1777 } 1778 ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar; 1779 TRACE2(("gdth_search_drives() cinfo: vs %x sta %d str %d dw %d b %d\n", 1780 ha->cpar.version,ha->cpar.state,ha->cpar.strategy, 1781 ha->cpar.write_back,ha->cpar.block_size)); 1782 1783 /* read board info and features */ 1784 ha->more_proc = FALSE; 1785 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_INFO, 1786 INVALID_CHANNEL,sizeof(gdth_binfo_str))) { 1787 memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch, 1788 sizeof(gdth_binfo_str)); 1789 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_FEATURES, 1790 INVALID_CHANNEL,sizeof(gdth_bfeat_str))) { 1791 TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n")); 1792 ha->bfeat = *(gdth_bfeat_str *)ha->pscratch; 1793 ha->more_proc = TRUE; 1794 } 1795 } else { 1796 TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n")); 1797 strcpy(ha->binfo.type_string, gdth_ctr_name(ha)); 1798 } 1799 TRACE2(("Controller name: %s\n",ha->binfo.type_string)); 1800 1801 /* read more informations */ 1802 if (ha->more_proc) { 1803 /* physical drives, channel addresses */ 1804 ioc = (gdth_iochan_str *)ha->pscratch; 1805 ioc->hdr.version = 0xffffffff; 1806 ioc->hdr.list_entries = MAXBUS; 1807 ioc->hdr.first_chan = 0; 1808 ioc->hdr.last_chan = MAXBUS-1; 1809 ioc->hdr.list_offset = GDTOFFSOF(gdth_iochan_str, list[0]); 1810 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_DESC, 1811 INVALID_CHANNEL,sizeof(gdth_iochan_str))) { 1812 for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { 1813 ha->raw[bus_no].address = ioc->list[bus_no].address; 1814 ha->raw[bus_no].local_no = ioc->list[bus_no].local_no; 1815 } 1816 } else { 1817 for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { 1818 ha->raw[bus_no].address = IO_CHANNEL; 1819 ha->raw[bus_no].local_no = bus_no; 1820 } 1821 } 1822 for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { 1823 chn = (gdth_getch_str *)ha->pscratch; 1824 chn->channel_no = ha->raw[bus_no].local_no; 1825 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, 1826 SCSI_CHAN_CNT | L_CTRL_PATTERN, 1827 ha->raw[bus_no].address | INVALID_CHANNEL, 1828 sizeof(gdth_getch_str))) { 1829 ha->raw[bus_no].pdev_cnt = chn->drive_cnt; 1830 TRACE2(("Channel %d: %d phys. drives\n", 1831 bus_no,chn->drive_cnt)); 1832 } 1833 if (ha->raw[bus_no].pdev_cnt > 0) { 1834 drl = (gdth_drlist_str *)ha->pscratch; 1835 drl->sc_no = ha->raw[bus_no].local_no; 1836 drl->sc_cnt = ha->raw[bus_no].pdev_cnt; 1837 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, 1838 SCSI_DR_LIST | L_CTRL_PATTERN, 1839 ha->raw[bus_no].address | INVALID_CHANNEL, 1840 sizeof(gdth_drlist_str))) { 1841 for (j = 0; j < ha->raw[bus_no].pdev_cnt; ++j) 1842 ha->raw[bus_no].id_list[j] = drl->sc_list[j]; 1843 } else { 1844 ha->raw[bus_no].pdev_cnt = 0; 1845 } 1846 } 1847 } 1848 1849 /* logical drives */ 1850 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_CNT, 1851 INVALID_CHANNEL,sizeof(ulong32))) { 1852 drv_cnt = *(ulong32 *)ha->pscratch; 1853 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_LIST, 1854 INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) { 1855 for (j = 0; j < drv_cnt; ++j) { 1856 drv_no = ((ulong32 *)ha->pscratch)[j]; 1857 if (drv_no < MAX_LDRIVES) { 1858 ha->hdr[drv_no].is_logdrv = TRUE; 1859 TRACE2(("Drive %d is log. drive\n",drv_no)); 1860 } 1861 } 1862 } 1863 alst = (gdth_arcdl_str *)ha->pscratch; 1864 alst->entries_avail = MAX_LDRIVES; 1865 alst->first_entry = 0; 1866 alst->list_offset = GDTOFFSOF(gdth_arcdl_str, list[0]); 1867 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, 1868 ARRAY_DRV_LIST2 | LA_CTRL_PATTERN, 1869 INVALID_CHANNEL, sizeof(gdth_arcdl_str) + 1870 (alst->entries_avail-1) * sizeof(gdth_alist_str))) { 1871 for (j = 0; j < alst->entries_init; ++j) { 1872 ha->hdr[j].is_arraydrv = alst->list[j].is_arrayd; 1873 ha->hdr[j].is_master = alst->list[j].is_master; 1874 ha->hdr[j].is_parity = alst->list[j].is_parity; 1875 ha->hdr[j].is_hotfix = alst->list[j].is_hotfix; 1876 ha->hdr[j].master_no = alst->list[j].cd_handle; 1877 } 1878 } else if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, 1879 ARRAY_DRV_LIST | LA_CTRL_PATTERN, 1880 0, 35 * sizeof(gdth_alist_str))) { 1881 for (j = 0; j < 35; ++j) { 1882 alst2 = &((gdth_alist_str *)ha->pscratch)[j]; 1883 ha->hdr[j].is_arraydrv = alst2->is_arrayd; 1884 ha->hdr[j].is_master = alst2->is_master; 1885 ha->hdr[j].is_parity = alst2->is_parity; 1886 ha->hdr[j].is_hotfix = alst2->is_hotfix; 1887 ha->hdr[j].master_no = alst2->cd_handle; 1888 } 1889 } 1890 } 1891 } 1892 1893 /* initialize raw service */ 1894 ha->raw_feat = 0; 1895 if (!force_dma32) { 1896 ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_X_INIT_RAW, 0, 0, 0); 1897 if (ok) 1898 ha->raw_feat = GDT_64BIT; 1899 } 1900 if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) 1901 ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_INIT, 0, 0, 0); 1902 if (!ok) { 1903 printk("GDT-HA %d: Initialization error raw service (code %d)\n", 1904 ha->hanum, ha->status); 1905 return 0; 1906 } 1907 TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n")); 1908 1909 /* set/get features raw service (scatter/gather) */ 1910 if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_SET_FEAT, SCATTER_GATHER, 1911 0, 0)) { 1912 TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n")); 1913 if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_GET_FEAT, 0, 0, 0)) { 1914 TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n", 1915 ha->info)); 1916 ha->raw_feat |= (ushort)ha->info; 1917 } 1918 } 1919 1920 /* set/get features cache service (equal to raw service) */ 1921 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_SET_FEAT, 0, 1922 SCATTER_GATHER,0)) { 1923 TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n")); 1924 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_GET_FEAT, 0, 0, 0)) { 1925 TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n", 1926 ha->info)); 1927 ha->cache_feat |= (ushort)ha->info; 1928 } 1929 } 1930 1931 /* reserve drives for raw service */ 1932 if (reserve_mode != 0) { 1933 gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE_ALL, 1934 reserve_mode == 1 ? 1 : 3, 0, 0); 1935 TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", 1936 ha->status)); 1937 } 1938 for (i = 0; i < MAX_RES_ARGS; i += 4) { 1939 if (reserve_list[i] == ha->hanum && reserve_list[i+1] < ha->bus_cnt && 1940 reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) { 1941 TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n", 1942 reserve_list[i], reserve_list[i+1], 1943 reserve_list[i+2], reserve_list[i+3])); 1944 if (!gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE, 0, 1945 reserve_list[i+1], reserve_list[i+2] | 1946 (reserve_list[i+3] << 8))) { 1947 printk("GDT-HA %d: Error raw service (RESERVE, code %d)\n", 1948 ha->hanum, ha->status); 1949 } 1950 } 1951 } 1952 1953 /* Determine OEM string using IOCTL */ 1954 oemstr = (gdth_oem_str_ioctl *)ha->pscratch; 1955 oemstr->params.ctl_version = 0x01; 1956 oemstr->params.buffer_size = sizeof(oemstr->text); 1957 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, 1958 CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL, 1959 sizeof(gdth_oem_str_ioctl))) { 1960 TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n")); 1961 printk("GDT-HA %d: Vendor: %s Name: %s\n", 1962 ha->hanum, oemstr->text.oem_company_name, ha->binfo.type_string); 1963 /* Save the Host Drive inquiry data */ 1964 strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id, 1965 sizeof(ha->oem_name)); 1966 } else { 1967 /* Old method, based on PCI ID */ 1968 TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n")); 1969 printk("GDT-HA %d: Name: %s\n", 1970 ha->hanum, ha->binfo.type_string); 1971 if (ha->oem_id == OEM_ID_INTEL) 1972 strlcpy(ha->oem_name,"Intel ", sizeof(ha->oem_name)); 1973 else 1974 strlcpy(ha->oem_name,"ICP ", sizeof(ha->oem_name)); 1975 } 1976 1977 /* scanning for host drives */ 1978 for (i = 0; i < cdev_cnt; ++i) 1979 gdth_analyse_hdrive(ha, i); 1980 1981 TRACE(("gdth_search_drives() OK\n")); 1982 return 1; 1983} 1984 1985static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive) 1986{ 1987 ulong32 drv_cyls; 1988 int drv_hds, drv_secs; 1989 1990 TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n", ha->hanum, hdrive)); 1991 if (hdrive >= MAX_HDRIVES) 1992 return 0; 1993 1994 if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_INFO, hdrive, 0, 0)) 1995 return 0; 1996 ha->hdr[hdrive].present = TRUE; 1997 ha->hdr[hdrive].size = ha->info; 1998 1999 /* evaluate mapping (sectors per head, heads per cylinder) */ 2000 ha->hdr[hdrive].size &= ~SECS32; 2001 if (ha->info2 == 0) { 2002 gdth_eval_mapping(ha->hdr[hdrive].size,&drv_cyls,&drv_hds,&drv_secs); 2003 } else { 2004 drv_hds = ha->info2 & 0xff; 2005 drv_secs = (ha->info2 >> 8) & 0xff; 2006 drv_cyls = (ulong32)ha->hdr[hdrive].size / drv_hds / drv_secs; 2007 } 2008 ha->hdr[hdrive].heads = (unchar)drv_hds; 2009 ha->hdr[hdrive].secs = (unchar)drv_secs; 2010 /* round size */ 2011 ha->hdr[hdrive].size = drv_cyls * drv_hds * drv_secs; 2012 2013 if (ha->cache_feat & GDT_64BIT) { 2014 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INFO, hdrive, 0, 0) 2015 && ha->info2 != 0) { 2016 ha->hdr[hdrive].size = ((ulong64)ha->info2 << 32) | ha->info; 2017 } 2018 } 2019 TRACE2(("gdth_search_dr() cdr. %d size %d hds %d scs %d\n", 2020 hdrive,ha->hdr[hdrive].size,drv_hds,drv_secs)); 2021 2022 /* get informations about device */ 2023 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_DEVTYPE, hdrive, 0, 0)) { 2024 TRACE2(("gdth_search_dr() cache drive %d devtype %d\n", 2025 hdrive,ha->info)); 2026 ha->hdr[hdrive].devtype = (ushort)ha->info; 2027 } 2028 2029 /* cluster info */ 2030 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_CLUST_INFO, hdrive, 0, 0)) { 2031 TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n", 2032 hdrive,ha->info)); 2033 if (!shared_access) 2034 ha->hdr[hdrive].cluster_type = (unchar)ha->info; 2035 } 2036 2037 /* R/W attributes */ 2038 if (gdth_internal_cmd(ha, CACHESERVICE, GDT_RW_ATTRIBS, hdrive, 0, 0)) { 2039 TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n", 2040 hdrive,ha->info)); 2041 ha->hdr[hdrive].rw_attribs = (unchar)ha->info; 2042 } 2043 2044 return 1; 2045} 2046 2047 2048/* command queueing/sending functions */ 2049 2050static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) 2051{ 2052 struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); 2053 register Scsi_Cmnd *pscp; 2054 register Scsi_Cmnd *nscp; 2055 ulong flags; 2056 unchar b, t; 2057 2058 TRACE(("gdth_putq() priority %d\n",priority)); 2059 spin_lock_irqsave(&ha->smp_lock, flags); 2060 2061 if (!cmndinfo->internal_command) { 2062 cmndinfo->priority = priority; 2063 b = scp->device->channel; 2064 t = scp->device->id; 2065 if (priority >= DEFAULT_PRI) { 2066 if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || 2067 (b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) { 2068 TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); 2069 cmndinfo->timeout = gdth_update_timeout(scp, 0); 2070 } 2071 } 2072 } 2073 2074 if (ha->req_first==NULL) { 2075 ha->req_first = scp; /* queue was empty */ 2076 scp->SCp.ptr = NULL; 2077 } else { /* queue not empty */ 2078 pscp = ha->req_first; 2079 nscp = (Scsi_Cmnd *)pscp->SCp.ptr; 2080 /* priority: 0-highest,..,0xff-lowest */ 2081 while (nscp && gdth_cmnd_priv(nscp)->priority <= priority) { 2082 pscp = nscp; 2083 nscp = (Scsi_Cmnd *)pscp->SCp.ptr; 2084 } 2085 pscp->SCp.ptr = (char *)scp; 2086 scp->SCp.ptr = (char *)nscp; 2087 } 2088 spin_unlock_irqrestore(&ha->smp_lock, flags); 2089 2090#ifdef GDTH_STATISTICS 2091 flags = 0; 2092 for (nscp=ha->req_first; nscp; nscp=(Scsi_Cmnd*)nscp->SCp.ptr) 2093 ++flags; 2094 if (max_rq < flags) { 2095 max_rq = flags; 2096 TRACE3(("GDT: max_rq = %d\n",(ushort)max_rq)); 2097 } 2098#endif 2099} 2100 2101static void gdth_next(gdth_ha_str *ha) 2102{ 2103 register Scsi_Cmnd *pscp; 2104 register Scsi_Cmnd *nscp; 2105 unchar b, t, l, firsttime; 2106 unchar this_cmd, next_cmd; 2107 ulong flags = 0; 2108 int cmd_index; 2109 2110 TRACE(("gdth_next() hanum %d\n", ha->hanum)); 2111 if (!gdth_polling) 2112 spin_lock_irqsave(&ha->smp_lock, flags); 2113 2114 ha->cmd_cnt = ha->cmd_offs_dpmem = 0; 2115 this_cmd = firsttime = TRUE; 2116 next_cmd = gdth_polling ? FALSE:TRUE; 2117 cmd_index = 0; 2118 2119 for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { 2120 struct gdth_cmndinfo *nscp_cmndinfo = gdth_cmnd_priv(nscp); 2121 if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) 2122 pscp = (Scsi_Cmnd *)pscp->SCp.ptr; 2123 if (!nscp_cmndinfo->internal_command) { 2124 b = nscp->device->channel; 2125 t = nscp->device->id; 2126 l = nscp->device->lun; 2127 if (nscp_cmndinfo->priority >= DEFAULT_PRI) { 2128 if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || 2129 (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) 2130 continue; 2131 } 2132 } else 2133 b = t = l = 0; 2134 2135 if (firsttime) { 2136 if (gdth_test_busy(ha)) { /* controller busy ? */ 2137 TRACE(("gdth_next() controller %d busy !\n", ha->hanum)); 2138 if (!gdth_polling) { 2139 spin_unlock_irqrestore(&ha->smp_lock, flags); 2140 return; 2141 } 2142 while (gdth_test_busy(ha)) 2143 gdth_delay(1); 2144 } 2145 firsttime = FALSE; 2146 } 2147 2148 if (!nscp_cmndinfo->internal_command) { 2149 if (nscp_cmndinfo->phase == -1) { 2150 nscp_cmndinfo->phase = CACHESERVICE; /* default: cache svc. */ 2151 if (nscp->cmnd[0] == TEST_UNIT_READY) { 2152 TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", 2153 b, t, l)); 2154 /* TEST_UNIT_READY -> set scan mode */ 2155 if ((ha->scan_mode & 0x0f) == 0) { 2156 if (b == 0 && t == 0 && l == 0) { 2157 ha->scan_mode |= 1; 2158 TRACE2(("Scan mode: 0x%x\n", ha->scan_mode)); 2159 } 2160 } else if ((ha->scan_mode & 0x0f) == 1) { 2161 if (b == 0 && ((t == 0 && l == 1) || 2162 (t == 1 && l == 0))) { 2163 nscp_cmndinfo->OpCode = GDT_SCAN_START; 2164 nscp_cmndinfo->phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) 2165 | SCSIRAWSERVICE; 2166 ha->scan_mode = 0x12; 2167 TRACE2(("Scan mode: 0x%x (SCAN_START)\n", 2168 ha->scan_mode)); 2169 } else { 2170 ha->scan_mode &= 0x10; 2171 TRACE2(("Scan mode: 0x%x\n", ha->scan_mode)); 2172 } 2173 } else if (ha->scan_mode == 0x12) { 2174 if (b == ha->bus_cnt && t == ha->tid_cnt-1) { 2175 nscp_cmndinfo->phase = SCSIRAWSERVICE; 2176 nscp_cmndinfo->OpCode = GDT_SCAN_END; 2177 ha->scan_mode &= 0x10; 2178 TRACE2(("Scan mode: 0x%x (SCAN_END)\n", 2179 ha->scan_mode)); 2180 } 2181 } 2182 } 2183 if (b == ha->virt_bus && nscp->cmnd[0] != INQUIRY && 2184 nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE && 2185 (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) { 2186 /* always GDT_CLUST_INFO! */ 2187 nscp_cmndinfo->OpCode = GDT_CLUST_INFO; 2188 } 2189 } 2190 } 2191 2192 if (nscp_cmndinfo->OpCode != -1) { 2193 if ((nscp_cmndinfo->phase & 0xff) == CACHESERVICE) { 2194 if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) 2195 this_cmd = FALSE; 2196 next_cmd = FALSE; 2197 } else if ((nscp_cmndinfo->phase & 0xff) == SCSIRAWSERVICE) { 2198 if (!(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) 2199 this_cmd = FALSE; 2200 next_cmd = FALSE; 2201 } else { 2202 memset((char*)nscp->sense_buffer,0,16); 2203 nscp->sense_buffer[0] = 0x70; 2204 nscp->sense_buffer[2] = NOT_READY; 2205 nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); 2206 if (!nscp_cmndinfo->wait_for_completion) 2207 nscp_cmndinfo->wait_for_completion++; 2208 else 2209 gdth_scsi_done(nscp); 2210 } 2211 } else if (gdth_cmnd_priv(nscp)->internal_command) { 2212 if (!(cmd_index=gdth_special_cmd(ha, nscp))) 2213 this_cmd = FALSE; 2214 next_cmd = FALSE; 2215 } else if (b != ha->virt_bus) { 2216 if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW || 2217 !(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) 2218 this_cmd = FALSE; 2219 else 2220 ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; 2221 } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || l != 0) { 2222 TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", 2223 nscp->cmnd[0], b, t, l)); 2224 nscp->result = DID_BAD_TARGET << 16; 2225 if (!nscp_cmndinfo->wait_for_completion) 2226 nscp_cmndinfo->wait_for_completion++; 2227 else 2228 gdth_scsi_done(nscp); 2229 } else { 2230 switch (nscp->cmnd[0]) { 2231 case TEST_UNIT_READY: 2232 case INQUIRY: 2233 case REQUEST_SENSE: 2234 case READ_CAPACITY: 2235 case VERIFY: 2236 case START_STOP: 2237 case MODE_SENSE: 2238 case SERVICE_ACTION_IN: 2239 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0], 2240 nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], 2241 nscp->cmnd[4],nscp->cmnd[5])); 2242 if (ha->hdr[t].media_changed && nscp->cmnd[0] != INQUIRY) { 2243 /* return UNIT_ATTENTION */ 2244 TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n", 2245 nscp->cmnd[0], t)); 2246 ha->hdr[t].media_changed = FALSE; 2247 memset((char*)nscp->sense_buffer,0,16); 2248 nscp->sense_buffer[0] = 0x70; 2249 nscp->sense_buffer[2] = UNIT_ATTENTION; 2250 nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); 2251 if (!nscp_cmndinfo->wait_for_completion) 2252 nscp_cmndinfo->wait_for_completion++; 2253 else 2254 gdth_scsi_done(nscp); 2255 } else if (gdth_internal_cache_cmd(ha, nscp)) 2256 gdth_scsi_done(nscp); 2257 break; 2258 2259 case ALLOW_MEDIUM_REMOVAL: 2260 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0], 2261 nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], 2262 nscp->cmnd[4],nscp->cmnd[5])); 2263 if ( (nscp->cmnd[4]&1) && !(ha->hdr[t].devtype&1) ) { 2264 TRACE(("Prevent r. nonremov. drive->do nothing\n")); 2265 nscp->result = DID_OK << 16; 2266 nscp->sense_buffer[0] = 0; 2267 if (!nscp_cmndinfo->wait_for_completion) 2268 nscp_cmndinfo->wait_for_completion++; 2269 else 2270 gdth_scsi_done(nscp); 2271 } else { 2272 nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; 2273 TRACE(("Prevent/allow r. %d rem. drive %d\n", 2274 nscp->cmnd[4],nscp->cmnd[3])); 2275 if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) 2276 this_cmd = FALSE; 2277 } 2278 break; 2279 2280 case RESERVE: 2281 case RELEASE: 2282 TRACE2(("cache cmd %s\n",nscp->cmnd[0] == RESERVE ? 2283 "RESERVE" : "RELEASE")); 2284 if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) 2285 this_cmd = FALSE; 2286 break; 2287 2288 case READ_6: 2289 case WRITE_6: 2290 case READ_10: 2291 case WRITE_10: 2292 case READ_16: 2293 case WRITE_16: 2294 if (ha->hdr[t].media_changed) { 2295 /* return UNIT_ATTENTION */ 2296 TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n", 2297 nscp->cmnd[0], t)); 2298 ha->hdr[t].media_changed = FALSE; 2299 memset((char*)nscp->sense_buffer,0,16); 2300 nscp->sense_buffer[0] = 0x70; 2301 nscp->sense_buffer[2] = UNIT_ATTENTION; 2302 nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); 2303 if (!nscp_cmndinfo->wait_for_completion) 2304 nscp_cmndinfo->wait_for_completion++; 2305 else 2306 gdth_scsi_done(nscp); 2307 } else if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) 2308 this_cmd = FALSE; 2309 break; 2310 2311 default: 2312 TRACE2(("cache cmd %x/%x/%x/%x/%x/%x unknown\n",nscp->cmnd[0], 2313 nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], 2314 nscp->cmnd[4],nscp->cmnd[5])); 2315 printk("GDT-HA %d: Unknown SCSI command 0x%x to cache service !\n", 2316 ha->hanum, nscp->cmnd[0]); 2317 nscp->result = DID_ABORT << 16; 2318 if (!nscp_cmndinfo->wait_for_completion) 2319 nscp_cmndinfo->wait_for_completion++; 2320 else 2321 gdth_scsi_done(nscp); 2322 break; 2323 } 2324 } 2325 2326 if (!this_cmd) 2327 break; 2328 if (nscp == ha->req_first) 2329 ha->req_first = pscp = (Scsi_Cmnd *)nscp->SCp.ptr; 2330 else 2331 pscp->SCp.ptr = nscp->SCp.ptr; 2332 if (!next_cmd) 2333 break; 2334 } 2335 2336 if (ha->cmd_cnt > 0) { 2337 gdth_release_event(ha); 2338 } 2339 2340 if (!gdth_polling) 2341 spin_unlock_irqrestore(&ha->smp_lock, flags); 2342 2343 if (gdth_polling && ha->cmd_cnt > 0) { 2344 if (!gdth_wait(ha, cmd_index, POLL_TIMEOUT)) 2345 printk("GDT-HA %d: Command %d timed out !\n", 2346 ha->hanum, cmd_index); 2347 } 2348} 2349 2350/* 2351 * gdth_copy_internal_data() - copy to/from a buffer onto a scsi_cmnd's 2352 * buffers, kmap_atomic() as needed. 2353 */ 2354static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, 2355 char *buffer, ushort count, int to_buffer) 2356{ 2357 ushort cpcount,i, max_sg = gdth_sg_count(scp); 2358 ushort cpsum,cpnow; 2359 struct scatterlist *sl; 2360 char *address; 2361 2362 cpcount = min_t(ushort, count, gdth_bufflen(scp)); 2363 2364 if (cpcount) { 2365 cpsum=0; 2366 scsi_for_each_sg(scp, sl, max_sg, i) { 2367 unsigned long flags; 2368 cpnow = (ushort)sl->length; 2369 TRACE(("copy_internal() now %d sum %d count %d %d\n", 2370 cpnow, cpsum, cpcount, gdth_bufflen(scp))); 2371 if (cpsum+cpnow > cpcount) 2372 cpnow = cpcount - cpsum; 2373 cpsum += cpnow; 2374 if (!sg_page(sl)) { 2375 printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n", 2376 ha->hanum); 2377 return; 2378 } 2379 local_irq_save(flags); 2380 address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset; 2381 if (to_buffer) 2382 memcpy(buffer, address, cpnow); 2383 else 2384 memcpy(address, buffer, cpnow); 2385 flush_dcache_page(sg_page(sl)); 2386 kunmap_atomic(address, KM_BIO_SRC_IRQ); 2387 local_irq_restore(flags); 2388 if (cpsum == cpcount) 2389 break; 2390 buffer += cpnow; 2391 } 2392 } else if (count) { 2393 printk("GDT-HA %d: SCSI command with no buffers but data transfer expected!\n", 2394 ha->hanum); 2395 WARN_ON(1); 2396 } 2397} 2398 2399static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) 2400{ 2401 unchar t; 2402 gdth_inq_data inq; 2403 gdth_rdcap_data rdc; 2404 gdth_sense_data sd; 2405 gdth_modep_data mpd; 2406 struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); 2407 2408 t = scp->device->id; 2409 TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", 2410 scp->cmnd[0],t)); 2411 2412 scp->result = DID_OK << 16; 2413 scp->sense_buffer[0] = 0; 2414 2415 switch (scp->cmnd[0]) { 2416 case TEST_UNIT_READY: 2417 case VERIFY: 2418 case START_STOP: 2419 TRACE2(("Test/Verify/Start hdrive %d\n",t)); 2420 break; 2421 2422 case INQUIRY: 2423 TRACE2(("Inquiry hdrive %d devtype %d\n", 2424 t,ha->hdr[t].devtype)); 2425 inq.type_qual = (ha->hdr[t].devtype&4) ? TYPE_ROM:TYPE_DISK; 2426 /* you can here set all disks to removable, if you want to do 2427 a flush using the ALLOW_MEDIUM_REMOVAL command */ 2428 inq.modif_rmb = 0x00; 2429 if ((ha->hdr[t].devtype & 1) || 2430 (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) 2431 inq.modif_rmb = 0x80; 2432 inq.version = 2; 2433 inq.resp_aenc = 2; 2434 inq.add_length= 32; 2435 strcpy(inq.vendor,ha->oem_name); 2436 sprintf(inq.product,"Host Drive #%02d",t); 2437 strcpy(inq.revision," "); 2438 gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0); 2439 break; 2440 2441 case REQUEST_SENSE: 2442 TRACE2(("Request sense hdrive %d\n",t)); 2443 sd.errorcode = 0x70; 2444 sd.segno = 0x00; 2445 sd.key = NO_SENSE; 2446 sd.info = 0; 2447 sd.add_length= 0; 2448 gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0); 2449 break; 2450 2451 case MODE_SENSE: 2452 TRACE2(("Mode sense hdrive %d\n",t)); 2453 memset((char*)&mpd,0,sizeof(gdth_modep_data)); 2454 mpd.hd.data_length = sizeof(gdth_modep_data); 2455 mpd.hd.dev_par = (ha->hdr[t].devtype&2) ? 0x80:0; 2456 mpd.hd.bd_length = sizeof(mpd.bd); 2457 mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; 2458 mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; 2459 mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); 2460 gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0); 2461 break; 2462 2463 case READ_CAPACITY: 2464 TRACE2(("Read capacity hdrive %d\n",t)); 2465 if (ha->hdr[t].size > (ulong64)0xffffffff) 2466 rdc.last_block_no = 0xffffffff; 2467 else 2468 rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); 2469 rdc.block_length = cpu_to_be32(SECTOR_SIZE); 2470 gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0); 2471 break; 2472 2473 case SERVICE_ACTION_IN: 2474 if ((scp->cmnd[1] & 0x1f) == SAI_READ_CAPACITY_16 && 2475 (ha->cache_feat & GDT_64BIT)) { 2476 gdth_rdcap16_data rdc16; 2477 2478 TRACE2(("Read capacity (16) hdrive %d\n",t)); 2479 rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); 2480 rdc16.block_length = cpu_to_be32(SECTOR_SIZE); 2481 gdth_copy_internal_data(ha, scp, (char*)&rdc16, 2482 sizeof(gdth_rdcap16_data), 0); 2483 } else { 2484 scp->result = DID_ABORT << 16; 2485 } 2486 break; 2487 2488 default: 2489 TRACE2(("Internal cache cmd 0x%x unknown\n",scp->cmnd[0])); 2490 break; 2491 } 2492 2493 if (!cmndinfo->wait_for_completion) 2494 cmndinfo->wait_for_completion++; 2495 else 2496 return 1; 2497 2498 return 0; 2499} 2500 2501static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) 2502{ 2503 register gdth_cmd_str *cmdp; 2504 struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); 2505 ulong32 cnt, blockcnt; 2506 ulong64 no, blockno; 2507 int i, cmd_index, read_write, sgcnt, mode64; 2508 2509 cmdp = ha->pccb; 2510 TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", 2511 scp->cmnd[0],scp->cmd_len,hdrive)); 2512 2513 if (ha->type==GDT_EISA && ha->cmd_cnt>0) 2514 return 0; 2515 2516 mode64 = (ha->cache_feat & GDT_64BIT) ? TRUE : FALSE; 2517 /* test for READ_16, WRITE_16 if !mode64 ? --- 2518 not required, should not occur due to error return on 2519 READ_CAPACITY_16 */ 2520 2521 cmdp->Service = CACHESERVICE; 2522 cmdp->RequestBuffer = scp; 2523 /* search free command index */ 2524 if (!(cmd_index=gdth_get_cmd_index(ha))) { 2525 TRACE(("GDT: No free command index found\n")); 2526 return 0; 2527 } 2528 /* if it's the first command, set command semaphore */ 2529 if (ha->cmd_cnt == 0) 2530 gdth_set_sema0(ha); 2531 2532 /* fill command */ 2533 read_write = 0; 2534 if (cmndinfo->OpCode != -1) 2535 cmdp->OpCode = cmndinfo->OpCode; /* special cache cmd. */ 2536 else if (scp->cmnd[0] == RESERVE) 2537 cmdp->OpCode = GDT_RESERVE_DRV; 2538 else if (scp->cmnd[0] == RELEASE) 2539 cmdp->OpCode = GDT_RELEASE_DRV; 2540 else if (scp->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { 2541 if (scp->cmnd[4] & 1) /* prevent ? */ 2542 cmdp->OpCode = GDT_MOUNT; 2543 else if (scp->cmnd[3] & 1) /* removable drive ? */ 2544 cmdp->OpCode = GDT_UNMOUNT; 2545 else 2546 cmdp->OpCode = GDT_FLUSH; 2547 } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10 || 2548 scp->cmnd[0] == WRITE_12 || scp->cmnd[0] == WRITE_16 2549 ) { 2550 read_write = 1; 2551 if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && 2552 (ha->cache_feat & GDT_WR_THROUGH))) 2553 cmdp->OpCode = GDT_WRITE_THR; 2554 else 2555 cmdp->OpCode = GDT_WRITE; 2556 } else { 2557 read_write = 2; 2558 cmdp->OpCode = GDT_READ; 2559 } 2560 2561 cmdp->BoardNode = LOCALBOARD; 2562 if (mode64) { 2563 cmdp->u.cache64.DeviceNo = hdrive; 2564 cmdp->u.cache64.BlockNo = 1; 2565 cmdp->u.cache64.sg_canz = 0; 2566 } else { 2567 cmdp->u.cache.DeviceNo = hdrive; 2568 cmdp->u.cache.BlockNo = 1; 2569 cmdp->u.cache.sg_canz = 0; 2570 } 2571 2572 if (read_write) { 2573 if (scp->cmd_len == 16) { 2574 memcpy(&no, &scp->cmnd[2], sizeof(ulong64)); 2575 blockno = be64_to_cpu(no); 2576 memcpy(&cnt, &scp->cmnd[10], sizeof(ulong32)); 2577 blockcnt = be32_to_cpu(cnt); 2578 } else if (scp->cmd_len == 10) { 2579 memcpy(&no, &scp->cmnd[2], sizeof(ulong32)); 2580 blockno = be32_to_cpu(no); 2581 memcpy(&cnt, &scp->cmnd[7], sizeof(ushort)); 2582 blockcnt = be16_to_cpu(cnt); 2583 } else { 2584 memcpy(&no, &scp->cmnd[0], sizeof(ulong32)); 2585 blockno = be32_to_cpu(no) & 0x001fffffUL; 2586 blockcnt= scp->cmnd[4]==0 ? 0x100 : scp->cmnd[4]; 2587 } 2588 if (mode64) { 2589 cmdp->u.cache64.BlockNo = blockno; 2590 cmdp->u.cache64.BlockCnt = blockcnt; 2591 } else { 2592 cmdp->u.cache.BlockNo = (ulong32)blockno; 2593 cmdp->u.cache.BlockCnt = blockcnt; 2594 } 2595 2596 if (gdth_bufflen(scp)) { 2597 cmndinfo->dma_dir = (read_write == 1 ? 2598 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); 2599 sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), 2600 cmndinfo->dma_dir); 2601 if (mode64) { 2602 struct scatterlist *sl; 2603 2604 cmdp->u.cache64.DestAddr= (ulong64)-1; 2605 cmdp->u.cache64.sg_canz = sgcnt; 2606 scsi_for_each_sg(scp, sl, sgcnt, i) { 2607 cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl); 2608#ifdef GDTH_DMA_STATISTICS 2609 if (cmdp->u.cache64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) 2610 ha->dma64_cnt++; 2611 else 2612 ha->dma32_cnt++; 2613#endif 2614 cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl); 2615 } 2616 } else { 2617 struct scatterlist *sl; 2618 2619 cmdp->u.cache.DestAddr= 0xffffffff; 2620 cmdp->u.cache.sg_canz = sgcnt; 2621 scsi_for_each_sg(scp, sl, sgcnt, i) { 2622 cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl); 2623#ifdef GDTH_DMA_STATISTICS 2624 ha->dma32_cnt++; 2625#endif 2626 cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl); 2627 } 2628 } 2629 2630#ifdef GDTH_STATISTICS 2631 if (max_sg < (ulong32)sgcnt) { 2632 max_sg = (ulong32)sgcnt; 2633 TRACE3(("GDT: max_sg = %d\n",max_sg)); 2634 } 2635#endif 2636 2637 } 2638 } 2639 /* evaluate command size, check space */ 2640 if (mode64) { 2641 TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", 2642 cmdp->u.cache64.DestAddr,cmdp->u.cache64.sg_canz, 2643 cmdp->u.cache64.sg_lst[0].sg_ptr, 2644 cmdp->u.cache64.sg_lst[0].sg_len)); 2645 TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n", 2646 cmdp->OpCode,cmdp->u.cache64.BlockNo,cmdp->u.cache64.BlockCnt)); 2647 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.cache64.sg_lst) + 2648 (ushort)cmdp->u.cache64.sg_canz * sizeof(gdth_sg64_str); 2649 } else { 2650 TRACE(("cache cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", 2651 cmdp->u.cache.DestAddr,cmdp->u.cache.sg_canz, 2652 cmdp->u.cache.sg_lst[0].sg_ptr, 2653 cmdp->u.cache.sg_lst[0].sg_len)); 2654 TRACE(("cache cmd: cmd %d blockno. %d, blockcnt %d\n", 2655 cmdp->OpCode,cmdp->u.cache.BlockNo,cmdp->u.cache.BlockCnt)); 2656 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) + 2657 (ushort)cmdp->u.cache.sg_canz * sizeof(gdth_sg_str); 2658 } 2659 if (ha->cmd_len & 3) 2660 ha->cmd_len += (4 - (ha->cmd_len & 3)); 2661 2662 if (ha->cmd_cnt > 0) { 2663 if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) > 2664 ha->ic_all_size) { 2665 TRACE2(("gdth_fill_cache() DPMEM overflow\n")); 2666 ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND; 2667 return 0; 2668 } 2669 } 2670 2671 /* copy command */ 2672 gdth_copy_command(ha); 2673 return cmd_index; 2674} 2675 2676static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) 2677{ 2678 register gdth_cmd_str *cmdp; 2679 ushort i; 2680 dma_addr_t sense_paddr; 2681 int cmd_index, sgcnt, mode64; 2682 unchar t,l; 2683 struct page *page; 2684 ulong offset; 2685 struct gdth_cmndinfo *cmndinfo; 2686 2687 t = scp->device->id; 2688 l = scp->device->lun; 2689 cmdp = ha->pccb; 2690 TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n", 2691 scp->cmnd[0],b,t,l)); 2692 2693 if (ha->type==GDT_EISA && ha->cmd_cnt>0) 2694 return 0; 2695 2696 mode64 = (ha->raw_feat & GDT_64BIT) ? TRUE : FALSE; 2697 2698 cmdp->Service = SCSIRAWSERVICE; 2699 cmdp->RequestBuffer = scp; 2700 /* search free command index */ 2701 if (!(cmd_index=gdth_get_cmd_index(ha))) { 2702 TRACE(("GDT: No free command index found\n")); 2703 return 0; 2704 } 2705 /* if it's the first command, set command semaphore */ 2706 if (ha->cmd_cnt == 0) 2707 gdth_set_sema0(ha); 2708 2709 cmndinfo = gdth_cmnd_priv(scp); 2710 /* fill command */ 2711 if (cmndinfo->OpCode != -1) { 2712 cmdp->OpCode = cmndinfo->OpCode; /* special raw cmd. */ 2713 cmdp->BoardNode = LOCALBOARD; 2714 if (mode64) { 2715 cmdp->u.raw64.direction = (cmndinfo->phase >> 8); 2716 TRACE2(("special raw cmd 0x%x param 0x%x\n", 2717 cmdp->OpCode, cmdp->u.raw64.direction)); 2718 /* evaluate command size */ 2719 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst); 2720 } else { 2721 cmdp->u.raw.direction = (cmndinfo->phase >> 8); 2722 TRACE2(("special raw cmd 0x%x param 0x%x\n", 2723 cmdp->OpCode, cmdp->u.raw.direction)); 2724 /* evaluate command size */ 2725 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst); 2726 } 2727 2728 } else { 2729 page = virt_to_page(scp->sense_buffer); 2730 offset = (ulong)scp->sense_buffer & ~PAGE_MASK; 2731 sense_paddr = pci_map_page(ha->pdev,page,offset, 2732 16,PCI_DMA_FROMDEVICE); 2733 2734 cmndinfo->sense_paddr = sense_paddr; 2735 cmdp->OpCode = GDT_WRITE; /* always */ 2736 cmdp->BoardNode = LOCALBOARD; 2737 if (mode64) { 2738 cmdp->u.raw64.reserved = 0; 2739 cmdp->u.raw64.mdisc_time = 0; 2740 cmdp->u.raw64.mcon_time = 0; 2741 cmdp->u.raw64.clen = scp->cmd_len; 2742 cmdp->u.raw64.target = t; 2743 cmdp->u.raw64.lun = l; 2744 cmdp->u.raw64.bus = b; 2745 cmdp->u.raw64.priority = 0; 2746 cmdp->u.raw64.sdlen = gdth_bufflen(scp); 2747 cmdp->u.raw64.sense_len = 16; 2748 cmdp->u.raw64.sense_data = sense_paddr; 2749 cmdp->u.raw64.direction = 2750 gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN; 2751 memcpy(cmdp->u.raw64.cmd,scp->cmnd,16); 2752 cmdp->u.raw64.sg_ranz = 0; 2753 } else { 2754 cmdp->u.raw.reserved = 0; 2755 cmdp->u.raw.mdisc_time = 0; 2756 cmdp->u.raw.mcon_time = 0; 2757 cmdp->u.raw.clen = scp->cmd_len; 2758 cmdp->u.raw.target = t; 2759 cmdp->u.raw.lun = l; 2760 cmdp->u.raw.bus = b; 2761 cmdp->u.raw.priority = 0; 2762 cmdp->u.raw.link_p = 0; 2763 cmdp->u.raw.sdlen = gdth_bufflen(scp); 2764 cmdp->u.raw.sense_len = 16; 2765 cmdp->u.raw.sense_data = sense_paddr; 2766 cmdp->u.raw.direction = 2767 gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN; 2768 memcpy(cmdp->u.raw.cmd,scp->cmnd,12); 2769 cmdp->u.raw.sg_ranz = 0; 2770 } 2771 2772 if (gdth_bufflen(scp)) { 2773 cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; 2774 sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), 2775 cmndinfo->dma_dir); 2776 if (mode64) { 2777 struct scatterlist *sl; 2778 2779 cmdp->u.raw64.sdata = (ulong64)-1; 2780 cmdp->u.raw64.sg_ranz = sgcnt; 2781 scsi_for_each_sg(scp, sl, sgcnt, i) { 2782 cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl); 2783#ifdef GDTH_DMA_STATISTICS 2784 if (cmdp->u.raw64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) 2785 ha->dma64_cnt++; 2786 else 2787 ha->dma32_cnt++; 2788#endif 2789 cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl); 2790 } 2791 } else { 2792 struct scatterlist *sl; 2793 2794 cmdp->u.raw.sdata = 0xffffffff; 2795 cmdp->u.raw.sg_ranz = sgcnt; 2796 scsi_for_each_sg(scp, sl, sgcnt, i) { 2797 cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl); 2798#ifdef GDTH_DMA_STATISTICS 2799 ha->dma32_cnt++; 2800#endif 2801 cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl); 2802 } 2803 } 2804 2805#ifdef GDTH_STATISTICS 2806 if (max_sg < sgcnt) { 2807 max_sg = sgcnt; 2808 TRACE3(("GDT: max_sg = %d\n",sgcnt)); 2809 } 2810#endif 2811 2812 } 2813 if (mode64) { 2814 TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", 2815 cmdp->u.raw64.sdata,cmdp->u.raw64.sg_ranz, 2816 cmdp->u.raw64.sg_lst[0].sg_ptr, 2817 cmdp->u.raw64.sg_lst[0].sg_len)); 2818 /* evaluate command size */ 2819 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst) + 2820 (ushort)cmdp->u.raw64.sg_ranz * sizeof(gdth_sg64_str); 2821 } else { 2822 TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", 2823 cmdp->u.raw.sdata,cmdp->u.raw.sg_ranz, 2824 cmdp->u.raw.sg_lst[0].sg_ptr, 2825 cmdp->u.raw.sg_lst[0].sg_len)); 2826 /* evaluate command size */ 2827 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) + 2828 (ushort)cmdp->u.raw.sg_ranz * sizeof(gdth_sg_str); 2829 } 2830 } 2831 /* check space */ 2832 if (ha->cmd_len & 3) 2833 ha->cmd_len += (4 - (ha->cmd_len & 3)); 2834 2835 if (ha->cmd_cnt > 0) { 2836 if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) > 2837 ha->ic_all_size) { 2838 TRACE2(("gdth_fill_raw() DPMEM overflow\n")); 2839 ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND; 2840 return 0; 2841 } 2842 } 2843 2844 /* copy command */ 2845 gdth_copy_command(ha); 2846 return cmd_index; 2847} 2848 2849static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) 2850{ 2851 register gdth_cmd_str *cmdp; 2852 int cmd_index; 2853 2854 cmdp= ha->pccb; 2855 TRACE2(("gdth_special_cmd(): ")); 2856 2857 if (ha->type==GDT_EISA && ha->cmd_cnt>0) 2858 return 0; 2859 2860 gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1); 2861 cmdp->RequestBuffer = scp; 2862 2863 /* search free command index */ 2864 if (!(cmd_index=gdth_get_cmd_index(ha))) { 2865 TRACE(("GDT: No free command index found\n")); 2866 return 0; 2867 } 2868 2869 /* if it's the first command, set command semaphore */ 2870 if (ha->cmd_cnt == 0) 2871 gdth_set_sema0(ha); 2872 2873 /* evaluate command size, check space */ 2874 if (cmdp->OpCode == GDT_IOCTL) { 2875 TRACE2(("IOCTL\n")); 2876 ha->cmd_len = 2877 GDTOFFSOF(gdth_cmd_str,u.ioctl.p_param) + sizeof(ulong64); 2878 } else if (cmdp->Service == CACHESERVICE) { 2879 TRACE2(("cache command %d\n",cmdp->OpCode)); 2880 if (ha->cache_feat & GDT_64BIT) 2881 ha->cmd_len = 2882 GDTOFFSOF(gdth_cmd_str,u.cache64.sg_lst) + sizeof(gdth_sg64_str); 2883 else 2884 ha->cmd_len = 2885 GDTOFFSOF(gdth_cmd_str,u.cache.sg_lst) + sizeof(gdth_sg_str); 2886 } else if (cmdp->Service == SCSIRAWSERVICE) { 2887 TRACE2(("raw command %d\n",cmdp->OpCode)); 2888 if (ha->raw_feat & GDT_64BIT) 2889 ha->cmd_len = 2890 GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst) + sizeof(gdth_sg64_str); 2891 else 2892 ha->cmd_len = 2893 GDTOFFSOF(gdth_cmd_str,u.raw.sg_lst) + sizeof(gdth_sg_str); 2894 } 2895 2896 if (ha->cmd_len & 3) 2897 ha->cmd_len += (4 - (ha->cmd_len & 3)); 2898 2899 if (ha->cmd_cnt > 0) { 2900 if ((ha->cmd_offs_dpmem + ha->cmd_len + DPMEM_COMMAND_OFFSET) > 2901 ha->ic_all_size) { 2902 TRACE2(("gdth_special_cmd() DPMEM overflow\n")); 2903 ha->cmd_tab[cmd_index-2].cmnd = UNUSED_CMND; 2904 return 0; 2905 } 2906 } 2907 2908 /* copy command */ 2909 gdth_copy_command(ha); 2910 return cmd_index; 2911} 2912 2913 2914/* Controller event handling functions */ 2915static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, 2916 ushort idx, gdth_evt_data *evt) 2917{ 2918 gdth_evt_str *e; 2919 struct timeval tv; 2920 2921 /* no GDTH_LOCK_HA() ! */ 2922 TRACE2(("gdth_store_event() source %d idx %d\n", source, idx)); 2923 if (source == 0) /* no source -> no event */ 2924 return NULL; 2925 2926 if (ebuffer[elastidx].event_source == source && 2927 ebuffer[elastidx].event_idx == idx && 2928 ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 && 2929 !memcmp((char *)&ebuffer[elastidx].event_data.eu, 2930 (char *)&evt->eu, evt->size)) || 2931 (evt->size == 0 && ebuffer[elastidx].event_data.size == 0 && 2932 !strcmp((char *)&ebuffer[elastidx].event_data.event_string, 2933 (char *)&evt->event_string)))) { 2934 e = &ebuffer[elastidx]; 2935 do_gettimeofday(&tv); 2936 e->last_stamp = tv.tv_sec; 2937 ++e->same_count; 2938 } else { 2939 if (ebuffer[elastidx].event_source != 0) { /* entry not free ? */ 2940 ++elastidx; 2941 if (elastidx == MAX_EVENTS) 2942 elastidx = 0; 2943 if (elastidx == eoldidx) { /* reached mark ? */ 2944 ++eoldidx; 2945 if (eoldidx == MAX_EVENTS) 2946 eoldidx = 0; 2947 } 2948 } 2949 e = &ebuffer[elastidx]; 2950 e->event_source = source; 2951 e->event_idx = idx; 2952 do_gettimeofday(&tv); 2953 e->first_stamp = e->last_stamp = tv.tv_sec; 2954 e->same_count = 1; 2955 e->event_data = *evt; 2956 e->application = 0; 2957 } 2958 return e; 2959} 2960 2961static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr) 2962{ 2963 gdth_evt_str *e; 2964 int eindex; 2965 ulong flags; 2966 2967 TRACE2(("gdth_read_event() handle %d\n", handle)); 2968 spin_lock_irqsave(&ha->smp_lock, flags); 2969 if (handle == -1) 2970 eindex = eoldidx; 2971 else 2972 eindex = handle; 2973 estr->event_source = 0; 2974 2975 if (eindex >= MAX_EVENTS) { 2976 spin_unlock_irqrestore(&ha->smp_lock, flags); 2977 return eindex; 2978 } 2979 e = &ebuffer[eindex]; 2980 if (e->event_source != 0) { 2981 if (eindex != elastidx) { 2982 if (++eindex == MAX_EVENTS) 2983 eindex = 0; 2984 } else { 2985 eindex = -1; 2986 } 2987 memcpy(estr, e, sizeof(gdth_evt_str)); 2988 } 2989 spin_unlock_irqrestore(&ha->smp_lock, flags); 2990 return eindex; 2991} 2992 2993static void gdth_readapp_event(gdth_ha_str *ha, 2994 unchar application, gdth_evt_str *estr) 2995{ 2996 gdth_evt_str *e; 2997 int eindex; 2998 ulong flags; 2999 unchar found = FALSE; 3000 3001 TRACE2(("gdth_readapp_event() app. %d\n", application)); 3002 spin_lock_irqsave(&ha->smp_lock, flags); 3003 eindex = eoldidx; 3004 for (;;) { 3005 e = &ebuffer[eindex]; 3006 if (e->event_source == 0) 3007 break; 3008 if ((e->application & application) == 0) { 3009 e->application |= application; 3010 found = TRUE; 3011 break; 3012 } 3013 if (eindex == elastidx) 3014 break; 3015 if (++eindex == MAX_EVENTS) 3016 eindex = 0; 3017 } 3018 if (found) 3019 memcpy(estr, e, sizeof(gdth_evt_str)); 3020 else 3021 estr->event_source = 0; 3022 spin_unlock_irqrestore(&ha->smp_lock, flags); 3023} 3024 3025static void gdth_clear_events(void) 3026{ 3027 TRACE(("gdth_clear_events()")); 3028 3029 eoldidx = elastidx = 0; 3030 ebuffer[0].event_source = 0; 3031} 3032 3033 3034/* SCSI interface functions */ 3035 3036static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, 3037 int gdth_from_wait, int* pIndex) 3038{ 3039 gdt6m_dpram_str __iomem *dp6m_ptr = NULL; 3040 gdt6_dpram_str __iomem *dp6_ptr; 3041 gdt2_dpram_str __iomem *dp2_ptr; 3042 Scsi_Cmnd *scp; 3043 int rval, i; 3044 unchar IStatus; 3045 ushort Service; 3046 ulong flags = 0; 3047#ifdef INT_COAL 3048 int coalesced = FALSE; 3049 int next = FALSE; 3050 gdth_coal_status *pcs = NULL; 3051 int act_int_coal = 0; 3052#endif 3053 3054 TRACE(("gdth_interrupt() IRQ %d\n", ha->irq)); 3055 3056 /* if polling and not from gdth_wait() -> return */ 3057 if (gdth_polling) { 3058 if (!gdth_from_wait) { 3059 return IRQ_HANDLED; 3060 } 3061 } 3062 3063 if (!gdth_polling) 3064 spin_lock_irqsave(&ha->smp_lock, flags); 3065 3066 /* search controller */ 3067 IStatus = gdth_get_status(ha); 3068 if (IStatus == 0) { 3069 /* spurious interrupt */ 3070 if (!gdth_polling) 3071 spin_unlock_irqrestore(&ha->smp_lock, flags); 3072 return IRQ_HANDLED; 3073 } 3074 3075#ifdef GDTH_STATISTICS 3076 ++act_ints; 3077#endif 3078 3079#ifdef INT_COAL 3080 /* See if the fw is returning coalesced status */ 3081 if (IStatus == COALINDEX) { 3082 /* Coalesced status. Setup the initial status 3083 buffer pointer and flags */ 3084 pcs = ha->coal_stat; 3085 coalesced = TRUE; 3086 next = TRUE; 3087 } 3088 3089 do { 3090 if (coalesced) { 3091 /* For coalesced requests all status 3092 information is found in the status buffer */ 3093 IStatus = (unchar)(pcs->status & 0xff); 3094 } 3095#endif 3096 3097 if (ha->type == GDT_EISA) { 3098 if (IStatus & 0x80) { /* error flag */ 3099 IStatus &= ~0x80; 3100 ha->status = inw(ha->bmic + MAILBOXREG+8); 3101 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); 3102 } else /* no error */ 3103 ha->status = S_OK; 3104 ha->info = inl(ha->bmic + MAILBOXREG+12); 3105 ha->service = inw(ha->bmic + MAILBOXREG+10); 3106 ha->info2 = inl(ha->bmic + MAILBOXREG+4); 3107 3108 outb(0xff, ha->bmic + EDOORREG); /* acknowledge interrupt */ 3109 outb(0x00, ha->bmic + SEMA1REG); /* reset status semaphore */ 3110 } else if (ha->type == GDT_ISA) { 3111 dp2_ptr = ha->brd; 3112 if (IStatus & 0x80) { /* error flag */ 3113 IStatus &= ~0x80; 3114 ha->status = readw(&dp2_ptr->u.ic.Status); 3115 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); 3116 } else /* no error */ 3117 ha->status = S_OK; 3118 ha->info = readl(&dp2_ptr->u.ic.Info[0]); 3119 ha->service = readw(&dp2_ptr->u.ic.Service); 3120 ha->info2 = readl(&dp2_ptr->u.ic.Info[1]); 3121 3122 writeb(0xff, &dp2_ptr->io.irqdel); /* acknowledge interrupt */ 3123 writeb(0, &dp2_ptr->u.ic.Cmd_Index);/* reset command index */ 3124 writeb(0, &dp2_ptr->io.Sema1); /* reset status semaphore */ 3125 } else if (ha->type == GDT_PCI) { 3126 dp6_ptr = ha->brd; 3127 if (IStatus & 0x80) { /* error flag */ 3128 IStatus &= ~0x80; 3129 ha->status = readw(&dp6_ptr->u.ic.Status); 3130 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); 3131 } else /* no error */ 3132 ha->status = S_OK; 3133 ha->info = readl(&dp6_ptr->u.ic.Info[0]); 3134 ha->service = readw(&dp6_ptr->u.ic.Service); 3135 ha->info2 = readl(&dp6_ptr->u.ic.Info[1]); 3136 3137 writeb(0xff, &dp6_ptr->io.irqdel); /* acknowledge interrupt */ 3138 writeb(0, &dp6_ptr->u.ic.Cmd_Index);/* reset command index */ 3139 writeb(0, &dp6_ptr->io.Sema1); /* reset status semaphore */ 3140 } else if (ha->type == GDT_PCINEW) { 3141 if (IStatus & 0x80) { /* error flag */ 3142 IStatus &= ~0x80; 3143 ha->status = inw(PTR2USHORT(&ha->plx->status)); 3144 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); 3145 } else 3146 ha->status = S_OK; 3147 ha->info = inl(PTR2USHORT(&ha->plx->info[0])); 3148 ha->service = inw(PTR2USHORT(&ha->plx->service)); 3149 ha->info2 = inl(PTR2USHORT(&ha->plx->info[1])); 3150 3151 outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); 3152 outb(0x00, PTR2USHORT(&ha->plx->sema1_reg)); 3153 } else if (ha->type == GDT_PCIMPR) { 3154 dp6m_ptr = ha->brd; 3155 if (IStatus & 0x80) { /* error flag */ 3156 IStatus &= ~0x80; 3157#ifdef INT_COAL 3158 if (coalesced) 3159 ha->status = pcs->ext_status & 0xffff; 3160 else 3161#endif 3162 ha->status = readw(&dp6m_ptr->i960r.status); 3163 TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); 3164 } else /* no error */ 3165 ha->status = S_OK; 3166#ifdef INT_COAL 3167 /* get information */ 3168 if (coalesced) { 3169 ha->info = pcs->info0; 3170 ha->info2 = pcs->info1; 3171 ha->service = (pcs->ext_status >> 16) & 0xffff; 3172 } else 3173#endif 3174 { 3175 ha->info = readl(&dp6m_ptr->i960r.info[0]); 3176 ha->service = readw(&dp6m_ptr->i960r.service); 3177 ha->info2 = readl(&dp6m_ptr->i960r.info[1]); 3178 } 3179 /* event string */ 3180 if (IStatus == ASYNCINDEX) { 3181 if (ha->service != SCREENSERVICE && 3182 (ha->fw_vers & 0xff) >= 0x1a) { 3183 ha->dvr.severity = readb 3184 (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.severity); 3185 for (i = 0; i < 256; ++i) { 3186 ha->dvr.event_string[i] = readb 3187 (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.evt_str[i]); 3188 if (ha->dvr.event_string[i] == 0) 3189 break; 3190 } 3191 } 3192 } 3193#ifdef INT_COAL 3194 /* Make sure that non coalesced interrupts get cleared 3195 before being handled by gdth_async_event/gdth_sync_event */ 3196 if (!coalesced) 3197#endif 3198 { 3199 writeb(0xff, &dp6m_ptr->i960r.edoor_reg); 3200 writeb(0, &dp6m_ptr->i960r.sema1_reg); 3201 } 3202 } else { 3203 TRACE2(("gdth_interrupt() unknown controller type\n")); 3204 if (!gdth_polling) 3205 spin_unlock_irqrestore(&ha->smp_lock, flags); 3206 return IRQ_HANDLED; 3207 } 3208 3209 TRACE(("gdth_interrupt() index %d stat %d info %d\n", 3210 IStatus,ha->status,ha->info)); 3211 3212 if (gdth_from_wait) { 3213 *pIndex = (int)IStatus; 3214 } 3215 3216 if (IStatus == ASYNCINDEX) { 3217 TRACE2(("gdth_interrupt() async. event\n")); 3218 gdth_async_event(ha); 3219 if (!gdth_polling) 3220 spin_unlock_irqrestore(&ha->smp_lock, flags); 3221 gdth_next(ha); 3222 return IRQ_HANDLED; 3223 } 3224 3225 if (IStatus == SPEZINDEX) { 3226 TRACE2(("Service unknown or not initialized !\n")); 3227 ha->dvr.size = sizeof(ha->dvr.eu.driver); 3228 ha->dvr.eu.driver.ionode = ha->hanum; 3229 gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr); 3230 if (!gdth_polling) 3231 spin_unlock_irqrestore(&ha->smp_lock, flags); 3232 return IRQ_HANDLED; 3233 } 3234 scp = ha->cmd_tab[IStatus-2].cmnd; 3235 Service = ha->cmd_tab[IStatus-2].service; 3236 ha->cmd_tab[IStatus-2].cmnd = UNUSED_CMND; 3237 if (scp == UNUSED_CMND) { 3238 TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus)); 3239 ha->dvr.size = sizeof(ha->dvr.eu.driver); 3240 ha->dvr.eu.driver.ionode = ha->hanum; 3241 ha->dvr.eu.driver.index = IStatus; 3242 gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr); 3243 if (!gdth_polling) 3244 spin_unlock_irqrestore(&ha->smp_lock, flags); 3245 return IRQ_HANDLED; 3246 } 3247 if (scp == INTERNAL_CMND) { 3248 TRACE(("gdth_interrupt() answer to internal command\n")); 3249 if (!gdth_polling) 3250 spin_unlock_irqrestore(&ha->smp_lock, flags); 3251 return IRQ_HANDLED; 3252 } 3253 3254 TRACE(("gdth_interrupt() sync. status\n")); 3255 rval = gdth_sync_event(ha,Service,IStatus,scp); 3256 if (!gdth_polling) 3257 spin_unlock_irqrestore(&ha->smp_lock, flags); 3258 if (rval == 2) { 3259 gdth_putq(ha, scp, gdth_cmnd_priv(scp)->priority); 3260 } else if (rval == 1) { 3261 gdth_scsi_done(scp); 3262 } 3263 3264#ifdef INT_COAL 3265 if (coalesced) { 3266 /* go to the next status in the status buffer */ 3267 ++pcs; 3268#ifdef GDTH_STATISTICS 3269 ++act_int_coal; 3270 if (act_int_coal > max_int_coal) { 3271 max_int_coal = act_int_coal; 3272 printk("GDT: max_int_coal = %d\n",(ushort)max_int_coal); 3273 } 3274#endif 3275 /* see if there is another status */ 3276 if (pcs->status == 0) 3277 /* Stop the coalesce loop */ 3278 next = FALSE; 3279 } 3280 } while (next); 3281 3282 /* coalescing only for new GDT_PCIMPR controllers available */ 3283 if (ha->type == GDT_PCIMPR && coalesced) { 3284 writeb(0xff, &dp6m_ptr->i960r.edoor_reg); 3285 writeb(0, &dp6m_ptr->i960r.sema1_reg); 3286 } 3287#endif 3288 3289 gdth_next(ha); 3290 return IRQ_HANDLED; 3291} 3292 3293static irqreturn_t gdth_interrupt(int irq, void *dev_id) 3294{ 3295 gdth_ha_str *ha = dev_id; 3296 3297 return __gdth_interrupt(ha, false, NULL); 3298} 3299 3300static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, 3301 Scsi_Cmnd *scp) 3302{ 3303 gdth_msg_str *msg; 3304 gdth_cmd_str *cmdp; 3305 unchar b, t; 3306 struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); 3307 3308 cmdp = ha->pccb; 3309 TRACE(("gdth_sync_event() serv %d status %d\n", 3310 service,ha->status)); 3311 3312 if (service == SCREENSERVICE) { 3313 msg = ha->pmsg; 3314 TRACE(("len: %d, answer: %d, ext: %d, alen: %d\n", 3315 msg->msg_len,msg->msg_answer,msg->msg_ext,msg->msg_alen)); 3316 if (msg->msg_len > MSGLEN+1) 3317 msg->msg_len = MSGLEN+1; 3318 if (msg->msg_len) 3319 if (!(msg->msg_answer && msg->msg_ext)) { 3320 msg->msg_text[msg->msg_len] = '\0'; 3321 printk("%s",msg->msg_text); 3322 } 3323 3324 if (msg->msg_ext && !msg->msg_answer) { 3325 while (gdth_test_busy(ha)) 3326 gdth_delay(0); 3327 cmdp->Service = SCREENSERVICE; 3328 cmdp->RequestBuffer = SCREEN_CMND; 3329 gdth_get_cmd_index(ha); 3330 gdth_set_sema0(ha); 3331 cmdp->OpCode = GDT_READ; 3332 cmdp->BoardNode = LOCALBOARD; 3333 cmdp->u.screen.reserved = 0; 3334 cmdp->u.screen.su.msg.msg_handle= msg->msg_handle; 3335 cmdp->u.screen.su.msg.msg_addr = ha->msg_phys; 3336 ha->cmd_offs_dpmem = 0; 3337 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 3338 + sizeof(ulong64); 3339 ha->cmd_cnt = 0; 3340 gdth_copy_command(ha); 3341 gdth_release_event(ha); 3342 return 0; 3343 } 3344 3345 if (msg->msg_answer && msg->msg_alen) { 3346 /* default answers (getchar() not possible) */ 3347 if (msg->msg_alen == 1) { 3348 msg->msg_alen = 0; 3349 msg->msg_len = 1; 3350 msg->msg_text[0] = 0; 3351 } else { 3352 msg->msg_alen -= 2; 3353 msg->msg_len = 2; 3354 msg->msg_text[0] = 1; 3355 msg->msg_text[1] = 0; 3356 } 3357 msg->msg_ext = 0; 3358 msg->msg_answer = 0; 3359 while (gdth_test_busy(ha)) 3360 gdth_delay(0); 3361 cmdp->Service = SCREENSERVICE; 3362 cmdp->RequestBuffer = SCREEN_CMND; 3363 gdth_get_cmd_index(ha); 3364 gdth_set_sema0(ha); 3365 cmdp->OpCode = GDT_WRITE; 3366 cmdp->BoardNode = LOCALBOARD; 3367 cmdp->u.screen.reserved = 0; 3368 cmdp->u.screen.su.msg.msg_handle= msg->msg_handle; 3369 cmdp->u.screen.su.msg.msg_addr = ha->msg_phys; 3370 ha->cmd_offs_dpmem = 0; 3371 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 3372 + sizeof(ulong64); 3373 ha->cmd_cnt = 0; 3374 gdth_copy_command(ha); 3375 gdth_release_event(ha); 3376 return 0; 3377 } 3378 printk("\n"); 3379 3380 } else { 3381 b = scp->device->channel; 3382 t = scp->device->id; 3383 if (cmndinfo->OpCode == -1 && b != ha->virt_bus) { 3384 ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; 3385 } 3386 /* cache or raw service */ 3387 if (ha->status == S_BSY) { 3388 TRACE2(("Controller busy -> retry !\n")); 3389 if (cmndinfo->OpCode == GDT_MOUNT) 3390 cmndinfo->OpCode = GDT_CLUST_INFO; 3391 /* retry */ 3392 return 2; 3393 } 3394 if (gdth_bufflen(scp)) 3395 pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), 3396 cmndinfo->dma_dir); 3397 3398 if (cmndinfo->sense_paddr) 3399 pci_unmap_page(ha->pdev, cmndinfo->sense_paddr, 16, 3400 PCI_DMA_FROMDEVICE); 3401 3402 if (ha->status == S_OK) { 3403 cmndinfo->status = S_OK; 3404 cmndinfo->info = ha->info; 3405 if (cmndinfo->OpCode != -1) { 3406 TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n", 3407 cmndinfo->OpCode)); 3408 /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ 3409 if (cmndinfo->OpCode == GDT_CLUST_INFO) { 3410 ha->hdr[t].cluster_type = (unchar)ha->info; 3411 if (!(ha->hdr[t].cluster_type & 3412 CLUSTER_MOUNTED)) { 3413 /* NOT MOUNTED -> MOUNT */ 3414 cmndinfo->OpCode = GDT_MOUNT; 3415 if (ha->hdr[t].cluster_type & 3416 CLUSTER_RESERVED) { 3417 /* cluster drive RESERVED (on the other node) */ 3418 cmndinfo->phase = -2; /* reservation conflict */ 3419 } 3420 } else { 3421 cmndinfo->OpCode = -1; 3422 } 3423 } else { 3424 if (cmndinfo->OpCode == GDT_MOUNT) { 3425 ha->hdr[t].cluster_type |= CLUSTER_MOUNTED; 3426 ha->hdr[t].media_changed = TRUE; 3427 } else if (cmndinfo->OpCode == GDT_UNMOUNT) { 3428 ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED; 3429 ha->hdr[t].media_changed = TRUE; 3430 } 3431 cmndinfo->OpCode = -1; 3432 } 3433 /* retry */ 3434 cmndinfo->priority = HIGH_PRI; 3435 return 2; 3436 } else { 3437 /* RESERVE/RELEASE ? */ 3438 if (scp->cmnd[0] == RESERVE) { 3439 ha->hdr[t].cluster_type |= CLUSTER_RESERVED; 3440 } else if (scp->cmnd[0] == RELEASE) { 3441 ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED; 3442 } 3443 scp->result = DID_OK << 16; 3444 scp->sense_buffer[0] = 0; 3445 } 3446 } else { 3447 cmndinfo->status = ha->status; 3448 cmndinfo->info = ha->info; 3449 3450 if (cmndinfo->OpCode != -1) { 3451 TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n", 3452 cmndinfo->OpCode, ha->status)); 3453 if (cmndinfo->OpCode == GDT_SCAN_START || 3454 cmndinfo->OpCode == GDT_SCAN_END) { 3455 cmndinfo->OpCode = -1; 3456 /* retry */ 3457 cmndinfo->priority = HIGH_PRI; 3458 return 2; 3459 } 3460 memset((char*)scp->sense_buffer,0,16); 3461 scp->sense_buffer[0] = 0x70; 3462 scp->sense_buffer[2] = NOT_READY; 3463 scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); 3464 } else if (service == CACHESERVICE) { 3465 if (ha->status == S_CACHE_UNKNOWN && 3466 (ha->hdr[t].cluster_type & 3467 CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) { 3468 /* bus reset -> force GDT_CLUST_INFO */ 3469 ha->hdr[t].cluster_type &= ~CLUSTER_RESERVED; 3470 } 3471 memset((char*)scp->sense_buffer,0,16); 3472 if (ha->status == (ushort)S_CACHE_RESERV) { 3473 scp->result = (DID_OK << 16) | (RESERVATION_CONFLICT << 1); 3474 } else { 3475 scp->sense_buffer[0] = 0x70; 3476 scp->sense_buffer[2] = NOT_READY; 3477 scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); 3478 } 3479 if (!cmndinfo->internal_command) { 3480 ha->dvr.size = sizeof(ha->dvr.eu.sync); 3481 ha->dvr.eu.sync.ionode = ha->hanum; 3482 ha->dvr.eu.sync.service = service; 3483 ha->dvr.eu.sync.status = ha->status; 3484 ha->dvr.eu.sync.info = ha->info; 3485 ha->dvr.eu.sync.hostdrive = t; 3486 if (ha->status >= 0x8000) 3487 gdth_store_event(ha, ES_SYNC, 0, &ha->dvr); 3488 else 3489 gdth_store_event(ha, ES_SYNC, service, &ha->dvr); 3490 } 3491 } else { 3492 /* sense buffer filled from controller firmware (DMA) */ 3493 if (ha->status != S_RAW_SCSI || ha->info >= 0x100) { 3494 scp->result = DID_BAD_TARGET << 16; 3495 } else { 3496 scp->result = (DID_OK << 16) | ha->info; 3497 } 3498 } 3499 } 3500 if (!cmndinfo->wait_for_completion) 3501 cmndinfo->wait_for_completion++; 3502 else 3503 return 1; 3504 } 3505 3506 return 0; 3507} 3508 3509static char *async_cache_tab[] = { 3510/* 0*/ "\011\000\002\002\002\004\002\006\004" 3511 "GDT HA %u, service %u, async. status %u/%lu unknown", 3512/* 1*/ "\011\000\002\002\002\004\002\006\004" 3513 "GDT HA %u, service %u, async. status %u/%lu unknown", 3514/* 2*/ "\005\000\002\006\004" 3515 "GDT HA %u, Host Drive %lu not ready", 3516/* 3*/ "\005\000\002\006\004" 3517 "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", 3518/* 4*/ "\005\000\002\006\004" 3519 "GDT HA %u, mirror update on Host Drive %lu failed", 3520/* 5*/ "\005\000\002\006\004" 3521 "GDT HA %u, Mirror Drive %lu failed", 3522/* 6*/ "\005\000\002\006\004" 3523 "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", 3524/* 7*/ "\005\000\002\006\004" 3525 "GDT HA %u, Host Drive %lu write protected", 3526/* 8*/ "\005\000\002\006\004" 3527 "GDT HA %u, media changed in Host Drive %lu", 3528/* 9*/ "\005\000\002\006\004" 3529 "GDT HA %u, Host Drive %lu is offline", 3530/*10*/ "\005\000\002\006\004" 3531 "GDT HA %u, media change of Mirror Drive %lu", 3532/*11*/ "\005\000\002\006\004" 3533 "GDT HA %u, Mirror Drive %lu is write protected", 3534/*12*/ "\005\000\002\006\004" 3535 "GDT HA %u, general error on Host Drive %lu. Please check the devices of this drive!", 3536/*13*/ "\007\000\002\006\002\010\002" 3537 "GDT HA %u, Array Drive %u: Cache Drive %u failed", 3538/*14*/ "\005\000\002\006\002" 3539 "GDT HA %u, Array Drive %u: FAIL state entered", 3540/*15*/ "\005\000\002\006\002" 3541 "GDT HA %u, Array Drive %u: error", 3542/*16*/ "\007\000\002\006\002\010\002" 3543 "GDT HA %u, Array Drive %u: failed drive replaced by Cache Drive %u", 3544/*17*/ "\005\000\002\006\002" 3545 "GDT HA %u, Array Drive %u: parity build failed", 3546/*18*/ "\005\000\002\006\002" 3547 "GDT HA %u, Array Drive %u: drive rebuild failed", 3548/*19*/ "\005\000\002\010\002" 3549 "GDT HA %u, Test of Hot Fix %u failed", 3550/*20*/ "\005\000\002\006\002" 3551 "GDT HA %u, Array Drive %u: drive build finished successfully", 3552/*21*/ "\005\000\002\006\002" 3553 "GDT HA %u, Array Drive %u: drive rebuild finished successfully", 3554/*22*/ "\007\000\002\006\002\010\002" 3555 "GDT HA %u, Array Drive %u: Hot Fix %u activated", 3556/*23*/ "\005\000\002\006\002" 3557 "GDT HA %u, Host Drive %u: processing of i/o aborted due to serious drive error", 3558/*24*/ "\005\000\002\010\002" 3559 "GDT HA %u, mirror update on Cache Drive %u completed", 3560/*25*/ "\005\000\002\010\002" 3561 "GDT HA %u, mirror update on Cache Drive %lu failed", 3562/*26*/ "\005\000\002\006\002" 3563 "GDT HA %u, Array Drive %u: drive rebuild started", 3564/*27*/ "\005\000\002\012\001" 3565 "GDT HA %u, Fault bus %u: SHELF OK detected", 3566/*28*/ "\005\000\002\012\001" 3567 "GDT HA %u, Fault bus %u: SHELF not OK detected", 3568/*29*/ "\007\000\002\012\001\013\001" 3569 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug started", 3570/*30*/ "\007\000\002\012\001\013\001" 3571 "GDT HA %u, Fault bus %u, ID %u: new disk detected", 3572/*31*/ "\007\000\002\012\001\013\001" 3573 "GDT HA %u, Fault bus %u, ID %u: old disk detected", 3574/*32*/ "\007\000\002\012\001\013\001" 3575 "GDT HA %u, Fault bus %u, ID %u: plugging an active disk is invalid", 3576/*33*/ "\007\000\002\012\001\013\001" 3577 "GDT HA %u, Fault bus %u, ID %u: invalid device detected", 3578/*34*/ "\011\000\002\012\001\013\001\006\004" 3579 "GDT HA %u, Fault bus %u, ID %u: insufficient disk capacity (%lu MB required)", 3580/*35*/ "\007\000\002\012\001\013\001" 3581 "GDT HA %u, Fault bus %u, ID %u: disk write protected", 3582/*36*/ "\007\000\002\012\001\013\001" 3583 "GDT HA %u, Fault bus %u, ID %u: disk not available", 3584/*37*/ "\007\000\002\012\001\006\004" 3585 "GDT HA %u, Fault bus %u: swap detected (%lu)", 3586/*38*/ "\007\000\002\012\001\013\001" 3587 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug finished successfully", 3588/*39*/ "\007\000\002\012\001\013\001" 3589 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted due to user Hot Plug", 3590/*40*/ "\007\000\002\012\001\013\001" 3591 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug aborted", 3592/*41*/ "\007\000\002\012\001\013\001" 3593 "GDT HA %u, Fault bus %u, ID %u: Auto Hot Plug for Hot Fix started", 3594/*42*/ "\005\000\002\006\002" 3595 "GDT HA %u, Array Drive %u: drive build started", 3596/*43*/ "\003\000\002" 3597 "GDT HA %u, DRAM parity error detected", 3598/*44*/ "\005\000\002\006\002" 3599 "GDT HA %u, Mirror Drive %u: update started", 3600/*45*/ "\007\000\002\006\002\010\002" 3601 "GDT HA %u, Mirror Drive %u: Hot Fix %u activated", 3602/*46*/ "\005\000\002\006\002" 3603 "GDT HA %u, Array Drive %u: no matching Pool Hot Fix Drive available", 3604/*47*/ "\005\000\002\006\002" 3605 "GDT HA %u, Array Drive %u: Pool Hot Fix Drive available", 3606/*48*/ "\005\000\002\006\002" 3607 "GDT HA %u, Mirror Drive %u: no matching Pool Hot Fix Drive available", 3608/*49*/ "\005\000\002\006\002" 3609 "GDT HA %u, Mirror Drive %u: Pool Hot Fix Drive available", 3610/*50*/ "\007\000\002\012\001\013\001" 3611 "GDT HA %u, SCSI bus %u, ID %u: IGNORE_WIDE_RESIDUE message received", 3612/*51*/ "\005\000\002\006\002" 3613 "GDT HA %u, Array Drive %u: expand started", 3614/*52*/ "\005\000\002\006\002" 3615 "GDT HA %u, Array Drive %u: expand finished successfully", 3616/*53*/ "\005\000\002\006\002" 3617 "GDT HA %u, Array Drive %u: expand failed", 3618/*54*/ "\003\000\002" 3619 "GDT HA %u, CPU temperature critical", 3620/*55*/ "\003\000\002" 3621 "GDT HA %u, CPU temperature OK", 3622/*56*/ "\005\000\002\006\004" 3623 "GDT HA %u, Host drive %lu created", 3624/*57*/ "\005\000\002\006\002" 3625 "GDT HA %u, Array Drive %u: expand restarted", 3626/*58*/ "\005\000\002\006\002" 3627 "GDT HA %u, Array Drive %u: expand stopped", 3628/*59*/ "\005\000\002\010\002" 3629 "GDT HA %u, Mirror Drive %u: drive build quited", 3630/*60*/ "\005\000\002\006\002" 3631 "GDT HA %u, Array Drive %u: parity build quited", 3632/*61*/ "\005\000\002\006\002" 3633 "GDT HA %u, Array Drive %u: drive rebuild quited", 3634/*62*/ "\005\000\002\006\002" 3635 "GDT HA %u, Array Drive %u: parity verify started", 3636/*63*/ "\005\000\002\006\002" 3637 "GDT HA %u, Array Drive %u: parity verify done", 3638/*64*/ "\005\000\002\006\002" 3639 "GDT HA %u, Array Drive %u: parity verify failed", 3640/*65*/ "\005\000\002\006\002" 3641 "GDT HA %u, Array Drive %u: parity error detected", 3642/*66*/ "\005\000\002\006\002" 3643 "GDT HA %u, Array Drive %u: parity verify quited", 3644/*67*/ "\005\000\002\006\002" 3645 "GDT HA %u, Host Drive %u reserved", 3646/*68*/ "\005\000\002\006\002" 3647 "GDT HA %u, Host Drive %u mounted and released", 3648/*69*/ "\005\000\002\006\002" 3649 "GDT HA %u, Host Drive %u released", 3650/*70*/ "\003\000\002" 3651 "GDT HA %u, DRAM error detected and corrected with ECC", 3652/*71*/ "\003\000\002" 3653 "GDT HA %u, Uncorrectable DRAM error detected with ECC", 3654/*72*/ "\011\000\002\012\001\013\001\014\001" 3655 "GDT HA %u, SCSI bus %u, ID %u, LUN %u: reassigning block", 3656/*73*/ "\005\000\002\006\002" 3657 "GDT HA %u, Host drive %u resetted locally", 3658/*74*/ "\005\000\002\006\002" 3659 "GDT HA %u, Host drive %u resetted remotely", 3660/*75*/ "\003\000\002" 3661 "GDT HA %u, async. status 75 unknown", 3662}; 3663 3664 3665static int gdth_async_event(gdth_ha_str *ha) 3666{ 3667 gdth_cmd_str *cmdp; 3668 int cmd_index; 3669 3670 cmdp= ha->pccb; 3671 TRACE2(("gdth_async_event() ha %d serv %d\n", 3672 ha->hanum, ha->service)); 3673 3674 if (ha->service == SCREENSERVICE) { 3675 if (ha->status == MSG_REQUEST) { 3676 while (gdth_test_busy(ha)) 3677 gdth_delay(0); 3678 cmdp->Service = SCREENSERVICE; 3679 cmdp->RequestBuffer = SCREEN_CMND; 3680 cmd_index = gdth_get_cmd_index(ha); 3681 gdth_set_sema0(ha); 3682 cmdp->OpCode = GDT_READ; 3683 cmdp->BoardNode = LOCALBOARD; 3684 cmdp->u.screen.reserved = 0; 3685 cmdp->u.screen.su.msg.msg_handle= MSG_INV_HANDLE; 3686 cmdp->u.screen.su.msg.msg_addr = ha->msg_phys; 3687 ha->cmd_offs_dpmem = 0; 3688 ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) 3689 + sizeof(ulong64); 3690 ha->cmd_cnt = 0; 3691 gdth_copy_command(ha); 3692 if (ha->type == GDT_EISA) 3693 printk("[EISA slot %d] ",(ushort)ha->brd_phys); 3694 else if (ha->type == GDT_ISA) 3695 printk("[DPMEM 0x%4X] ",(ushort)ha->brd_phys); 3696 else 3697 printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8), 3698 (ushort)((ha->brd_phys>>3)&0x1f)); 3699 gdth_release_event(ha); 3700 } 3701 3702 } else { 3703 if (ha->type == GDT_PCIMPR && 3704 (ha->fw_vers & 0xff) >= 0x1a) { 3705 ha->dvr.size = 0; 3706 ha->dvr.eu.async.ionode = ha->hanum; 3707 ha->dvr.eu.async.status = ha->status; 3708 /* severity and event_string already set! */ 3709 } else { 3710 ha->dvr.size = sizeof(ha->dvr.eu.async); 3711 ha->dvr.eu.async.ionode = ha->hanum; 3712 ha->dvr.eu.async.service = ha->service; 3713 ha->dvr.eu.async.status = ha->status; 3714 ha->dvr.eu.async.info = ha->info; 3715 *(ulong32 *)ha->dvr.eu.async.scsi_coord = ha->info2; 3716 } 3717 gdth_store_event( ha, ES_ASYNC, ha->service, &ha->dvr ); 3718 gdth_log_event( &ha->dvr, NULL ); 3719 3720 /* new host drive from expand? */ 3721 if (ha->service == CACHESERVICE && ha->status == 56) { 3722 TRACE2(("gdth_async_event(): new host drive %d created\n", 3723 (ushort)ha->info)); 3724 /* gdth_analyse_hdrive(hanum, (ushort)ha->info); */ 3725 } 3726 } 3727 return 1; 3728} 3729 3730static void gdth_log_event(gdth_evt_data *dvr, char *buffer) 3731{ 3732 gdth_stackframe stack; 3733 char *f = NULL; 3734 int i,j; 3735 3736 TRACE2(("gdth_log_event()\n")); 3737 if (dvr->size == 0) { 3738 if (buffer == NULL) { 3739 printk("Adapter %d: %s\n",dvr->eu.async.ionode,dvr->event_string); 3740 } else { 3741 sprintf(buffer,"Adapter %d: %s\n", 3742 dvr->eu.async.ionode,dvr->event_string); 3743 } 3744 } else if (dvr->eu.async.service == CACHESERVICE && 3745 INDEX_OK(dvr->eu.async.status, async_cache_tab)) { 3746 TRACE2(("GDT: Async. event cache service, event no.: %d\n", 3747 dvr->eu.async.status)); 3748 3749 f = async_cache_tab[dvr->eu.async.status]; 3750 3751 /* i: parameter to push, j: stack element to fill */ 3752 for (j=0,i=1; i < f[0]; i+=2) { 3753 switch (f[i+1]) { 3754 case 4: 3755 stack.b[j++] = *(ulong32*)&dvr->eu.stream[(int)f[i]]; 3756 break; 3757 case 2: 3758 stack.b[j++] = *(ushort*)&dvr->eu.stream[(int)f[i]]; 3759 break; 3760 case 1: 3761 stack.b[j++] = *(unchar*)&dvr->eu.stream[(int)f[i]]; 3762 break; 3763 default: 3764 break; 3765 } 3766 } 3767 3768 if (buffer == NULL) { 3769 printk(&f[(int)f[0]],stack); 3770 printk("\n"); 3771 } else { 3772 sprintf(buffer,&f[(int)f[0]],stack); 3773 } 3774 3775 } else { 3776 if (buffer == NULL) { 3777 printk("GDT HA %u, Unknown async. event service %d event no. %d\n", 3778 dvr->eu.async.ionode,dvr->eu.async.service,dvr->eu.async.status); 3779 } else { 3780 sprintf(buffer,"GDT HA %u, Unknown async. event service %d event no. %d", 3781 dvr->eu.async.ionode,dvr->eu.async.service,dvr->eu.async.status); 3782 } 3783 } 3784} 3785 3786#ifdef GDTH_STATISTICS 3787static void gdth_timeout(ulong data) 3788{ 3789 ulong32 i; 3790 Scsi_Cmnd *nscp; 3791 gdth_ha_str *ha; 3792 ulong flags; 3793 3794 ha = list_first_entry(&gdth_instances, gdth_ha_str, list); 3795 spin_lock_irqsave(&ha->smp_lock, flags); 3796 3797 for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) 3798 if (ha->cmd_tab[i].cmnd != UNUSED_CMND) 3799 ++act_stats; 3800 3801 for (act_rq=0,nscp=ha->req_first; nscp; nscp=(Scsi_Cmnd*)nscp->SCp.ptr) 3802 ++act_rq; 3803 3804 TRACE2(("gdth_to(): ints %d, ios %d, act_stats %d, act_rq %d\n", 3805 act_ints, act_ios, act_stats, act_rq)); 3806 act_ints = act_ios = 0; 3807 3808 gdth_timer.expires = jiffies + 30 * HZ; 3809 add_timer(&gdth_timer); 3810 spin_unlock_irqrestore(&ha->smp_lock, flags); 3811} 3812#endif 3813 3814static void __init internal_setup(char *str,int *ints) 3815{ 3816 int i, argc; 3817 char *cur_str, *argv; 3818 3819 TRACE2(("internal_setup() str %s ints[0] %d\n", 3820 str ? str:"NULL", ints ? ints[0]:0)); 3821 3822 /* read irq[] from ints[] */ 3823 if (ints) { 3824 argc = ints[0]; 3825 if (argc > 0) { 3826 if (argc > MAXHA) 3827 argc = MAXHA; 3828 for (i = 0; i < argc; ++i) 3829 irq[i] = ints[i+1]; 3830 } 3831 } 3832 3833 /* analyse string */ 3834 argv = str; 3835 while (argv && (cur_str = strchr(argv, ':'))) { 3836 int val = 0, c = *++cur_str; 3837 3838 if (c == 'n' || c == 'N') 3839 val = 0; 3840 else if (c == 'y' || c == 'Y') 3841 val = 1; 3842 else 3843 val = (int)simple_strtoul(cur_str, NULL, 0); 3844 3845 if (!strncmp(argv, "disable:", 8)) 3846 disable = val; 3847 else if (!strncmp(argv, "reserve_mode:", 13)) 3848 reserve_mode = val; 3849 else if (!strncmp(argv, "reverse_scan:", 13)) 3850 reverse_scan = val; 3851 else if (!strncmp(argv, "hdr_channel:", 12)) 3852 hdr_channel = val; 3853 else if (!strncmp(argv, "max_ids:", 8)) 3854 max_ids = val; 3855 else if (!strncmp(argv, "rescan:", 7)) 3856 rescan = val; 3857 else if (!strncmp(argv, "shared_access:", 14)) 3858 shared_access = val; 3859 else if (!strncmp(argv, "probe_eisa_isa:", 15)) 3860 probe_eisa_isa = val; 3861 else if (!strncmp(argv, "reserve_list:", 13)) { 3862 reserve_list[0] = val; 3863 for (i = 1; i < MAX_RES_ARGS; i++) { 3864 cur_str = strchr(cur_str, ','); 3865 if (!cur_str) 3866 break; 3867 if (!isdigit((int)*++cur_str)) { 3868 --cur_str; 3869 break; 3870 } 3871 reserve_list[i] = 3872 (int)simple_strtoul(cur_str, NULL, 0); 3873 } 3874 if (!cur_str) 3875 break; 3876 argv = ++cur_str; 3877 continue; 3878 } 3879 3880 if ((argv = strchr(argv, ','))) 3881 ++argv; 3882 } 3883} 3884 3885int __init option_setup(char *str) 3886{ 3887 int ints[MAXHA]; 3888 char *cur = str; 3889 int i = 1; 3890 3891 TRACE2(("option_setup() str %s\n", str ? str:"NULL")); 3892 3893 while (cur && isdigit(*cur) && i <= MAXHA) { 3894 ints[i++] = simple_strtoul(cur, NULL, 0); 3895 if ((cur = strchr(cur, ',')) != NULL) cur++; 3896 } 3897 3898 ints[0] = i - 1; 3899 internal_setup(cur, ints); 3900 return 1; 3901} 3902 3903static const char *gdth_ctr_name(gdth_ha_str *ha) 3904{ 3905 TRACE2(("gdth_ctr_name()\n")); 3906 3907 if (ha->type == GDT_EISA) { 3908 switch (ha->stype) { 3909 case GDT3_ID: 3910 return("GDT3000/3020"); 3911 case GDT3A_ID: 3912 return("GDT3000A/3020A/3050A"); 3913 case GDT3B_ID: 3914 return("GDT3000B/3010A"); 3915 } 3916 } else if (ha->type == GDT_ISA) { 3917 return("GDT2000/2020"); 3918 } else if (ha->type == GDT_PCI) { 3919 switch (ha->pdev->device) { 3920 case PCI_DEVICE_ID_VORTEX_GDT60x0: 3921 return("GDT6000/6020/6050"); 3922 case PCI_DEVICE_ID_VORTEX_GDT6000B: 3923 return("GDT6000B/6010"); 3924 } 3925 } 3926 /* new controllers (GDT_PCINEW, GDT_PCIMPR, ..) use board_info IOCTL! */ 3927 3928 return(""); 3929} 3930 3931static const char *gdth_info(struct Scsi_Host *shp) 3932{ 3933 gdth_ha_str *ha = shost_priv(shp); 3934 3935 TRACE2(("gdth_info()\n")); 3936 return ((const char *)ha->binfo.type_string); 3937} 3938 3939static int gdth_eh_bus_reset(Scsi_Cmnd *scp) 3940{ 3941 gdth_ha_str *ha = shost_priv(scp->device->host); 3942 int i; 3943 ulong flags; 3944 Scsi_Cmnd *cmnd; 3945 unchar b; 3946 3947 TRACE2(("gdth_eh_bus_reset()\n")); 3948 3949 b = scp->device->channel; 3950 3951 /* clear command tab */ 3952 spin_lock_irqsave(&ha->smp_lock, flags); 3953 for (i = 0; i < GDTH_MAXCMDS; ++i) { 3954 cmnd = ha->cmd_tab[i].cmnd; 3955 if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b) 3956 ha->cmd_tab[i].cmnd = UNUSED_CMND; 3957 } 3958 spin_unlock_irqrestore(&ha->smp_lock, flags); 3959 3960 if (b == ha->virt_bus) { 3961 /* host drives */ 3962 for (i = 0; i < MAX_HDRIVES; ++i) { 3963 if (ha->hdr[i].present) { 3964 spin_lock_irqsave(&ha->smp_lock, flags); 3965 gdth_polling = TRUE; 3966 while (gdth_test_busy(ha)) 3967 gdth_delay(0); 3968 if (gdth_internal_cmd(ha, CACHESERVICE, 3969 GDT_CLUST_RESET, i, 0, 0)) 3970 ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED; 3971 gdth_polling = FALSE; 3972 spin_unlock_irqrestore(&ha->smp_lock, flags); 3973 } 3974 } 3975 } else { 3976 /* raw devices */ 3977 spin_lock_irqsave(&ha->smp_lock, flags); 3978 for (i = 0; i < MAXID; ++i) 3979 ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0; 3980 gdth_polling = TRUE; 3981 while (gdth_test_busy(ha)) 3982 gdth_delay(0); 3983 gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESET_BUS, 3984 BUS_L2P(ha,b), 0, 0); 3985 gdth_polling = FALSE; 3986 spin_unlock_irqrestore(&ha->smp_lock, flags); 3987 } 3988 return SUCCESS; 3989} 3990 3991static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip) 3992{ 3993 unchar b, t; 3994 gdth_ha_str *ha = shost_priv(sdev->host); 3995 struct scsi_device *sd; 3996 unsigned capacity; 3997 3998 sd = sdev; 3999 capacity = cap; 4000 b = sd->channel; 4001 t = sd->id; 4002 TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", ha->hanum, b, t)); 4003 4004 if (b != ha->virt_bus || ha->hdr[t].heads == 0) { 4005 /* raw device or host drive without mapping information */ 4006 TRACE2(("Evaluate mapping\n")); 4007 gdth_eval_mapping(capacity,&ip[2],&ip[0],&ip[1]); 4008 } else { 4009 ip[0] = ha->hdr[t].heads; 4010 ip[1] = ha->hdr[t].secs; 4011 ip[2] = capacity / ip[0] / ip[1]; 4012 } 4013 4014 TRACE2(("gdth_bios_param(): %d heads, %d secs, %d cyls\n", 4015 ip[0],ip[1],ip[2])); 4016 return 0; 4017} 4018 4019 4020static int gdth_queuecommand(struct scsi_cmnd *scp, 4021 void (*done)(struct scsi_cmnd *)) 4022{ 4023 gdth_ha_str *ha = shost_priv(scp->device->host); 4024 struct gdth_cmndinfo *cmndinfo; 4025 4026 TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); 4027 4028 cmndinfo = gdth_get_cmndinfo(ha); 4029 BUG_ON(!cmndinfo); 4030 4031 scp->scsi_done = done; 4032 gdth_update_timeout(scp, scp->timeout_per_command * 6); 4033 cmndinfo->priority = DEFAULT_PRI; 4034 4035 gdth_set_bufflen(scp, scsi_bufflen(scp)); 4036 gdth_set_sg_count(scp, scsi_sg_count(scp)); 4037 gdth_set_sglist(scp, scsi_sglist(scp)); 4038 4039 return __gdth_queuecommand(ha, scp, cmndinfo); 4040} 4041 4042static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, 4043 struct gdth_cmndinfo *cmndinfo) 4044{ 4045 scp->host_scribble = (unsigned char *)cmndinfo; 4046 cmndinfo->wait_for_completion = 1; 4047 cmndinfo->phase = -1; 4048 cmndinfo->OpCode = -1; 4049 4050#ifdef GDTH_STATISTICS 4051 ++act_ios; 4052#endif 4053 4054 gdth_putq(ha, scp, cmndinfo->priority); 4055 gdth_next(ha); 4056 return 0; 4057} 4058 4059 4060static int gdth_open(struct inode *inode, struct file *filep) 4061{ 4062 gdth_ha_str *ha; 4063 4064 list_for_each_entry(ha, &gdth_instances, list) { 4065 if (!ha->sdev) 4066 ha->sdev = scsi_get_host_dev(ha->shost); 4067 } 4068 4069 TRACE(("gdth_open()\n")); 4070 return 0; 4071} 4072 4073static int gdth_close(struct inode *inode, struct file *filep) 4074{ 4075 TRACE(("gdth_close()\n")); 4076 return 0; 4077} 4078 4079static int ioc_event(void __user *arg) 4080{ 4081 gdth_ioctl_event evt; 4082 gdth_ha_str *ha; 4083 ulong flags; 4084 4085 if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event))) 4086 return -EFAULT; 4087 ha = gdth_find_ha(evt.ionode); 4088 if (!ha) 4089 return -EFAULT; 4090 4091 if (evt.erase == 0xff) { 4092 if (evt.event.event_source == ES_TEST) 4093 evt.event.event_data.size=sizeof(evt.event.event_data.eu.test); 4094 else if (evt.event.event_source == ES_DRIVER) 4095 evt.event.event_data.size=sizeof(evt.event.event_data.eu.driver); 4096 else if (evt.event.event_source == ES_SYNC) 4097 evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync); 4098 else 4099 evt.event.event_data.size=sizeof(evt.event.event_data.eu.async); 4100 spin_lock_irqsave(&ha->smp_lock, flags); 4101 gdth_store_event(ha, evt.event.event_source, evt.event.event_idx, 4102 &evt.event.event_data); 4103 spin_unlock_irqrestore(&ha->smp_lock, flags); 4104 } else if (evt.erase == 0xfe) { 4105 gdth_clear_events(); 4106 } else if (evt.erase == 0) { 4107 evt.handle = gdth_read_event(ha, evt.handle, &evt.event); 4108 } else { 4109 gdth_readapp_event(ha, evt.erase, &evt.event); 4110 } 4111 if (copy_to_user(arg, &evt, sizeof(gdth_ioctl_event))) 4112 return -EFAULT; 4113 return 0; 4114} 4115 4116static int ioc_lockdrv(void __user *arg) 4117{ 4118 gdth_ioctl_lockdrv ldrv; 4119 unchar i, j; 4120 ulong flags; 4121 gdth_ha_str *ha; 4122 4123 if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv))) 4124 return -EFAULT; 4125 ha = gdth_find_ha(ldrv.ionode); 4126 if (!ha) 4127 return -EFAULT; 4128 4129 for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { 4130 j = ldrv.drives[i]; 4131 if (j >= MAX_HDRIVES || !ha->hdr[j].present) 4132 continue; 4133 if (ldrv.lock) { 4134 spin_lock_irqsave(&ha->smp_lock, flags); 4135 ha->hdr[j].lock = 1; 4136 spin_unlock_irqrestore(&ha->smp_lock, flags); 4137 gdth_wait_completion(ha, ha->bus_cnt, j); 4138 gdth_stop_timeout(ha, ha->bus_cnt, j); 4139 } else { 4140 spin_lock_irqsave(&ha->smp_lock, flags); 4141 ha->hdr[j].lock = 0; 4142 spin_unlock_irqrestore(&ha->smp_lock, flags); 4143 gdth_start_timeout(ha, ha->bus_cnt, j); 4144 gdth_next(ha); 4145 } 4146 } 4147 return 0; 4148} 4149 4150static int ioc_resetdrv(void __user *arg, char *cmnd) 4151{ 4152 gdth_ioctl_reset res; 4153 gdth_cmd_str cmd; 4154 gdth_ha_str *ha; 4155 int rval; 4156 4157 if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || 4158 res.number >= MAX_HDRIVES) 4159 return -EFAULT; 4160 ha = gdth_find_ha(res.ionode); 4161 if (!ha) 4162 return -EFAULT; 4163 4164 if (!ha->hdr[res.number].present) 4165 return 0; 4166 memset(&cmd, 0, sizeof(gdth_cmd_str)); 4167 cmd.Service = CACHESERVICE; 4168 cmd.OpCode = GDT_CLUST_RESET; 4169 if (ha->cache_feat & GDT_64BIT) 4170 cmd.u.cache64.DeviceNo = res.number; 4171 else 4172 cmd.u.cache.DeviceNo = res.number; 4173 4174 rval = __gdth_execute(ha->sdev, &cmd, cmnd, 30, NULL); 4175 if (rval < 0) 4176 return rval; 4177 res.status = rval; 4178 4179 if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset))) 4180 return -EFAULT; 4181 return 0; 4182} 4183 4184static int ioc_general(void __user *arg, char *cmnd) 4185{ 4186 gdth_ioctl_general gen; 4187 char *buf = NULL; 4188 ulong64 paddr; 4189 gdth_ha_str *ha; 4190 int rval; 4191 4192 if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) 4193 return -EFAULT; 4194 ha = gdth_find_ha(gen.ionode); 4195 if (!ha) 4196 return -EFAULT; 4197 if (gen.data_len + gen.sense_len != 0) { 4198 if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, 4199 FALSE, &paddr))) 4200 return -EFAULT; 4201 if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), 4202 gen.data_len + gen.sense_len)) { 4203 gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); 4204 return -EFAULT; 4205 } 4206 4207 if (gen.command.OpCode == GDT_IOCTL) { 4208 gen.command.u.ioctl.p_param = paddr; 4209 } else if (gen.command.Service == CACHESERVICE) { 4210 if (ha->cache_feat & GDT_64BIT) { 4211 /* copy elements from 32-bit IOCTL structure */ 4212 gen.command.u.cache64.BlockCnt = gen.command.u.cache.BlockCnt; 4213 gen.command.u.cache64.BlockNo = gen.command.u.cache.BlockNo; 4214 gen.command.u.cache64.DeviceNo = gen.command.u.cache.DeviceNo; 4215 /* addresses */ 4216 if (ha->cache_feat & SCATTER_GATHER) { 4217 gen.command.u.cache64.DestAddr = (ulong64)-1; 4218 gen.command.u.cache64.sg_canz = 1; 4219 gen.command.u.cache64.sg_lst[0].sg_ptr = paddr; 4220 gen.command.u.cache64.sg_lst[0].sg_len = gen.data_len; 4221 gen.command.u.cache64.sg_lst[1].sg_len = 0; 4222 } else { 4223 gen.command.u.cache64.DestAddr = paddr; 4224 gen.command.u.cache64.sg_canz = 0; 4225 } 4226 } else { 4227 if (ha->cache_feat & SCATTER_GATHER) { 4228 gen.command.u.cache.DestAddr = 0xffffffff; 4229 gen.command.u.cache.sg_canz = 1; 4230 gen.command.u.cache.sg_lst[0].sg_ptr = (ulong32)paddr; 4231 gen.command.u.cache.sg_lst[0].sg_len = gen.data_len; 4232 gen.command.u.cache.sg_lst[1].sg_len = 0; 4233 } else { 4234 gen.command.u.cache.DestAddr = paddr; 4235 gen.command.u.cache.sg_canz = 0; 4236 } 4237 } 4238 } else if (gen.command.Service == SCSIRAWSERVICE) { 4239 if (ha->raw_feat & GDT_64BIT) { 4240 /* copy elements from 32-bit IOCTL structure */ 4241 char cmd[16]; 4242 gen.command.u.raw64.sense_len = gen.command.u.raw.sense_len; 4243 gen.command.u.raw64.bus = gen.command.u.raw.bus; 4244 gen.command.u.raw64.lun = gen.command.u.raw.lun; 4245 gen.command.u.raw64.target = gen.command.u.raw.target; 4246 memcpy(cmd, gen.command.u.raw.cmd, 16); 4247 memcpy(gen.command.u.raw64.cmd, cmd, 16); 4248 gen.command.u.raw64.clen = gen.command.u.raw.clen; 4249 gen.command.u.raw64.sdlen = gen.command.u.raw.sdlen; 4250 gen.command.u.raw64.direction = gen.command.u.raw.direction; 4251 /* addresses */ 4252 if (ha->raw_feat & SCATTER_GATHER) { 4253 gen.command.u.raw64.sdata = (ulong64)-1; 4254 gen.command.u.raw64.sg_ranz = 1; 4255 gen.command.u.raw64.sg_lst[0].sg_ptr = paddr; 4256 gen.command.u.raw64.sg_lst[0].sg_len = gen.data_len; 4257 gen.command.u.raw64.sg_lst[1].sg_len = 0; 4258 } else { 4259 gen.command.u.raw64.sdata = paddr; 4260 gen.command.u.raw64.sg_ranz = 0; 4261 } 4262 gen.command.u.raw64.sense_data = paddr + gen.data_len; 4263 } else { 4264 if (ha->raw_feat & SCATTER_GATHER) { 4265 gen.command.u.raw.sdata = 0xffffffff; 4266 gen.command.u.raw.sg_ranz = 1; 4267 gen.command.u.raw.sg_lst[0].sg_ptr = (ulong32)paddr; 4268 gen.command.u.raw.sg_lst[0].sg_len = gen.data_len; 4269 gen.command.u.raw.sg_lst[1].sg_len = 0; 4270 } else { 4271 gen.command.u.raw.sdata = paddr; 4272 gen.command.u.raw.sg_ranz = 0; 4273 } 4274 gen.command.u.raw.sense_data = (ulong32)paddr + gen.data_len; 4275 } 4276 } else { 4277 gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); 4278 return -EFAULT; 4279 } 4280 } 4281 4282 rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info); 4283 if (rval < 0) 4284 return rval; 4285 gen.status = rval; 4286 4287 if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, 4288 gen.data_len + gen.sense_len)) { 4289 gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); 4290 return -EFAULT; 4291 } 4292 if (copy_to_user(arg, &gen, 4293 sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) { 4294 gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); 4295 return -EFAULT; 4296 } 4297 gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); 4298 return 0; 4299} 4300 4301static int ioc_hdrlist(void __user *arg, char *cmnd) 4302{ 4303 gdth_ioctl_rescan *rsc; 4304 gdth_cmd_str *cmd; 4305 gdth_ha_str *ha; 4306 unchar i; 4307 int rc = -ENOMEM; 4308 u32 cluster_type = 0; 4309 4310 rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); 4311 cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); 4312 if (!rsc || !cmd) 4313 goto free_fail; 4314 4315 if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || 4316 (NULL == (ha = gdth_find_ha(rsc->ionode)))) { 4317 rc = -EFAULT; 4318 goto free_fail; 4319 } 4320 memset(cmd, 0, sizeof(gdth_cmd_str)); 4321 4322 for (i = 0; i < MAX_HDRIVES; ++i) { 4323 if (!ha->hdr[i].present) { 4324 rsc->hdr_list[i].bus = 0xff; 4325 continue; 4326 } 4327 rsc->hdr_list[i].bus = ha->virt_bus; 4328 rsc->hdr_list[i].target = i; 4329 rsc->hdr_list[i].lun = 0; 4330 rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type; 4331 if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) { 4332 cmd->Service = CACHESERVICE; 4333 cmd->OpCode = GDT_CLUST_INFO; 4334 if (ha->cache_feat & GDT_64BIT) 4335 cmd->u.cache64.DeviceNo = i; 4336 else 4337 cmd->u.cache.DeviceNo = i; 4338 if (__gdth_execute(ha->sdev, cmd, cmnd, 30, &cluster_type) == S_OK) 4339 rsc->hdr_list[i].cluster_type = cluster_type; 4340 } 4341 } 4342 4343 if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) 4344 rc = -EFAULT; 4345 else 4346 rc = 0; 4347 4348free_fail: 4349 kfree(rsc); 4350 kfree(cmd); 4351 return rc; 4352} 4353 4354static int ioc_rescan(void __user *arg, char *cmnd) 4355{ 4356 gdth_ioctl_rescan *rsc; 4357 gdth_cmd_str *cmd; 4358 ushort i, status, hdr_cnt; 4359 ulong32 info; 4360 int cyls, hds, secs; 4361 int rc = -ENOMEM; 4362 ulong flags; 4363 gdth_ha_str *ha; 4364 4365 rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); 4366 cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); 4367 if (!cmd || !rsc) 4368 goto free_fail; 4369 4370 if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || 4371 (NULL == (ha = gdth_find_ha(rsc->ionode)))) { 4372 rc = -EFAULT; 4373 goto free_fail; 4374 } 4375 memset(cmd, 0, sizeof(gdth_cmd_str)); 4376 4377 if (rsc->flag == 0) { 4378 /* old method: re-init. cache service */ 4379 cmd->Service = CACHESERVICE; 4380 if (ha->cache_feat & GDT_64BIT) { 4381 cmd->OpCode = GDT_X_INIT_HOST; 4382 cmd->u.cache64.DeviceNo = LINUX_OS; 4383 } else { 4384 cmd->OpCode = GDT_INIT; 4385 cmd->u.cache.DeviceNo = LINUX_OS; 4386 } 4387 4388 status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); 4389 i = 0; 4390 hdr_cnt = (status == S_OK ? (ushort)info : 0); 4391 } else { 4392 i = rsc->hdr_no; 4393 hdr_cnt = i + 1; 4394 } 4395 4396 for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) { 4397 cmd->Service = CACHESERVICE; 4398 cmd->OpCode = GDT_INFO; 4399 if (ha->cache_feat & GDT_64BIT) 4400 cmd->u.cache64.DeviceNo = i; 4401 else 4402 cmd->u.cache.DeviceNo = i; 4403 4404 status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); 4405 4406 spin_lock_irqsave(&ha->smp_lock, flags); 4407 rsc->hdr_list[i].bus = ha->virt_bus; 4408 rsc->hdr_list[i].target = i; 4409 rsc->hdr_list[i].lun = 0; 4410 if (status != S_OK) { 4411 ha->hdr[i].present = FALSE; 4412 } else { 4413 ha->hdr[i].present = TRUE; 4414 ha->hdr[i].size = info; 4415 /* evaluate mapping */ 4416 ha->hdr[i].size &= ~SECS32; 4417 gdth_eval_mapping(ha->hdr[i].size,&cyls,&hds,&secs); 4418 ha->hdr[i].heads = hds; 4419 ha->hdr[i].secs = secs; 4420 /* round size */ 4421 ha->hdr[i].size = cyls * hds * secs; 4422 } 4423 spin_unlock_irqrestore(&ha->smp_lock, flags); 4424 if (status != S_OK) 4425 continue; 4426 4427 /* extended info, if GDT_64BIT, for drives > 2 TB */ 4428 /* but we need ha->info2, not yet stored in scp->SCp */ 4429 4430 /* devtype, cluster info, R/W attribs */ 4431 cmd->Service = CACHESERVICE; 4432 cmd->OpCode = GDT_DEVTYPE; 4433 if (ha->cache_feat & GDT_64BIT) 4434 cmd->u.cache64.DeviceNo = i; 4435 else 4436 cmd->u.cache.DeviceNo = i; 4437 4438 status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); 4439 4440 spin_lock_irqsave(&ha->smp_lock, flags); 4441 ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0); 4442 spin_unlock_irqrestore(&ha->smp_lock, flags); 4443 4444 cmd->Service = CACHESERVICE; 4445 cmd->OpCode = GDT_CLUST_INFO; 4446 if (ha->cache_feat & GDT_64BIT) 4447 cmd->u.cache64.DeviceNo = i; 4448 else 4449 cmd->u.cache.DeviceNo = i; 4450 4451 status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); 4452 4453 spin_lock_irqsave(&ha->smp_lock, flags); 4454 ha->hdr[i].cluster_type = 4455 ((status == S_OK && !shared_access) ? (ushort)info : 0); 4456 spin_unlock_irqrestore(&ha->smp_lock, flags); 4457 rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type; 4458 4459 cmd->Service = CACHESERVICE; 4460 cmd->OpCode = GDT_RW_ATTRIBS; 4461 if (ha->cache_feat & GDT_64BIT) 4462 cmd->u.cache64.DeviceNo = i; 4463 else 4464 cmd->u.cache.DeviceNo = i; 4465 4466 status = __gdth_execute(ha->sdev, cmd, cmnd, 30, &info); 4467 4468 spin_lock_irqsave(&ha->smp_lock, flags); 4469 ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0); 4470 spin_unlock_irqrestore(&ha->smp_lock, flags); 4471 } 4472 4473 if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) 4474 rc = -EFAULT; 4475 else 4476 rc = 0; 4477 4478free_fail: 4479 kfree(rsc); 4480 kfree(cmd); 4481 return rc; 4482} 4483 4484static int gdth_ioctl(struct inode *inode, struct file *filep, 4485 unsigned int cmd, unsigned long arg) 4486{ 4487 gdth_ha_str *ha; 4488 Scsi_Cmnd *scp; 4489 ulong flags; 4490 char cmnd[MAX_COMMAND_SIZE]; 4491 void __user *argp = (void __user *)arg; 4492 4493 memset(cmnd, 0xff, 12); 4494 4495 TRACE(("gdth_ioctl() cmd 0x%x\n", cmd)); 4496 4497 switch (cmd) { 4498 case GDTIOCTL_CTRCNT: 4499 { 4500 int cnt = gdth_ctr_count; 4501 if (put_user(cnt, (int __user *)argp)) 4502 return -EFAULT; 4503 break; 4504 } 4505 4506 case GDTIOCTL_DRVERS: 4507 { 4508 int ver = (GDTH_VERSION<<8) | GDTH_SUBVERSION; 4509 if (put_user(ver, (int __user *)argp)) 4510 return -EFAULT; 4511 break; 4512 } 4513 4514 case GDTIOCTL_OSVERS: 4515 { 4516 gdth_ioctl_osvers osv; 4517 4518 osv.version = (unchar)(LINUX_VERSION_CODE >> 16); 4519 osv.subversion = (unchar)(LINUX_VERSION_CODE >> 8); 4520 osv.revision = (ushort)(LINUX_VERSION_CODE & 0xff); 4521 if (copy_to_user(argp, &osv, sizeof(gdth_ioctl_osvers))) 4522 return -EFAULT; 4523 break; 4524 } 4525 4526 case GDTIOCTL_CTRTYPE: 4527 { 4528 gdth_ioctl_ctrtype ctrt; 4529 4530 if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || 4531 (NULL == (ha = gdth_find_ha(ctrt.ionode)))) 4532 return -EFAULT; 4533 4534 if (ha->type == GDT_ISA || ha->type == GDT_EISA) { 4535 ctrt.type = (unchar)((ha->stype>>20) - 0x10); 4536 } else { 4537 if (ha->type != GDT_PCIMPR) { 4538 ctrt.type = (unchar)((ha->stype<<4) + 6); 4539 } else { 4540 ctrt.type = 4541 (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe); 4542 if (ha->stype >= 0x300) 4543 ctrt.ext_type = 0x6000 | ha->pdev->subsystem_device; 4544 else 4545 ctrt.ext_type = 0x6000 | ha->stype; 4546 } 4547 ctrt.device_id = ha->pdev->device; 4548 ctrt.sub_device_id = ha->pdev->subsystem_device; 4549 } 4550 ctrt.info = ha->brd_phys; 4551 ctrt.oem_id = ha->oem_id; 4552 if (copy_to_user(argp, &ctrt, sizeof(gdth_ioctl_ctrtype))) 4553 return -EFAULT; 4554 break; 4555 } 4556 4557 case GDTIOCTL_GENERAL: 4558 return ioc_general(argp, cmnd); 4559 4560 case GDTIOCTL_EVENT: 4561 return ioc_event(argp); 4562 4563 case GDTIOCTL_LOCKDRV: 4564 return ioc_lockdrv(argp); 4565 4566 case GDTIOCTL_LOCKCHN: 4567 { 4568 gdth_ioctl_lockchn lchn; 4569 unchar i, j; 4570 4571 if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || 4572 (NULL == (ha = gdth_find_ha(lchn.ionode)))) 4573 return -EFAULT; 4574 4575 i = lchn.channel; 4576 if (i < ha->bus_cnt) { 4577 if (lchn.lock) { 4578 spin_lock_irqsave(&ha->smp_lock, flags); 4579 ha->raw[i].lock = 1; 4580 spin_unlock_irqrestore(&ha->smp_lock, flags); 4581 for (j = 0; j < ha->tid_cnt; ++j) { 4582 gdth_wait_completion(ha, i, j); 4583 gdth_stop_timeout(ha, i, j); 4584 } 4585 } else { 4586 spin_lock_irqsave(&ha->smp_lock, flags); 4587 ha->raw[i].lock = 0; 4588 spin_unlock_irqrestore(&ha->smp_lock, flags); 4589 for (j = 0; j < ha->tid_cnt; ++j) { 4590 gdth_start_timeout(ha, i, j); 4591 gdth_next(ha); 4592 } 4593 } 4594 } 4595 break; 4596 } 4597 4598 case GDTIOCTL_RESCAN: 4599 return ioc_rescan(argp, cmnd); 4600 4601 case GDTIOCTL_HDRLIST: 4602 return ioc_hdrlist(argp, cmnd); 4603 4604 case GDTIOCTL_RESET_BUS: 4605 { 4606 gdth_ioctl_reset res; 4607 int rval; 4608 4609 if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || 4610 (NULL == (ha = gdth_find_ha(res.ionode)))) 4611 return -EFAULT; 4612 4613 scp = kzalloc(sizeof(*scp), GFP_KERNEL); 4614 if (!scp) 4615 return -ENOMEM; 4616 scp->device = ha->sdev; 4617 scp->cmd_len = 12; 4618 scp->device->channel = res.number; 4619 rval = gdth_eh_bus_reset(scp); 4620 res.status = (rval == SUCCESS ? S_OK : S_GENERR); 4621 kfree(scp); 4622 4623 if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset))) 4624 return -EFAULT; 4625 break; 4626 } 4627 4628 case GDTIOCTL_RESET_DRV: 4629 return ioc_resetdrv(argp, cmnd); 4630 4631 default: 4632 break; 4633 } 4634 return 0; 4635} 4636 4637 4638/* flush routine */ 4639static void gdth_flush(gdth_ha_str *ha) 4640{ 4641 int i; 4642 gdth_cmd_str gdtcmd; 4643 char cmnd[MAX_COMMAND_SIZE]; 4644 memset(cmnd, 0xff, MAX_COMMAND_SIZE); 4645 4646 TRACE2(("gdth_flush() hanum %d\n", ha->hanum)); 4647 4648 for (i = 0; i < MAX_HDRIVES; ++i) { 4649 if (ha->hdr[i].present) { 4650 gdtcmd.BoardNode = LOCALBOARD; 4651 gdtcmd.Service = CACHESERVICE; 4652 gdtcmd.OpCode = GDT_FLUSH; 4653 if (ha->cache_feat & GDT_64BIT) { 4654 gdtcmd.u.cache64.DeviceNo = i; 4655 gdtcmd.u.cache64.BlockNo = 1; 4656 gdtcmd.u.cache64.sg_canz = 0; 4657 } else { 4658 gdtcmd.u.cache.DeviceNo = i; 4659 gdtcmd.u.cache.BlockNo = 1; 4660 gdtcmd.u.cache.sg_canz = 0; 4661 } 4662 TRACE2(("gdth_flush(): flush ha %d drive %d\n", ha->hanum, i)); 4663 4664 gdth_execute(ha->shost, &gdtcmd, cmnd, 30, NULL); 4665 } 4666 } 4667} 4668 4669/* shutdown routine */ 4670static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) 4671{ 4672 gdth_ha_str *ha; 4673#ifndef __alpha__ 4674 gdth_cmd_str gdtcmd; 4675 char cmnd[MAX_COMMAND_SIZE]; 4676#endif 4677 4678 if (notifier_disabled) 4679 return NOTIFY_OK; 4680 4681 TRACE2(("gdth_halt() event %d\n",(int)event)); 4682 if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) 4683 return NOTIFY_DONE; 4684 4685 notifier_disabled = 1; 4686 printk("GDT-HA: Flushing all host drives .. "); 4687 list_for_each_entry(ha, &gdth_instances, list) { 4688 gdth_flush(ha); 4689 4690#ifndef __alpha__ 4691 /* controller reset */ 4692 memset(cmnd, 0xff, MAX_COMMAND_SIZE); 4693 gdtcmd.BoardNode = LOCALBOARD; 4694 gdtcmd.Service = CACHESERVICE; 4695 gdtcmd.OpCode = GDT_RESET; 4696 TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum)); 4697 gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL); 4698#endif 4699 } 4700 printk("Done.\n"); 4701 4702#ifdef GDTH_STATISTICS 4703 del_timer(&gdth_timer); 4704#endif 4705 return NOTIFY_OK; 4706} 4707 4708/* configure lun */ 4709static int gdth_slave_configure(struct scsi_device *sdev) 4710{ 4711 scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); 4712 sdev->skip_ms_page_3f = 1; 4713 sdev->skip_ms_page_8 = 1; 4714 return 0; 4715} 4716 4717static struct scsi_host_template gdth_template = { 4718 .name = "GDT SCSI Disk Array Controller", 4719 .info = gdth_info, 4720 .queuecommand = gdth_queuecommand, 4721 .eh_bus_reset_handler = gdth_eh_bus_reset, 4722 .slave_configure = gdth_slave_configure, 4723 .bios_param = gdth_bios_param, 4724 .proc_info = gdth_proc_info, 4725 .proc_name = "gdth", 4726 .can_queue = GDTH_MAXCMDS, 4727 .this_id = -1, 4728 .sg_tablesize = GDTH_MAXSG, 4729 .cmd_per_lun = GDTH_MAXC_P_L, 4730 .unchecked_isa_dma = 1, 4731 .use_clustering = ENABLE_CLUSTERING, 4732}; 4733 4734#ifdef CONFIG_ISA 4735static int __init gdth_isa_probe_one(ulong32 isa_bios) 4736{ 4737 struct Scsi_Host *shp; 4738 gdth_ha_str *ha; 4739 dma_addr_t scratch_dma_handle = 0; 4740 int error, i; 4741 4742 if (!gdth_search_isa(isa_bios)) 4743 return -ENXIO; 4744 4745 shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); 4746 if (!shp) 4747 return -ENOMEM; 4748 ha = shost_priv(shp); 4749 4750 error = -ENODEV; 4751 if (!gdth_init_isa(isa_bios,ha)) 4752 goto out_host_put; 4753 4754 /* controller found and initialized */ 4755 printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", 4756 isa_bios, ha->irq, ha->drq); 4757 4758 error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha); 4759 if (error) { 4760 printk("GDT-ISA: Unable to allocate IRQ\n"); 4761 goto out_host_put; 4762 } 4763 4764 error = request_dma(ha->drq, "gdth"); 4765 if (error) { 4766 printk("GDT-ISA: Unable to allocate DMA channel\n"); 4767 goto out_free_irq; 4768 } 4769 4770 set_dma_mode(ha->drq,DMA_MODE_CASCADE); 4771 enable_dma(ha->drq); 4772 shp->unchecked_isa_dma = 1; 4773 shp->irq = ha->irq; 4774 shp->dma_channel = ha->drq; 4775 4776 ha->hanum = gdth_ctr_count++; 4777 ha->shost = shp; 4778 4779 ha->pccb = &ha->cmdext; 4780 ha->ccb_phys = 0L; 4781 ha->pdev = NULL; 4782 4783 error = -ENOMEM; 4784 4785 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 4786 &scratch_dma_handle); 4787 if (!ha->pscratch) 4788 goto out_dec_counters; 4789 ha->scratch_phys = scratch_dma_handle; 4790 4791 ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), 4792 &scratch_dma_handle); 4793 if (!ha->pmsg) 4794 goto out_free_pscratch; 4795 ha->msg_phys = scratch_dma_handle; 4796 4797#ifdef INT_COAL 4798 ha->coal_stat = pci_alloc_consistent(ha->pdev, 4799 sizeof(gdth_coal_status) * MAXOFFSETS, 4800 &scratch_dma_handle); 4801 if (!ha->coal_stat) 4802 goto out_free_pmsg; 4803 ha->coal_stat_phys = scratch_dma_handle; 4804#endif 4805 4806 ha->scratch_busy = FALSE; 4807 ha->req_first = NULL; 4808 ha->tid_cnt = MAX_HDRIVES; 4809 if (max_ids > 0 && max_ids < ha->tid_cnt) 4810 ha->tid_cnt = max_ids; 4811 for (i = 0; i < GDTH_MAXCMDS; ++i) 4812 ha->cmd_tab[i].cmnd = UNUSED_CMND; 4813 ha->scan_mode = rescan ? 0x10 : 0; 4814 4815 error = -ENODEV; 4816 if (!gdth_search_drives(ha)) { 4817 printk("GDT-ISA: Error during device scan\n"); 4818 goto out_free_coal_stat; 4819 } 4820 4821 if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) 4822 hdr_channel = ha->bus_cnt; 4823 ha->virt_bus = hdr_channel; 4824 4825 if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) 4826 shp->max_cmd_len = 16; 4827 4828 shp->max_id = ha->tid_cnt; 4829 shp->max_lun = MAXLUN; 4830 shp->max_channel = ha->bus_cnt; 4831 4832 spin_lock_init(&ha->smp_lock); 4833 gdth_enable_int(ha); 4834 4835 error = scsi_add_host(shp, NULL); 4836 if (error) 4837 goto out_free_coal_stat; 4838 list_add_tail(&ha->list, &gdth_instances); 4839 return 0; 4840 4841 out_free_coal_stat: 4842#ifdef INT_COAL 4843 pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, 4844 ha->coal_stat, ha->coal_stat_phys); 4845 out_free_pmsg: 4846#endif 4847 pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 4848 ha->pmsg, ha->msg_phys); 4849 out_free_pscratch: 4850 pci_free_consistent(ha->pdev, GDTH_SCRATCH, 4851 ha->pscratch, ha->scratch_phys); 4852 out_dec_counters: 4853 gdth_ctr_count--; 4854 out_free_irq: 4855 free_irq(ha->irq, ha); 4856 out_host_put: 4857 scsi_host_put(shp); 4858 return error; 4859} 4860#endif /* CONFIG_ISA */ 4861 4862#ifdef CONFIG_EISA 4863static int __init gdth_eisa_probe_one(ushort eisa_slot) 4864{ 4865 struct Scsi_Host *shp; 4866 gdth_ha_str *ha; 4867 dma_addr_t scratch_dma_handle = 0; 4868 int error, i; 4869 4870 if (!gdth_search_eisa(eisa_slot)) 4871 return -ENXIO; 4872 4873 shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); 4874 if (!shp) 4875 return -ENOMEM; 4876 ha = shost_priv(shp); 4877 4878 error = -ENODEV; 4879 if (!gdth_init_eisa(eisa_slot,ha)) 4880 goto out_host_put; 4881 4882 /* controller found and initialized */ 4883 printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", 4884 eisa_slot >> 12, ha->irq); 4885 4886 error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha); 4887 if (error) { 4888 printk("GDT-EISA: Unable to allocate IRQ\n"); 4889 goto out_host_put; 4890 } 4891 4892 shp->unchecked_isa_dma = 0; 4893 shp->irq = ha->irq; 4894 shp->dma_channel = 0xff; 4895 4896 ha->hanum = gdth_ctr_count++; 4897 ha->shost = shp; 4898 4899 TRACE2(("EISA detect Bus 0: hanum %d\n", ha->hanum)); 4900 4901 ha->pccb = &ha->cmdext; 4902 ha->ccb_phys = 0L; 4903 4904 error = -ENOMEM; 4905 4906 ha->pdev = NULL; 4907 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 4908 &scratch_dma_handle); 4909 if (!ha->pscratch) 4910 goto out_free_irq; 4911 ha->scratch_phys = scratch_dma_handle; 4912 4913 ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), 4914 &scratch_dma_handle); 4915 if (!ha->pmsg) 4916 goto out_free_pscratch; 4917 ha->msg_phys = scratch_dma_handle; 4918 4919#ifdef INT_COAL 4920 ha->coal_stat = pci_alloc_consistent(ha->pdev, 4921 sizeof(gdth_coal_status) * MAXOFFSETS, 4922 &scratch_dma_handle); 4923 if (!ha->coal_stat) 4924 goto out_free_pmsg; 4925 ha->coal_stat_phys = scratch_dma_handle; 4926#endif 4927 4928 ha->ccb_phys = pci_map_single(ha->pdev,ha->pccb, 4929 sizeof(gdth_cmd_str), PCI_DMA_BIDIRECTIONAL); 4930 if (!ha->ccb_phys) 4931 goto out_free_coal_stat; 4932 4933 ha->scratch_busy = FALSE; 4934 ha->req_first = NULL; 4935 ha->tid_cnt = MAX_HDRIVES; 4936 if (max_ids > 0 && max_ids < ha->tid_cnt) 4937 ha->tid_cnt = max_ids; 4938 for (i = 0; i < GDTH_MAXCMDS; ++i) 4939 ha->cmd_tab[i].cmnd = UNUSED_CMND; 4940 ha->scan_mode = rescan ? 0x10 : 0; 4941 4942 if (!gdth_search_drives(ha)) { 4943 printk("GDT-EISA: Error during device scan\n"); 4944 error = -ENODEV; 4945 goto out_free_ccb_phys; 4946 } 4947 4948 if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) 4949 hdr_channel = ha->bus_cnt; 4950 ha->virt_bus = hdr_channel; 4951 4952 if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) 4953 shp->max_cmd_len = 16; 4954 4955 shp->max_id = ha->tid_cnt; 4956 shp->max_lun = MAXLUN; 4957 shp->max_channel = ha->bus_cnt; 4958 4959 spin_lock_init(&ha->smp_lock); 4960 gdth_enable_int(ha); 4961 4962 error = scsi_add_host(shp, NULL); 4963 if (error) 4964 goto out_free_coal_stat; 4965 list_add_tail(&ha->list, &gdth_instances); 4966 return 0; 4967 4968 out_free_ccb_phys: 4969 pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str), 4970 PCI_DMA_BIDIRECTIONAL); 4971 out_free_coal_stat: 4972#ifdef INT_COAL 4973 pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, 4974 ha->coal_stat, ha->coal_stat_phys); 4975 out_free_pmsg: 4976#endif 4977 pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 4978 ha->pmsg, ha->msg_phys); 4979 out_free_pscratch: 4980 pci_free_consistent(ha->pdev, GDTH_SCRATCH, 4981 ha->pscratch, ha->scratch_phys); 4982 out_free_irq: 4983 free_irq(ha->irq, ha); 4984 gdth_ctr_count--; 4985 out_host_put: 4986 scsi_host_put(shp); 4987 return error; 4988} 4989#endif /* CONFIG_EISA */ 4990 4991#ifdef CONFIG_PCI 4992static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) 4993{ 4994 struct Scsi_Host *shp; 4995 gdth_ha_str *ha; 4996 dma_addr_t scratch_dma_handle = 0; 4997 int error, i; 4998 4999 shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); 5000 if (!shp) 5001 return -ENOMEM; 5002 ha = shost_priv(shp); 5003 5004 error = -ENODEV; 5005 if (!gdth_init_pci(&pcistr[ctr],ha)) 5006 goto out_host_put; 5007 5008 /* controller found and initialized */ 5009 printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", 5010 pcistr[ctr].pdev->bus->number, 5011 PCI_SLOT(pcistr[ctr].pdev->devfn), 5012 ha->irq); 5013 5014 error = request_irq(ha->irq, gdth_interrupt, 5015 IRQF_DISABLED|IRQF_SHARED, "gdth", ha); 5016 if (error) { 5017 printk("GDT-PCI: Unable to allocate IRQ\n"); 5018 goto out_host_put; 5019 } 5020 5021 shp->unchecked_isa_dma = 0; 5022 shp->irq = ha->irq; 5023 shp->dma_channel = 0xff; 5024 5025 ha->hanum = gdth_ctr_count++; 5026 ha->shost = shp; 5027 5028 ha->pccb = &ha->cmdext; 5029 ha->ccb_phys = 0L; 5030 5031 error = -ENOMEM; 5032 5033 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 5034 &scratch_dma_handle); 5035 if (!ha->pscratch) 5036 goto out_free_irq; 5037 ha->scratch_phys = scratch_dma_handle; 5038 5039 ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), 5040 &scratch_dma_handle); 5041 if (!ha->pmsg) 5042 goto out_free_pscratch; 5043 ha->msg_phys = scratch_dma_handle; 5044 5045#ifdef INT_COAL 5046 ha->coal_stat = pci_alloc_consistent(ha->pdev, 5047 sizeof(gdth_coal_status) * MAXOFFSETS, 5048 &scratch_dma_handle); 5049 if (!ha->coal_stat) 5050 goto out_free_pmsg; 5051 ha->coal_stat_phys = scratch_dma_handle; 5052#endif 5053 5054 ha->scratch_busy = FALSE; 5055 ha->req_first = NULL; 5056 ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; 5057 if (max_ids > 0 && max_ids < ha->tid_cnt) 5058 ha->tid_cnt = max_ids; 5059 for (i = 0; i < GDTH_MAXCMDS; ++i) 5060 ha->cmd_tab[i].cmnd = UNUSED_CMND; 5061 ha->scan_mode = rescan ? 0x10 : 0; 5062 5063 error = -ENODEV; 5064 if (!gdth_search_drives(ha)) { 5065 printk("GDT-PCI %d: Error during device scan\n", ha->hanum); 5066 goto out_free_coal_stat; 5067 } 5068 5069 if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) 5070 hdr_channel = ha->bus_cnt; 5071 ha->virt_bus = hdr_channel; 5072 5073 /* 64-bit DMA only supported from FW >= x.43 */ 5074 if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || 5075 !ha->dma64_support) { 5076 if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { 5077 printk(KERN_WARNING "GDT-PCI %d: " 5078 "Unable to set 32-bit DMA\n", ha->hanum); 5079 goto out_free_coal_stat; 5080 } 5081 } else { 5082 shp->max_cmd_len = 16; 5083 if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { 5084 printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); 5085 } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { 5086 printk(KERN_WARNING "GDT-PCI %d: " 5087 "Unable to set 64/32-bit DMA\n", ha->hanum); 5088 goto out_free_coal_stat; 5089 } 5090 } 5091 5092 shp->max_id = ha->tid_cnt; 5093 shp->max_lun = MAXLUN; 5094 shp->max_channel = ha->bus_cnt; 5095 5096 spin_lock_init(&ha->smp_lock); 5097 gdth_enable_int(ha); 5098 5099 error = scsi_add_host(shp, &pcistr[ctr].pdev->dev); 5100 if (error) 5101 goto out_free_coal_stat; 5102 list_add_tail(&ha->list, &gdth_instances); 5103 return 0; 5104 5105 out_free_coal_stat: 5106#ifdef INT_COAL 5107 pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, 5108 ha->coal_stat, ha->coal_stat_phys); 5109 out_free_pmsg: 5110#endif 5111 pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 5112 ha->pmsg, ha->msg_phys); 5113 out_free_pscratch: 5114 pci_free_consistent(ha->pdev, GDTH_SCRATCH, 5115 ha->pscratch, ha->scratch_phys); 5116 out_free_irq: 5117 free_irq(ha->irq, ha); 5118 gdth_ctr_count--; 5119 out_host_put: 5120 scsi_host_put(shp); 5121 return error; 5122} 5123#endif /* CONFIG_PCI */ 5124 5125static void gdth_remove_one(gdth_ha_str *ha) 5126{ 5127 struct Scsi_Host *shp = ha->shost; 5128 5129 TRACE2(("gdth_remove_one()\n")); 5130 5131 scsi_remove_host(shp); 5132 5133 if (ha->sdev) { 5134 scsi_free_host_dev(ha->sdev); 5135 ha->sdev = NULL; 5136 } 5137 5138 gdth_flush(ha); 5139 5140 if (shp->irq) 5141 free_irq(shp->irq,ha); 5142 5143#ifdef CONFIG_ISA 5144 if (shp->dma_channel != 0xff) 5145 free_dma(shp->dma_channel); 5146#endif 5147#ifdef INT_COAL 5148 if (ha->coal_stat) 5149 pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * 5150 MAXOFFSETS, ha->coal_stat, ha->coal_stat_phys); 5151#endif 5152 if (ha->pscratch) 5153 pci_free_consistent(ha->pdev, GDTH_SCRATCH, 5154 ha->pscratch, ha->scratch_phys); 5155 if (ha->pmsg) 5156 pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 5157 ha->pmsg, ha->msg_phys); 5158 if (ha->ccb_phys) 5159 pci_unmap_single(ha->pdev,ha->ccb_phys, 5160 sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); 5161 5162 scsi_host_put(shp); 5163} 5164 5165static int __init gdth_init(void) 5166{ 5167 if (disable) { 5168 printk("GDT-HA: Controller driver disabled from" 5169 " command line !\n"); 5170 return 0; 5171 } 5172 5173 printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n", 5174 GDTH_VERSION_STR); 5175 5176 /* initializations */ 5177 gdth_polling = TRUE; 5178 gdth_clear_events(); 5179 5180 /* As default we do not probe for EISA or ISA controllers */ 5181 if (probe_eisa_isa) { 5182 /* scanning for controllers, at first: ISA controller */ 5183#ifdef CONFIG_ISA 5184 ulong32 isa_bios; 5185 for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL; 5186 isa_bios += 0x8000UL) 5187 gdth_isa_probe_one(isa_bios); 5188#endif 5189#ifdef CONFIG_EISA 5190 { 5191 ushort eisa_slot; 5192 for (eisa_slot = 0x1000; eisa_slot <= 0x8000; 5193 eisa_slot += 0x1000) 5194 gdth_eisa_probe_one(eisa_slot); 5195 } 5196#endif 5197 } 5198 5199#ifdef CONFIG_PCI 5200 /* scanning for PCI controllers */ 5201 { 5202 gdth_pci_str pcistr[MAXHA]; 5203 int cnt,ctr; 5204 5205 cnt = gdth_search_pci(pcistr); 5206 printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt); 5207 gdth_sort_pci(pcistr,cnt); 5208 for (ctr = 0; ctr < cnt; ++ctr) 5209 gdth_pci_probe_one(pcistr, ctr); 5210 } 5211#endif /* CONFIG_PCI */ 5212 5213 TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); 5214 5215 if (list_empty(&gdth_instances)) 5216 return -ENODEV; 5217 5218#ifdef GDTH_STATISTICS 5219 TRACE2(("gdth_detect(): Initializing timer !\n")); 5220 init_timer(&gdth_timer); 5221 gdth_timer.expires = jiffies + HZ; 5222 gdth_timer.data = 0L; 5223 gdth_timer.function = gdth_timeout; 5224 add_timer(&gdth_timer); 5225#endif 5226 major = register_chrdev(0,"gdth", &gdth_fops); 5227 notifier_disabled = 0; 5228 register_reboot_notifier(&gdth_notifier); 5229 gdth_polling = FALSE; 5230 return 0; 5231} 5232 5233static void __exit gdth_exit(void) 5234{ 5235 gdth_ha_str *ha; 5236 5237 list_for_each_entry(ha, &gdth_instances, list) 5238 gdth_remove_one(ha); 5239 5240#ifdef GDTH_STATISTICS 5241 del_timer(&gdth_timer); 5242#endif 5243 unregister_chrdev(major,"gdth"); 5244 unregister_reboot_notifier(&gdth_notifier); 5245} 5246 5247module_init(gdth_init); 5248module_exit(gdth_exit); 5249 5250#ifndef MODULE 5251__setup("gdth=", option_setup); 5252#endif