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

Configure Feed

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

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