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