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