]> git.pld-linux.org Git - packages/kernel.git/blob - dpt_i2o-2.2.19.diff
- added description of djurban's branch
[packages/kernel.git] / dpt_i2o-2.2.19.diff
1 --- /dev/null   Sat Apr 14 07:06:21 2001
2 +++ linux/drivers/scsi/dpti.c   Wed Jul 18 14:31:28 2001
3 @@ -0,0 +1,3835 @@
4 +/***************************************************************************
5 +                          dpti.c  -  description
6 +                             -------------------
7 +    begin                : Thu Sep 7 2001
8 +    copyright            : (C) 2000 by Adaptec
9 +    email                : deanna_bonds@adaptec.com
10 +
11 +    ToDo                : Investigate why we can't throttle the scsi
12 +                          subsystem. It can't handle a condition where
13 +                          no commands can be issued to the controller.
14 +                        : If there is no TID for LUN0, but one for LUNx,
15 +                          we need to fake an inquiry response at LUN0 to x-1
16 +                          indicating that we support LUNs. This is to
17 +                          support Fibre and SCSI bridges.
18 +
19 +    See README.dpti for history, notes, license info, and credits
20 + ***************************************************************************/
21 +
22 +/***************************************************************************
23 + *                                                                         *
24 + *   This program is free software; you can redistribute it and/or modify  *
25 + *   it under the terms of the GNU General Public License as published by  *
26 + *   the Free Software Foundation; either version 2 of the License, or     *
27 + *   (at your option) any later version.                                   *
28 + *                                                                         *
29 + ***************************************************************************/
30 +
31 +//#define DEBUG 1
32 +//#define UARTDELAY 1
33 +
34 +
35 +
36 +//Define ADDR32 = GFP_DMA for 64 bin architectures.  This provides us with a
37 +//way to work withing the boundaries of i2o address space limitations -
38 +//the exception is our own private scsi cmd which can take 64 bit sg
39 +#define ADDR32 0
40 +//#define ADDR32 GFP_DMA
41 +
42 +#include <linux/autoconf.h>
43 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
44 +#      define MODVERSIONS
45 +#endif
46 +
47 +#if defined MODVERSIONS && defined MODULE
48 +#      include <linux/modversions.h>
49 +#endif
50 +
51 +#include <linux/version.h>
52 +
53 +#ifdef MODULE
54 +#include <linux/module.h>
55 +
56 +MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
57 +MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
58 +char kernel_version[] = UTS_RELEASE;
59 +
60 +#endif
61 +
62 +////////////////////////////////////////////////////////////////
63 +
64 +#include <linux/ioctl.h>       /* For SCSI-Passthrough */
65 +#include <asm/uaccess.h>
66 +
67 +#include <linux/stat.h>
68 +#include <linux/malloc.h>      /* for kmalloc() */
69 +#include <linux/config.h>      /* for CONFIG_PCI */
70 +#include <linux/pci.h>         /* for PCI support */
71 +#include <linux/proc_fs.h>
72 +#include <linux/blk.h>
73 +#include <linux/delay.h>       /* for udelay */
74 +#include <linux/tqueue.h>
75 +#include <linux/interrupt.h>
76 +#include <linux/kernel.h>      /* for printk */
77 +#include <linux/sched.h>
78 +#include <linux/reboot.h>
79 +#include <linux/smp_lock.h>
80 +
81 +#include <linux/timer.h>
82 +#include <linux/string.h>
83 +#include <linux/ioport.h>
84 +#include <linux/stat.h>
85 +
86 +#include <asm/processor.h>     /* for boot_cpu_data */
87 +#include <asm/pgtable.h>
88 +#include <asm/io.h>            /* for virt_to_bus, etc. */
89 +
90 +#include "scsi.h"
91 +#include "hosts.h"
92 +#include "sd.h"
93 +
94 +#include "dptsig.h"
95 +#include "dpti.h"
96 +
97 +/* Create a binary signature */
98 +static dpt_sig_S DPTI_sig = {
99 +       {'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
100 +#ifdef __i386__
101 +       PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
102 +#elif defined __ia64__
103 +       PROC_INTEL, PROC_IA64,
104 +#elif define __sparc__
105 +       PROC_ULTRASPARC,
106 +#elif defined(__alpha__)
107 +       PROC_ALPHA ,
108 +#else
109 +#error This has not been ported to your architecture
110 +#endif
111 +        FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
112 +       ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
113 +       DPT_MONTH, DPT_DAY, DPT_YEAR, "Adaptec Linux I2O RAID Driver"
114 +};
115 +
116 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
117 +static struct semaphore adpt_configuration_lock = MUTEX;
118 +#else
119 +DECLARE_MUTEX(adpt_configuration_lock);
120 +#endif
121 +static struct i2o_sys_tbl *sys_tbl = NULL;
122 +static int sys_tbl_ind = 0;
123 +static int sys_tbl_len = 0;
124 +/*
125 + * The method for determining if PCI is present was changed in the 2.1.xx tree.
126 + */
127 +#define NEWPCI_VERSION KERNEL_VERSION(2,1,92)
128 +
129 +static adpt_hba* hbas[DPTI_MAX_HBA];
130 +static adpt_hba* hba_chain = NULL;
131 +static int hba_count = 0;
132 +
133 +// Debug flags to be put into the HBA flags field when initialized
134 +// Make sure to enable DEBUG_PRINT for these flags to work
135 +unsigned long DebugFlags = HBA_FLAGS_DBG_SCAN_B | HBA_FLAGS_DBG_FLAGS_MASK;
136 +
137 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
138 +// If this is driver is embedded in the kernel this define
139 +// should be moved to include/linux/proc_fs.h as an emumerated type
140 +#define PROC_SCSI_DPT_I2O  0
141 +struct proc_dir_entry proc_scsi_dptI2O = {
142 +       PROC_SCSI_DPT_I2O, 7, DPT_DRIVER,
143 +       S_IFDIR | S_IRUGO | S_IXUGO, 2,
144 +       0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
145 +};
146 +#endif
147 +
148 +static struct file_operations adpt_fops = {
149 +       ioctl: adpt_ioctl,
150 +       open: adpt_open,
151 +       release: adpt_close
152 +};
153 +
154 +#ifdef REBOOT_NOTIFIER
155 +static struct notifier_block adpt_reboot_notifier =
156 +{
157 +        adpt_reboot_event,
158 +        NULL,
159 +        0
160 +};
161 +#endif
162 +
163 +inline u32 adpt_getBlinkLED(adpt_hba* host)
164 +{
165 +       return (host->FwDebugBLEDflag_P && (volatile u32)(*(host->FwDebugBLEDflag_P)) == 0xbc) ?
166 +                       host->FwDebugBLEDvalue_P[0] : 0;
167 +}
168 +
169 +inline struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
170 +{
171 +
172 +       struct adpt_device* d;
173 +
174 +       if( pHba->channel[chan].device == NULL){
175 +               printk(KERN_ERR"Adaptec I2O RAID: Trying to find device before they are allocated\n");
176 +               return NULL;
177 +       }
178 +
179 +       d = pHba->channel[chan].device[id];
180 +       if(!d || d->tid == 0) {
181 +               return NULL;
182 +       }
183 +
184 +       if(d->scsi_lun == lun){
185 +               return d;
186 +       }
187 +
188 +       for(d=d->next_lun ; d ; d = d->next_lun){
189 +               if(d->scsi_lun == lun){
190 +                       return d;
191 +               }
192 +       }
193 +
194 +       return NULL;
195 +}
196 +
197 +///////////////////////////////////////////////////////////////////////
198 +///////////////////////////////////////////////////////////////////////
199 +//                             Functions
200 +///////////////////////////////////////////////////////////////////////
201 +///////////////////////////////////////////////////////////////////////
202 +
203 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
204 +
205 +Scsi_Host_Template driver_template = DPT_I2O;
206 +#include "scsi_module.c"
207 +
208 +#else
209 +#ifdef MODULE 
210 +
211 +Scsi_Host_Template driver_template = DPT_I2O;
212 +#include "scsi_module.c"
213 +
214 +#endif
215 +#endif
216 +
217 +
218 +static int adpt_i2o_systab_send(adpt_hba* pHba)
219 +{
220 +        u32 msg[12];
221 +        int ret;
222 +
223 +       msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
224 +       msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
225 +       msg[2] = 0;
226 +       msg[3] = 0;
227 +       msg[4] = (0<<16) | ((pHba->unit+2) << 12); /* Host 0 IOP ID (unit + 2) */
228 +       msg[5] = 0;                                /* Segment 0 */
229 +
230 +       /* 
231 +        * Provide three SGL-elements:
232 +        * System table (SysTab), Private memory space declaration and 
233 +        * Private i/o space declaration  
234 +        */
235 +       msg[6] = 0x54000000 | sys_tbl_len;
236 +       msg[7] = virt_to_phys(sys_tbl);
237 +       msg[8] = 0x54000000 | 0;
238 +       msg[9] = 0;
239 +       msg[10] = 0xD4000000 | 0;
240 +       msg[11] = 0;
241 +
242 +       if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 120))) {
243 +               printk(KERN_INFO "%s: Unable to set SysTab (status=%#10x).\n", 
244 +                       pHba->name, ret);
245 +       }
246 +#ifdef DEBUG
247 +       else {
248 +               PINFO("%s: SysTab set.\n", pHba->name);
249 +       }
250 +#endif
251 +
252 +       return ret;     
253 + }
254 +
255 +
256 +void adpt_i2o_sys_shutdown(void)
257 +{
258 +       adpt_hba *pHba, *pNext;
259 +
260 +        printk(KERN_INFO "Shutting down Adaptec I2O controllers.\n");
261 +        printk(KERN_INFO
262 +                 "   This could take a few minutes if there are many devices attached\n");
263 +       /* Delete all IOPs from the controller chain */
264 +       for (pHba = hba_chain; pHba; pHba = pNext) {
265 +               pNext = pHba->next;
266 +               adpt_i2o_delete_hba(pHba);
267 +       }
268 +
269 +        printk(KERN_INFO "Adaptec I2O controllers down.\n");
270 +}
271 +
272 +/*
273 + * reboot/shutdown notification.
274 + *
275 + * - Quiesce each IOP in the system
276 + *
277 + */
278 +
279 +#ifdef REBOOT_NOTIFIER
280 +int adpt_reboot_event(struct notifier_block *n, unsigned long code, void *p)
281 +{
282 +
283 +        if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
284 +                 return NOTIFY_DONE;
285 +
286 +        adpt_i2o_sys_shutdown();
287 +
288 +        return NOTIFY_DONE;
289 +}
290 +#endif
291 +
292 +
293 +int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) 
294 +{
295 +
296 +       adpt_hba* pHba = NULL;
297 +       adpt_hba* p = NULL;
298 +       caddr_t base_addr0_phys = NULL;
299 +       caddr_t base_addr1_phys = NULL;
300 +       u32 hba_map0_area_size = 0;
301 +       u32 hba_map1_area_size = 0;
302 +       caddr_t base_addr_virt = NULL;
303 +       caddr_t msg_addr_virt = NULL;
304 +
305 +       int raptorFlag = FALSE;
306 +       int i;
307 +
308 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
309 +       if(pci_enable_device(pDev)) {
310 +               return -EINVAL;
311 +       }
312 +       pci_set_master(pDev);
313 +
314 +       base_addr0_phys = (caddr_t)pci_resource_start(pDev,0);
315 +       hba_map0_area_size = pci_resource_len(pDev,0);
316 +
317 +       // Check if standard PCI card or single BAR Raptor
318 +       if(pDev->device == PCI_DPT_DEVICE_ID){
319 +               if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){
320 +                       // Raptor card with this device id needs 4M
321 +                       hba_map0_area_size = 0x400000;
322 +               } else { // Not Raptor - it is a PCI card
323 +                       if(hba_map0_area_size > 0x100000 ){ 
324 +                               hba_map0_area_size = 0x100000;
325 +                       }
326 +               }
327 +       } else {// Raptor split BAR config
328 +               // Use BAR1 in this configuration
329 +               base_addr1_phys = (caddr_t)pci_resource_start(pDev,1);
330 +               hba_map1_area_size = pci_resource_len(pDev,1);
331 +               raptorFlag = TRUE;
332 +       }
333 +
334 +
335 +#else
336 +       u16 command = 0;
337 +       u16 subdevice = 0;
338 +
339 +       // Read in the command register and make sure that the device is 
340 +       // enabled and set up for bus master                             
341 +       pci_read_config_word(pDev, PCI_COMMAND, &command);
342 +       if(((command & PCI_COMMAND_MEMORY) && !(command & PCI_COMMAND_MASTER))){
343 +               command |= PCI_COMMAND_MASTER;
344 +               pci_write_config_word(pDev, PCI_COMMAND, command);
345 +       }
346 +
347 +       pci_read_config_dword(pDev, PCI_BASE_ADDRESS_0,(u32*)&base_addr0_phys);
348 +       // To get the size of the memory space taken we have to write out
349 +       // 0xffffffff (32 bit) to the base register (PCI_BASE_ADDRESS_0)
350 +       // and then read it back. The lower 4 bits are ignored not needed.
351 +       // They contain address space flag (io or memory) 
352 +       // and memory type (32 1M 64)
353 +       // The Rest is used to determine the size of memory space
354 +       // used. All other upper bits will be set to ones. 
355 +       // If we take the negative of this number and add one
356 +       // it will give us the memory size. We must also write the original
357 +       // Base address back out to reset it up.
358 +       pci_write_config_dword(pDev, PCI_BASE_ADDRESS_0 , 0xffffffff);
359 +       pci_read_config_dword(pDev, PCI_BASE_ADDRESS_0 , &hba_map0_area_size);
360 +
361 +       // Restore the base address
362 +       pci_write_config_dword(pDev, PCI_BASE_ADDRESS_0 , (u32)base_addr0_phys);
363 +       (u32)base_addr0_phys &= PCI_BASE_ADDRESS_MEM_MASK;
364 +
365 +       // Take the negative, disreguard the bottem four bits and add 1
366 +       hba_map0_area_size &= PCI_BASE_ADDRESS_MEM_MASK;        // And out the lower 4 bits
367 +       hba_map0_area_size = ~hba_map0_area_size + 1;   // Take the negative and add 1
368 +
369 +       pci_read_config_word (pDev, PCI_SUBSYSTEM_ID, &subdevice);
370 +
371 +       if(pDev->device == PCI_DPT_DEVICE_ID){
372 +               // Raptor card with this device id  needs 4M
373 +               if(subdevice >= 0xc032 && subdevice <= 0xc03b){ 
374 +                       hba_map0_area_size = 0x400000;
375 +               } else {
376 +                       if(hba_map0_area_size > 0x100000) { // Only give 'em 1M
377 +                               hba_map0_area_size = 0x100000;
378 +                       }
379 +               }
380 +       } else {
381 +               //Use BAR1 in this config
382 +               pci_read_config_dword(pDev,PCI_BASE_ADDRESS_1, (u32*)&base_addr1_phys);
383 +               pci_write_config_dword(pDev,PCI_BASE_ADDRESS_1, 0xffffffff);
384 +               pci_read_config_dword(pDev,PCI_BASE_ADDRESS_1, &hba_map1_area_size);
385 +
386 +               //Restore the base address
387 +               pci_write_config_dword(pDev,PCI_BASE_ADDRESS_1, (u32)base_addr1_phys);
388 +               (u32)base_addr1_phys &= PCI_BASE_ADDRESS_MEM_MASK;
389 +               hba_map1_area_size &= PCI_BASE_ADDRESS_MEM_MASK;
390 +               hba_map1_area_size = ~hba_map1_area_size + 1;
391 +               
392 +               raptorFlag=TRUE;
393 +       }
394 +#endif
395 +
396 +       base_addr_virt = ioremap((long)base_addr0_phys,(long)hba_map0_area_size);
397 +       if(base_addr_virt == NULL) {
398 +               PERROR("dpti: adpt_config_hba: io remap failed\n");
399 +               return -EINVAL;
400 +       }
401 +
402 +        if(raptorFlag == TRUE) {
403 +               msg_addr_virt = ioremap((long)base_addr1_phys, (long)hba_map1_area_size );
404 +               if(msg_addr_virt == NULL) {
405 +                       PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
406 +                       return -EINVAL;
407 +               }
408 +       } else {
409 +               msg_addr_virt = base_addr_virt;
410 +       }
411 +       
412 +       // Allocate and zero the data structure
413 +       if( (pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL)) == NULL) {
414 +               iounmap(base_addr_virt);
415 +               return -ENOMEM;
416 +       }
417 +       memset(pHba, 0, sizeof(adpt_hba));
418 +
419 +       down(&adpt_configuration_lock);
420 +       for(i=0;i<DPTI_MAX_HBA;i++) {
421 +               if(hbas[i]==NULL) {
422 +                       hbas[i]=pHba;
423 +                       break;
424 +               }
425 +       }
426 +
427 +       if(hba_chain != NULL){
428 +               for(p = hba_chain; p->next; p = p->next);
429 +               p->next = pHba;
430 +       } else {
431 +               hba_chain = pHba;
432 +       }
433 +       pHba->next = NULL;
434 +//     pHba->next=hba_chain;
435 +//     hba_chain=pHba;
436 +       pHba->unit = hba_count;
437 +       sprintf(pHba->name, "dpti%d", i);
438 +       hba_count++;
439 +       
440 +       up(&adpt_configuration_lock);
441 +
442 +       pHba->pDev = pDev;
443 +       pHba->base_addr_phys = base_addr0_phys;
444 +
445 +       // Set up the Virtual Base Address of the I2O Device
446 +       pHba->base_addr_virt = base_addr_virt;
447 +       pHba->msg_addr_virt = msg_addr_virt;  
448 +       pHba->irq_mask = (ulong)(base_addr_virt+0x30);
449 +       pHba->post_port = (ulong)(base_addr_virt+0x40);
450 +       pHba->reply_port = (ulong)(base_addr_virt+0x44);
451 +
452 +       pHba->hrt = NULL;
453 +       pHba->lct = NULL;
454 +       pHba->lct_size = 0;
455 +       pHba->status_block = NULL;
456 +       pHba->post_count = 0;
457 +       pHba->state = DPTI_STATE_RESET;
458 +       pHba->pDev = pDev;
459 +       pHba->devices = NULL;
460 +
461 +       // Initializing the spinlocks
462 +       spin_lock_init(&pHba->state_lock);
463 +
464 +       if(raptorFlag == 0){
465 +               printk(KERN_INFO"Adaptec I2O RAID controller %d at %p size=%x irq=%d\n", 
466 +                       hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);
467 +       } else {
468 +               printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);
469 +               printk(KERN_INFO"     BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size);
470 +               printk(KERN_INFO"     BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size);
471 +
472 +       }
473 +
474 +       if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, pHba)) {
475 +               printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
476 +               adpt_i2o_delete_hba(pHba);
477 +               return -EINVAL;
478 +       }
479 +
480 +       return 0;
481 +}
482 +
483 +
484 +void adpt_i2o_delete_hba(adpt_hba* pHba)
485 +{
486 +       adpt_hba* p1;
487 +       adpt_hba* p2;
488 +       struct i2o_device* d;
489 +       struct i2o_device* next;
490 +       int i;
491 +       int j;
492 +       struct adpt_device* pDev;
493 +       struct adpt_device* pNext;
494 +
495 +
496 +       down(&adpt_configuration_lock);
497 +       // scsi_unregister calls our adpt_release which
498 +       // does a quiese
499 +       if(pHba->host){
500 +               free_irq(pHba->host->irq, pHba);
501 +       }
502 +       for(i=0;i<DPTI_MAX_HBA;i++) {
503 +               if(hbas[i]==pHba) {
504 +                       hbas[i] = NULL;
505 +               }
506 +       }
507 +       p2 = NULL;
508 +       for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
509 +               if(p1 == pHba) {
510 +                       if(p2) {
511 +                               p2->next = p1->next;
512 +                       } else {
513 +                               hba_chain = p1->next;
514 +                       }
515 +                       break;
516 +               }
517 +       }
518 +
519 +       hba_count--;
520 +       up(&adpt_configuration_lock);
521 +
522 +       iounmap(pHba->base_addr_virt);
523 +       if(pHba->msg_addr_virt != pHba->base_addr_virt){
524 +               iounmap(pHba->msg_addr_virt);
525 +       }
526 +       if(pHba->hrt) {
527 +               kfree(pHba->hrt);
528 +       }
529 +       if(pHba->lct){
530 +               kfree(pHba->lct);
531 +       }
532 +       if(pHba->status_block) {
533 +               kfree(pHba->status_block);
534 +       }
535 +       if(pHba->reply_pool){
536 +               kfree(pHba->reply_pool);
537 +       }
538 +
539 +       for(d = pHba->devices; d ; d = next){
540 +               next = d->next;
541 +               kfree(d);
542 +       }
543 +       for(i = 0 ; i < pHba->top_scsi_channel ; i++){
544 +               for(j = 0; j < MAX_ID; j++){
545 +                       if(pHba->channel[i].device[j] != NULL){
546 +                               for(pDev = pHba->channel[i].device[j]; pDev; pDev = pNext){
547 +                                       pNext = pDev->next_lun;
548 +                                       kfree(pDev);
549 +                               }
550 +                       }
551 +               }
552 +       }
553 +
554 +       kfree(pHba);
555 +
556 +       if(hba_count <= 0){
557 +               unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
558 +       }
559 +}
560 +
561 +
562 +
563 +/* 
564 + * Enable IOP. Allows the IOP to resume external operations.
565 + */
566 +int adpt_i2o_enable_hba(adpt_hba* pHba)
567 +{
568 +       u32 msg[4];
569 +       int ret;
570 +       
571 +       adpt_i2o_status_get(pHba);
572 +       if(!pHba->status_block){
573 +               return -ENOMEM;
574 +       }
575 +       /* Enable only allowed on READY state */
576 +       if(pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
577 +               return 0;
578 +
579 +       if(pHba->status_block->iop_state != ADAPTER_STATE_READY)
580 +               return -EINVAL;
581 +
582 +       msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
583 +       msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
584 +       msg[2]= 0;
585 +       msg[3]= 0;
586 +
587 +       /* How long of a timeout do we need? */
588 +
589 +       if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
590 +               printk(KERN_ERR "%s: Could not enable (status=%#10x).\n", 
591 +                       pHba->name, ret);
592 +       } else {
593 +               printk(KERN_INFO "%s: Enabled.\n", pHba->name);
594 +       }
595 +
596 +       adpt_i2o_status_get(pHba);
597 +       return ret;
598 +}
599 +
600 +
601 +/*
602 + *     Bring a controller online into OPERATIONAL state. 
603 + */
604
605 +int adpt_i2o_online_hba(adpt_hba* pHba)
606 +{
607 +       if (adpt_i2o_systab_send(pHba) < 0) {
608 +               adpt_i2o_delete_hba(pHba);
609 +               return -1;
610 +       }
611 +       /* In READY state */
612 +
613 +       if (adpt_i2o_enable_hba(pHba) < 0) {
614 +               adpt_i2o_delete_hba(pHba);
615 +               return -1;
616 +       }
617 +
618 +       /* In OPERATIONAL state  */
619 +       return 0;
620 +}
621 +
622 +
623 +// This function is called by the OS at initalization time. The system  
624 +// is scanned For HBAs. Once an HBA is found various structures are
625 +// set up for the HBA and a list of all devices on the HBA is generated.
626 +// Once all HBAs are found, a device lookup table is set up and then
627 +// each HBA is enabled and presented to the OS.
628 +
629 +
630 +int adpt_detect(Scsi_Host_Template* sht)
631 +{
632 +       struct pci_dev *pDev = NULL;
633 +       adpt_hba* pHba;
634 +
635 +       adpt_init();
636 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
637 +       sht->proc_dir = &proc_scsi_dptI2O;
638 +#endif
639 +       sht->use_new_eh_code = 1;
640 +
641 +       PINFO("Detecting Adaptec I2O RAID controllers...\n");
642 +
643 +        /* search for all Adatpec I2O RAID cards */
644 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
645 +       while ((pDev = pci_find_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
646 +               if(pDev->device == PCI_DPT_DEVICE_ID ||
647 +                  pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
648 +                       if(adpt_install_hba(sht, pDev) ){
649 +                               PERROR("Could not Init an I2O RAID device\n");
650 +                               PERROR("Will not try to detect others.\n");
651 +                               return hba_count-1;
652 +                       }
653 +               }
654 +       }
655 +#else
656 +       while ((pDev = adpt_pci_find_device( PCI_DPT_VENDOR_ID, pDev))) {
657 +               if(pDev->device == PCI_DPT_DEVICE_ID ||
658 +                  pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
659 +                       if(adpt_install_hba(sht, pDev) ){
660 +                               PERROR("Could not Init an I2O RAID device\n");
661 +                               PERROR("Will not try to detect others.\n");
662 +                               return hba_count-1;
663 +                       }
664 +               }
665 +       }
666 +#endif
667 +
668 +       /* In INIT state, Activate IOPs */
669 +       for (pHba = hba_chain; pHba; pHba = pHba->next) {
670 +               // Activate does get status , init outbound, and get hrt
671 +               if (adpt_i2o_activate_hba(pHba) < 0) {
672 +                       adpt_i2o_delete_hba(pHba);
673 +               }
674 +       }
675 +
676 +
677 +       /* Active IOPs in HOLD state */
678 +
679 +rebuild_sys_tab:
680 +       if (hba_chain == NULL) 
681 +               return 0;
682 +
683 +       /*
684 +        * If build_sys_table fails, we kill everything and bail
685 +        * as we can't init the IOPs w/o a system table
686 +        */     
687 +       if (adpt_i2o_build_sys_table() < 0) {
688 +               adpt_i2o_sys_shutdown();
689 +               return 0;
690 +       }
691 +
692 +       PDEBUG("HBA's in HOLD state\n");
693 +
694 +       /* If IOP don't get online, we need to rebuild the System table */
695 +       for (pHba = hba_chain; pHba; pHba = pHba->next) {
696 +               if (adpt_i2o_online_hba(pHba) < 0) {
697 +                       adpt_i2o_delete_hba(pHba);      
698 +                       goto rebuild_sys_tab;
699 +               }
700 +       }
701 +
702 +       /* Active IOPs now in OPERATIONAL state */
703 +       PDEBUG("HBA's in OPERATIONAL state\n");
704 +
705 +       printk("dpti: If you have a lot of devices this could take a few minutes.\n");
706 +       for (pHba = hba_chain; pHba; pHba = pHba->next) {
707 +               printk("%s: Reading the hardware resource table.\n", pHba->name);
708 +               if (adpt_i2o_lct_get(pHba) < 0){
709 +                       adpt_i2o_delete_hba(pHba);
710 +                       continue;
711 +               }
712 +
713 +               if (adpt_i2o_parse_lct(pHba) < 0){
714 +                       adpt_i2o_delete_hba(pHba);
715 +                       continue;
716 +               }
717 +               adpt_inquiry(pHba);
718 +       }
719 +
720 +       for (pHba = hba_chain; pHba; pHba = pHba->next) {
721 +               if( adpt_scsi_register(pHba,sht) < 0){
722 +                       adpt_i2o_delete_hba(pHba);
723 +                       continue;
724 +               }
725 +               pHba->initialized = TRUE;
726 +               pHba->state &= ~DPTI_STATE_RESET;
727 +       }
728 +
729 +       // Register our control device node
730 +       // nodes will need to be created in /dev to access this
731 +       // the nodes can not be created from within the driver
732 +       if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
733 +               adpt_i2o_sys_shutdown();
734 +               return 0;
735 +       }
736 +       return hba_count;
737 +}
738 +
739 +
740 +int adpt_init(void)
741 +{
742 +       int i;
743 +
744 +       printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
745 +       for (i = 0; i < DPTI_MAX_HBA; i++) {
746 +               hbas[i] = NULL;
747 +       }
748 +#ifdef REBOOT_NOTIFIER
749 +       register_reboot_notifier(&adpt_reboot_notifier);
750 +#endif
751 +
752 +       return 0;
753 +}
754 +
755 +/* Structures and definitions for synchronous message posting.
756 + * See adpt_i2o_post_wait() for description
757 + * */
758 +struct adpt_i2o_post_wait_data
759 +{
760 +       int status;
761 +       u32 id;
762 +       adpt_wait_queue_head_t *wq;
763 +       struct adpt_i2o_post_wait_data *next;
764 +};
765 +
766 +static struct adpt_i2o_post_wait_data *adpt_post_wait_queue = NULL;
767 +static u32 adpt_post_wait_id = 0;
768 +static spinlock_t adpt_post_wait_lock = SPIN_LOCK_UNLOCKED;
769 +static void adpt_i2o_post_wait_complete(u32, int);
770 +
771 +int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
772 +{
773 +       ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
774 +       int status = 0;
775 +       ulong flags = 0;
776 +       struct adpt_i2o_post_wait_data *p1, *p2;
777 +       struct adpt_i2o_post_wait_data *wait_data =
778 +               kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
779 +       adpt_wait_queue_t wait;
780 +
781 +       if(!wait_data){
782 +               return -ENOMEM;
783 +       }
784 +       /*
785 +        * The spin locking is needed to keep anyone from playing
786 +        * with the queue pointers and id while we do the same
787 +        */
788 +       spin_lock_irqsave(&adpt_post_wait_lock, flags);
789 +       // TODO we need a MORE unique way of getting ids
790 +       // to support async LCT get
791 +       wait_data->next = adpt_post_wait_queue;
792 +       adpt_post_wait_queue = wait_data;
793 +       adpt_post_wait_id = (++adpt_post_wait_id & 0x7fff);
794 +       wait_data->id =  adpt_post_wait_id;
795 +       spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
796 +
797 +       wait_data->wq = &adpt_wq_i2o_post;
798 +       wait_data->status = -ETIMEDOUT;
799 +
800 +       // this code is taken from kernel/sched.c:interruptible_sleep_on_timeout
801 +       wait.task = current;
802 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
803 +       write_lock_irqsave(&waitqueue_lock,flags);
804 +       __add_wait_queue(&adpt_wq_i2o_post, &wait);
805 +       write_unlock(&waitqueue_lock);
806 +#else
807 +       init_waitqueue_entry(&wait, current);
808 +       wq_write_lock_irqsave(&adpt_wq_i2o_post.lock,flags);
809 +       __add_wait_queue(&adpt_wq_i2o_post, &wait);
810 +       wq_write_unlock(&adpt_wq_i2o_post.lock);
811 +#endif
812 +
813 +       msg[2] |= 0x80000000 | ((u32)wait_data->id);
814 +       timeout *= HZ;
815 +       if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
816 +               if(!timeout){
817 +                       current->state = TASK_INTERRUPTIBLE;
818 +                       spin_unlock_irq(&io_request_lock);
819 +                       schedule();
820 +                       spin_lock_irq(&io_request_lock);
821 +               } else {
822 +                       current->state = TASK_INTERRUPTIBLE;
823 +                       spin_unlock_irq(&io_request_lock);
824 +                       schedule_timeout(timeout*HZ);
825 +                       spin_lock_irq(&io_request_lock);
826 +               }
827 +       }
828 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
829 +       write_lock_irq(&waitqueue_lock);
830 +       __remove_wait_queue(&adpt_wq_i2o_post, &wait);
831 +       write_unlock_irqrestore(&waitqueue_lock,flags);
832 +#else
833 +       wq_write_lock_irq(&adpt_wq_i2o_post.lock);
834 +       __remove_wait_queue(&adpt_wq_i2o_post, &wait);
835 +       wq_write_unlock_irqrestore(&adpt_wq_i2o_post.lock,flags);
836 +#endif
837 +
838 +       if(status == -ETIMEDOUT)
839 +               printk("dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
840 +
841 +       /* Remove the entry from the queue.  */
842 +       p2 = NULL;
843 +       spin_lock_irqsave(&adpt_post_wait_lock, flags);
844 +       for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p1->next) {
845 +               if(p1 == wait_data) {
846 +                       if(p2)
847 +                               p2->next = p1->next;
848 +                       else
849 +                               adpt_post_wait_queue = p1->next;
850 +                       break;
851 +               }
852 +       }
853 +       spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
854 +       kfree(wait_data);
855 +       return status;
856 +}
857 +
858 +
859 +s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
860 +{
861 +
862 +       u32 m = EMPTY_QUEUE;
863 +       u32 *msg;
864 +       u32 timeout = jiffies + 30*HZ;
865 +       do {
866 +               rmb();
867 +               m = readl(pHba->post_port);
868 +               if (m != EMPTY_QUEUE) {
869 +                       break;
870 +               }
871 +               if(time_after(jiffies,timeout)){
872 +                       printk(KERN_ERR 
873 +                               "dpti%d: Timeout waiting for message frame!\n", 
874 +                                       pHba->unit);
875 +                       return -ETIMEDOUT;
876 +               }
877 +       } while(m == EMPTY_QUEUE);
878 +               
879 +       msg = (u32*) (pHba->msg_addr_virt + m);
880 +       memcpy_toio(msg, data, len);
881 +       wmb();
882 +
883 +       //post message
884 +       writel(m, pHba->post_port);
885 +       wmb();
886 +
887 +       return 0;
888 +}
889 +
890 +
891 +static void adpt_i2o_post_wait_complete(u32 context, int status)
892 +{
893 +       struct adpt_i2o_post_wait_data *p1 = NULL;
894 +       /*
895 +        * We need to search through the adpt_post_wait
896 +        * queue to see if the given message is still
897 +        * outstanding.  If not, it means that the IOP
898 +        * took longer to respond to the message than we
899 +        * had allowed and timer has already expired.
900 +        * Not much we can do about that except log
901 +        * it for debug purposes, increase timeout, and recompile
902 +        *
903 +        * Lock needed to keep anyone from moving queue pointers
904 +        * around while we're looking through them.
905 +        */
906 +
907 +       context &= 0x7fff;
908 +
909 +       spin_lock(&adpt_post_wait_lock);
910 +       for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
911 +               if(p1->id == context) {
912 +                       p1->status = status;
913 +                       spin_unlock(&adpt_post_wait_lock);
914 +                       wake_up_interruptible(p1->wq);
915 +                       return;
916 +               }
917 +       }
918 +       spin_unlock(&adpt_post_wait_lock);
919 +        // If this happens we loose commands that probably really completed
920 +       printk(KERN_ERR"dpti: Could Not find task %d in wait queue\n",context);
921 +       printk(KERN_ERR"      Tasks in wait queue:\n");
922 +       for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
923 +               printk(KERN_ERR"           %d\n",p1->id);
924 +       }
925 +       return;
926 +}
927 +
928 +/*
929 + *     Bring an I2O controller into HOLD state. See the spec.
930 + */
931 +int adpt_i2o_activate_hba(adpt_hba* pHba)
932 +{
933 +       int rcode;
934 +
935 +       if(pHba->initialized ) {
936 +               if (adpt_i2o_status_get(pHba) < 0) {
937 +                       if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
938 +                               printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
939 +                               return rcode;
940 +                       }
941 +                       if (adpt_i2o_status_get(pHba) < 0) {
942 +                               printk(KERN_INFO "HBA not responding.\n");
943 +                               return -1;
944 +                       }
945 +               }
946 +
947 +               if(pHba->status_block->iop_state == ADAPTER_STATE_FAULTED) {
948 +                       printk(KERN_CRIT "%s: hardware fault\n", pHba->name);
949 +                       return -1;
950 +               }
951 +
952 +               if (pHba->status_block->iop_state == ADAPTER_STATE_READY ||
953 +                   pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL ||
954 +                   pHba->status_block->iop_state == ADAPTER_STATE_HOLD ||
955 +                   pHba->status_block->iop_state == ADAPTER_STATE_FAILED) {
956 +                       adpt_i2o_reset_hba(pHba);                       
957 +                       if (adpt_i2o_status_get(pHba) < 0 || pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
958 +                               printk(KERN_CRIT "%s: Failed to initialize.\n", pHba->name);
959 +                               return -1;
960 +                       }
961 +               }
962 +       } else {
963 +               if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
964 +                       printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
965 +                       return rcode;
966 +               }
967 +
968 +       }
969 +
970 +       if (adpt_i2o_init_outbound_q(pHba) < 0) {
971 +               return -1;
972 +       }
973 +
974 +       /* In HOLD state */
975 +       
976 +       if (adpt_i2o_hrt_get(pHba) < 0) {
977 +               return -1;
978 +       }
979 +
980 +       return 0;
981 +}
982 +
983 +
984 +s32 adpt_i2o_reset_hba(adpt_hba* pHba)                 
985 +{
986 +       u32 msg[8];
987 +       u8* status;
988 +       u32 m = EMPTY_QUEUE ;
989 +       u32 timeout = jiffies + (TMOUT_IOPRESET*HZ);
990 +
991 +       if(pHba->initialized  == FALSE) {       // First time reset should be quick
992 +               timeout = jiffies + (25*HZ);
993 +       } else {
994 +               adpt_i2o_quiesce_hba(pHba);
995 +       }
996 +
997 +       do {
998 +               rmb();
999 +               m = readl(pHba->post_port);
1000 +               if (m != EMPTY_QUEUE) {
1001 +                       break;
1002 +               }
1003 +               if(time_after(jiffies,timeout)){
1004 +                       printk(KERN_ERR "Timeout waiting for message!\n");
1005 +                       return -ETIMEDOUT;
1006 +               }
1007 +       } while (m == EMPTY_QUEUE);
1008 +
1009 +       status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
1010 +       if(status == NULL) {
1011 +               adpt_send_nop(pHba, m);
1012 +               printk(KERN_ERR"IOP reset failed - no free memory.\n");
1013 +               return -ENOMEM;
1014 +       }
1015 +       memset(status,0,4);
1016 +
1017 +       msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
1018 +       msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
1019 +       msg[2]=0;
1020 +       msg[3]=0;
1021 +       msg[4]=0;
1022 +       msg[5]=0;
1023 +       msg[6]=virt_to_bus(status);
1024 +       msg[7]=0;     
1025 +
1026 +       memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
1027 +       wmb();
1028 +       writel(m, pHba->post_port);
1029 +       wmb();
1030 +
1031 +       while((volatile u8)*status == 0){
1032 +               if(time_after(jiffies,timeout)){
1033 +                       printk(KERN_ERR"%s: IOP Reset Timeout\n",pHba->name);
1034 +                       kfree(status);
1035 +                       return -ETIMEDOUT;
1036 +               }
1037 +               rmb();
1038 +       }
1039 +
1040 +       if((volatile u8)*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
1041 +               printk(KERN_INFO"%s: Reset in progress...\n", pHba->name);
1042 +               // Here we wait for message frame to become available
1043 +               // indicated that reset has finished
1044 +               do {
1045 +                       rmb();
1046 +                       m = readl(pHba->post_port);
1047 +                       if (m != EMPTY_QUEUE) {
1048 +                               break;
1049 +                       }
1050 +                       if(time_after(jiffies,timeout)){
1051 +                               printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
1052 +                               return -ETIMEDOUT;
1053 +                       }
1054 +               } while (m == EMPTY_QUEUE);
1055 +               // Flush the offset
1056 +               adpt_send_nop(pHba, m);
1057 +       }
1058 +       adpt_i2o_status_get(pHba);
1059 +       if(*status == 0x02 ||
1060 +                       pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
1061 +               printk(KERN_WARNING"%s: Reset reject, trying to clear\n",
1062 +                               pHba->name);
1063 +       } else {
1064 +               printk(KERN_INFO"%s: Reset completed.\n",
1065 +                               pHba->name);
1066 +       }
1067 +
1068 +       kfree(status);
1069 +#ifdef UARTDELAY
1070 +       adpt_delay(20000);
1071 +#endif
1072 +       return 0;
1073 +}
1074 +
1075 +s32 adpt_i2o_quiesce_hba(adpt_hba* pHba)
1076 +{
1077 +       u32 msg[4];
1078 +       int ret;
1079 +
1080 +       adpt_i2o_status_get(pHba);
1081 +
1082 +       /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
1083 +
1084 +       if((pHba->status_block->iop_state != ADAPTER_STATE_READY) &&
1085 +          (pHba->status_block->iop_state != ADAPTER_STATE_OPERATIONAL)){
1086 +               return 0;
1087 +       }
1088 +
1089 +       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
1090 +       msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
1091 +       msg[2] = 0;
1092 +       msg[3] = 0;
1093 +
1094 +       if((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
1095 +               printk("dpti%d: Unable to quiesce (status=%#x).\n",
1096 +                               pHba->unit, -ret);
1097 +       } else {
1098 +               printk("dpti%d: Quiesced.\n",pHba->unit);
1099 +       }
1100 +
1101 +       adpt_i2o_status_get(pHba);
1102 +       return ret;
1103 +}
1104 +
1105 +s32 adpt_i2o_status_get(adpt_hba* pHba)
1106 +{
1107 +       u32 timeout;
1108 +       u32 m;
1109 +       volatile u32 *msg;
1110 +       volatile u8 *status_block=NULL;
1111 +       caddr_t status_block_bus;
1112 +
1113 +       if(pHba->status_block == NULL) {
1114 +               pHba->status_block = (i2o_status_block*)
1115 +                       kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32);
1116 +               if(pHba->status_block == NULL) {
1117 +                       printk(KERN_ERR
1118 +                       "dpti%d: Get Status Block failed; Out of memory. \n", 
1119 +                       pHba->unit);
1120 +                       return -ENOMEM;
1121 +               }
1122 +       }
1123 +       memset(pHba->status_block, 0, sizeof(i2o_status_block));
1124 +       status_block = (u8*)(pHba->status_block);
1125 +       status_block_bus =(caddr_t) virt_to_bus(pHba->status_block);
1126 +       timeout = jiffies+TMOUT_GETSTATUS*HZ;
1127 +       do {
1128 +               rmb();
1129 +               m = readl(pHba->post_port);
1130 +               if (m != EMPTY_QUEUE) {
1131 +                       break;
1132 +               }
1133 +               if(time_after(jiffies,timeout)){
1134 +                       printk(KERN_ERR "%s: Timeout waiting for message !\n",
1135 +                                       pHba->name);
1136 +                       return -ETIMEDOUT;
1137 +               }
1138 +       } while(m==EMPTY_QUEUE);
1139 +
1140 +       
1141 +       msg=(u32*)(pHba->msg_addr_virt+m);
1142 +
1143 +       writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
1144 +       writel(I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID, &msg[1]);
1145 +       writel(1, &msg[2]);
1146 +       writel(0, &msg[3]);
1147 +       writel(0, &msg[4]);
1148 +       writel(0, &msg[5]);
1149 +       writel(((u32)status_block_bus)&0xffffffff, &msg[6]);
1150 +       writel(0, &msg[7]);
1151 +       writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes
1152 +
1153 +       //post message
1154 +       writel(m, pHba->post_port);
1155 +       wmb();
1156 +
1157 +       while(status_block[87]!=0xff){
1158 +               if(time_after(jiffies,timeout)){
1159 +                       printk(KERN_ERR"dpti%d: Get status timeout.\n",
1160 +                               pHba->unit);
1161 +                       return -ETIMEDOUT;
1162 +               }
1163 +               rmb();
1164 +       }
1165 +
1166 +       // Set up our number of outbound and inbound messages
1167 +       pHba->post_fifo_size = pHba->status_block->max_inbound_frames;
1168 +       if (pHba->post_fifo_size > MAX_TO_IOP_MESSAGES) {
1169 +               pHba->post_fifo_size = MAX_TO_IOP_MESSAGES;
1170 +       }
1171 +
1172 +       pHba->reply_fifo_size = pHba->status_block->max_outbound_frames;
1173 +       if (pHba->reply_fifo_size > MAX_FROM_IOP_MESSAGES) {
1174 +               pHba->reply_fifo_size = MAX_FROM_IOP_MESSAGES;
1175 +       }
1176 +
1177 +       // Calculate the Scatter Gather list size
1178 +       pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element);
1179 +       if (pHba->sg_tablesize > SG_LIST_ELEMENTS) {
1180 +               pHba->sg_tablesize = SG_LIST_ELEMENTS;
1181 +       }
1182 +
1183 +
1184 +#ifdef DEBUG
1185 +       printk("dpti%d: State = ",pHba->unit);
1186 +       switch(pHba->status_block->iop_state) {
1187 +               case 0x01:
1188 +                       printk("INIT\n");
1189 +                       break;
1190 +               case 0x02:
1191 +                       printk("RESET\n");
1192 +                       break;
1193 +               case 0x04:
1194 +                       printk("HOLD\n");
1195 +                       break;
1196 +               case 0x05:
1197 +                       printk("READY\n");
1198 +                       break;
1199 +               case 0x08:
1200 +                       printk("OPERATIONAL\n");
1201 +                       break;
1202 +               case 0x10:
1203 +                       printk("FAILED\n");
1204 +                       break;
1205 +               case 0x11:
1206 +                       printk("FAULTED\n");
1207 +                       break;
1208 +               default:
1209 +                       printk("%x (unknown!!)\n",pHba->status_block->iop_state);
1210 +       }
1211 +#endif
1212 +       return 0;
1213 +}
1214 +
1215 +
1216 +s32 adpt_i2o_hrt_get(adpt_hba* pHba)
1217 +{
1218 +       u32 msg[6];
1219 +       int ret, size = sizeof(i2o_hrt);
1220 +
1221 +       do {
1222 +               if (pHba->hrt == NULL) {
1223 +                       pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32);
1224 +                       if (pHba->hrt == NULL) {
1225 +                               printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name);
1226 +                               return -ENOMEM;
1227 +                       }
1228 +               }
1229 +
1230 +               msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
1231 +               msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
1232 +               msg[2]= 0;
1233 +               msg[3]= 0;
1234 +               msg[4]= (0xD0000000 | size);    /* Simple transaction */
1235 +               msg[5]= virt_to_bus(pHba->hrt);   /* Dump it here */
1236 +
1237 +               if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) {
1238 +                       printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret);
1239 +                       return ret;
1240 +               }
1241 +
1242 +               if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
1243 +                       size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
1244 +                       kfree(pHba->hrt);
1245 +                       pHba->hrt = NULL;
1246 +               }
1247 +       } while(pHba->hrt == NULL);
1248 +       return 0;
1249 +}                                                                                                                                       
1250 +
1251 +/*
1252 + *      Query one scalar group value or a whole scalar group.
1253 + */                    
1254 +int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
1255 +                       int group, int field, void *buf, int buflen)
1256 +{
1257 +       u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
1258 +       u8  resblk[8+buflen]; /* 8 bytes for header */
1259 +       int size;
1260 +
1261 +       if (field == -1)                /* whole group */
1262 +                       opblk[4] = -1;
1263 +
1264 +       size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, 
1265 +               opblk, sizeof(opblk), resblk, sizeof(resblk));
1266 +                       
1267 +       if (size < 0)
1268 +               return size;    
1269 +
1270 +       memcpy(buf, resblk+8, buflen);  /* cut off header */
1271 +       return buflen;
1272 +}
1273 +
1274 +
1275 +/*     Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
1276 + *
1277 + *     This function can be used for all UtilParamsGet/Set operations.
1278 + *     The OperationBlock is given in opblk-buffer, 
1279 + *     and results are returned in resblk-buffer.
1280 + *     Note that the minimum sized resblk is 8 bytes and contains
1281 + *     ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
1282 + */
1283 +int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
1284 +                 void *opblk, int oplen, void *resblk, int reslen)
1285 +{
1286 +       u32 msg[9]; 
1287 +       u32 *res = (u32 *)resblk;
1288 +       int wait_status;
1289 +
1290 +       msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
1291 +       msg[1] = cmd << 24 | HOST_TID << 12 | tid; 
1292 +       msg[2] = 0;
1293 +       msg[3] = 0;
1294 +       msg[4] = 0;
1295 +       msg[5] = 0x54000000 | oplen;    /* OperationBlock */
1296 +       msg[6] = virt_to_bus(opblk);
1297 +       msg[7] = 0xD0000000 | reslen;   /* ResultBlock */
1298 +       msg[8] = virt_to_bus(resblk);
1299 +
1300 +       if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
1301 +               return wait_status;     /* -DetailedStatus */
1302 +       }
1303 +
1304 +       if (res[1]&0x00FF0000) {        /* BlockStatus != SUCCESS */
1305 +               printk(KERN_WARNING "%s: %s - Error:\n  ErrorInfoSize = 0x%02x, "
1306 +                       "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
1307 +                       pHba->name,
1308 +                       (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
1309 +                                                        : "PARAMS_GET",   
1310 +                       res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF);
1311 +               return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
1312 +       }
1313 +
1314 +        return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */ 
1315 +}
1316 +
1317 +/*
1318 + * Get the IOP's Logical Configuration Table
1319 + */
1320 +int adpt_i2o_lct_get(adpt_hba* pHba)
1321 +{
1322 +       u32 msg[8];
1323 +       int ret;
1324 +       u32 buf[16];
1325 +
1326 +       if ((pHba->lct_size == 0) || (pHba->lct == NULL)){
1327 +               pHba->lct_size = pHba->status_block->expected_lct_size;
1328 +       }
1329 +       do {
1330 +               if (pHba->lct == NULL) {
1331 +                       pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32);
1332 +                       if(pHba->lct == NULL) {
1333 +                               printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
1334 +                                       pHba->name);
1335 +                               return -ENOMEM;
1336 +                       }
1337 +               }
1338 +               memset(pHba->lct, 0, pHba->lct_size);
1339 +
1340 +               msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
1341 +               msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
1342 +               msg[2] = 0;
1343 +               msg[3] = 0;
1344 +               msg[4] = 0xFFFFFFFF;    /* All devices */
1345 +               msg[5] = 0x00000000;    /* Report now */
1346 +               msg[6] = 0xD0000000|pHba->lct_size;
1347 +               msg[7] = virt_to_bus(pHba->lct);
1348 +
1349 +               if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
1350 +                       printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n", 
1351 +                               pHba->name, ret);       
1352 +                       printk("Adaptec: Error Reading Hardware.\n");
1353 +                       return ret;
1354 +               }
1355 +
1356 +               if ((pHba->lct->table_size << 2) > pHba->lct_size) {
1357 +                       pHba->lct_size = pHba->lct->table_size << 2;
1358 +                       kfree(pHba->lct);
1359 +                       pHba->lct = NULL;
1360 +               }
1361 +       } while (pHba->lct == NULL);
1362 +
1363 +       PDEBUG("%s: Hardware resource table read.\n", pHba->name);
1364 +
1365 +
1366 +       // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO;
1367 +       if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) {
1368 +               pHba->FwDebugBufferSize = buf[1];
1369 +               pHba->FwDebugBuffer_P = pHba->base_addr_virt + buf[0];
1370 +               pHba->FwDebugFlags_P = (u32*) (pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET);
1371 +               pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET;
1372 +               pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1;
1373 +               pHba->FwDebugStrLength_P = (u32*) (pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET);
1374 +               pHba->FwDebugBuffer_P += buf[2]; 
1375 +               pHba->FwDebugFlags = 0;
1376 +       }
1377 +
1378 +       return 0;
1379 +}
1380 +
1381 +/*
1382 + *     The logical configuration table tells us what we can talk to
1383 + *     on the board. Most of the stuff isn't interesting to us. 
1384 + */
1385 +
1386 +int adpt_i2o_parse_lct(adpt_hba* pHba)
1387 +{
1388 +       int i;
1389 +       int max;
1390 +       int tid;
1391 +       struct i2o_device *d;
1392 +       i2o_lct *lct = pHba->lct;
1393 +       u8 bus_no = 0;
1394 +       s16 scsi_id;
1395 +       s16 scsi_lun;
1396 +       u32 buf[10]; // larger than 7, or 8 ...
1397 +       struct adpt_device* pDev; 
1398 +       
1399 +       if (lct == NULL) {
1400 +               printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
1401 +               return -1;
1402 +       }
1403 +       
1404 +       max = lct->table_size;  
1405 +       max -= 3;
1406 +       max /= 9;
1407 +
1408 +       if(lct->iop_flags&(1<<0))
1409 +               printk(KERN_WARNING "%s: Configuration dialog desired.\n", pHba->name);
1410 +               
1411 +       for(i=0;i<max;i++) {
1412 +               if( lct->lct_entry[i].user_tid != 0xfff){
1413 +                       /*
1414 +                        * If we have hidden devices, we need to inform the upper layers about
1415 +                        * the possible maximum id reference to handle device access when
1416 +                        * an array is disassembled. This code has no other purpose but to
1417 +                        * allow us future access to devices that are currently hidden
1418 +                        * behind arrays, hotspares or have not been configured (JBOD mode).
1419 +                        */
1420 +                       if( lct->lct_entry[i].class_id != I2O_CLASS_RANDOM_BLOCK_STORAGE &&
1421 +                           lct->lct_entry[i].class_id != I2O_CLASS_SCSI_PERIPHERAL &&
1422 +                           lct->lct_entry[i].class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
1423 +                               continue;
1424 +                       }
1425 +                       tid = lct->lct_entry[i].tid;
1426 +                       // I2O_DPT_DEVICE_INFO_GROUP_NO;
1427 +                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
1428 +                               continue;
1429 +                       }
1430 +                       bus_no = buf[0]>>16;
1431 +                       scsi_id = buf[1];
1432 +                       scsi_lun = (buf[2]>>8 )&0xff;
1433 +                       if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
1434 +                               printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
1435 +                               continue;
1436 +                       }
1437 +                       if(scsi_id > MAX_ID){
1438 +                               printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
1439 +                               continue;
1440 +                       }
1441 +                       if(bus_no > pHba->top_scsi_channel){
1442 +                               pHba->top_scsi_channel = bus_no;
1443 +                       }
1444 +                       if(scsi_id > pHba->top_scsi_id){
1445 +                               pHba->top_scsi_id = scsi_id;
1446 +                       }
1447 +                       if(scsi_lun > pHba->top_scsi_lun){
1448 +                               pHba->top_scsi_lun = scsi_lun;
1449 +                       }
1450 +                       continue;
1451 +               }
1452 +               d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
1453 +               if(d==NULL)
1454 +               {
1455 +                       printk(KERN_CRIT "%s: Out of memory for I2O device data.\n",pHba->name);
1456 +                       return -ENOMEM;
1457 +               }
1458 +               
1459 +               d->controller = (void*)pHba;
1460 +               d->next = NULL;
1461 +
1462 +               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
1463 +
1464 +               d->flags = 0;
1465 +               tid = d->lct_data.tid;
1466 +               adpt_i2o_report_hba_unit(pHba, d);
1467 +               adpt_i2o_install_device(pHba, d);
1468 +       }
1469 +       bus_no = 0;
1470 +       for(d = pHba->devices; d ; d = d->next) {
1471 +               if(d->lct_data.class_id  == I2O_CLASS_BUS_ADAPTER_PORT ||
1472 +                  d->lct_data.class_id  == I2O_CLASS_FIBRE_CHANNEL_PORT){
1473 +                       tid = d->lct_data.tid;
1474 +                       // TODO get the bus_no from hrt
1475 +                       //bus_no = 
1476 +                       if(bus_no > pHba->top_scsi_channel){
1477 +                               pHba->top_scsi_channel = bus_no;
1478 +                       }
1479 +                       pHba->channel[bus_no].type = d->lct_data.class_id;
1480 +                       pHba->channel[bus_no].tid = tid;
1481 +                       if(adpt_i2o_query_scalar(pHba, tid, 0x0200, -1, buf, 28)>=0)
1482 +                       {
1483 +                               pHba->channel[bus_no].scsi_id = buf[1];
1484 +                               printk(KERN_INFO "Bus %d - SCSI ID %d.\n", bus_no, buf[1]);
1485 +                       }
1486 +                       // TODO remove - this is just until we get from hrt
1487 +                       bus_no++;
1488 +                       if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
1489 +                               printk(KERN_WARNING"%s: Channel number %d out of range - LCT\n", pHba->name, bus_no);
1490 +                               break;
1491 +                       }
1492 +               }
1493 +       }
1494 +
1495 +       // Setup adpt_device table
1496 +       for(d = pHba->devices; d ; d = d->next) {
1497 +               if(d->lct_data.class_id  == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
1498 +                  d->lct_data.class_id  == I2O_CLASS_SCSI_PERIPHERAL ||
1499 +                  d->lct_data.class_id  == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
1500 +
1501 +                       tid = d->lct_data.tid;
1502 +                       scsi_id = -1;
1503 +                       // I2O_DPT_DEVICE_INFO_GROUP_NO;
1504 +                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)>=0) {
1505 +                               bus_no = buf[0]>>16;
1506 +                               scsi_id = buf[1];
1507 +                               scsi_lun = (buf[2]>>8 )&0xff;
1508 +                               if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
1509 +                                       continue;
1510 +                               }
1511 +                               if(scsi_id > MAX_ID){
1512 +                                       continue;
1513 +                               }
1514 +                               if( pHba->channel[bus_no].device[scsi_id] == NULL){
1515 +                                       pDev =  kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
1516 +                                       if(pDev == NULL) {
1517 +                                               return -ENOMEM;
1518 +                                       }
1519 +                                       pHba->channel[bus_no].device[scsi_id] = pDev;
1520 +                                       memset(pDev,0,sizeof(struct adpt_device));
1521 +                               } else {
1522 +                                       for( pDev = pHba->channel[bus_no].device[scsi_id];      
1523 +                                                       pDev->next_lun; pDev = pDev->next_lun){
1524 +                                       }
1525 +                                       pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
1526 +                                       if(pDev == NULL) {
1527 +                                               return -ENOMEM;
1528 +                                       }
1529 +                                       memset(pDev->next_lun,0,sizeof(struct adpt_device));
1530 +                                       pDev = pDev->next_lun;
1531 +                               }
1532 +                               pDev->tid = tid;
1533 +                               pDev->scsi_channel = bus_no;
1534 +                               pDev->scsi_id = scsi_id;
1535 +                               pDev->scsi_lun = scsi_lun;
1536 +                               pDev->pI2o_dev = d;
1537 +                               d->owner = (struct i2o_handler *)pDev;
1538 +                               pDev->type = (buf[0])&0xff;
1539 +                               pDev->flags = (buf[0]>>8)&0xff;
1540 +                               if(scsi_id > pHba->top_scsi_id){
1541 +                                       pHba->top_scsi_id = scsi_id;
1542 +                               }
1543 +                               if(scsi_lun > pHba->top_scsi_lun){
1544 +                                       pHba->top_scsi_lun = scsi_lun;
1545 +                               }
1546 +                       }
1547 +                       if(scsi_id == -1){
1548 +                               printk(KERN_WARNING"Could not find SCSI ID for %s\n",
1549 +                                               d->lct_data.identity_tag);
1550 +                       }
1551 +               }
1552 +       }
1553 +       return 0;
1554 +}
1555 +
1556 +
1557 +/*
1558 + *     Each I2O controller has a chain of devices on it - these match
1559 + *     the useful parts of the LCT of the board.
1560 + */
1561
1562 +int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
1563 +{
1564 +       down(&adpt_configuration_lock);
1565 +       d->controller=(struct i2o_controller*)pHba;
1566 +       d->owner=NULL;
1567 +       d->next=pHba->devices;
1568 +       d->prev=NULL;
1569 +       if (pHba->devices != NULL){
1570 +               pHba->devices->prev=d;
1571 +       }
1572 +       pHba->devices=d;
1573 +       *d->dev_name = 0;
1574 +
1575 +       up(&adpt_configuration_lock);
1576 +       return 0;
1577 +}
1578 +
1579 +
1580 +/*
1581 + *      Dump the information block associated with a given unit (TID)
1582 + */
1583
1584 +void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d)
1585 +{
1586 +       char buf[64];
1587 +       int unit = d->lct_data.tid;
1588 +
1589 +       printk(KERN_INFO "Target ID %d.\n", unit);
1590 +
1591 +       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 3, buf, 16)>=0)
1592 +       {
1593 +               buf[16]=0;
1594 +               printk(KERN_INFO"  Vendor: %s", buf);
1595 +       }
1596 +       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 4, buf, 16)>=0)
1597 +       {
1598 +               buf[16]=0;
1599 +               printk("     Device: %s", buf);
1600 +       }
1601 +#if 0
1602 +       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 5, buf, 16)>=0)
1603 +       {
1604 +               buf[16]=0;
1605 +               printk(KERN_INFO "Description: %s", buf);
1606 +       }
1607 +#endif 
1608 +       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 6, buf, 8)>=0)
1609 +       {
1610 +               buf[8]=0;
1611 +               printk("  Rev: %s\n", buf);
1612 +       }
1613 +
1614 +        printk(KERN_INFO "  Class: %.21s\n", adpt_i2o_get_class_name(d->lct_data.class_id));
1615 +        printk(KERN_INFO "  Subclass: 0x%04X\n", d->lct_data.sub_class);
1616 +        printk(KERN_INFO "  Flags: ");
1617 +
1618 +        if(d->lct_data.device_flags&(1<<0))
1619 +                 printk("C");       // ConfigDialog requested
1620 +        if(d->lct_data.device_flags&(1<<1))
1621 +                 printk("U");       // Multi-user capable
1622 +        if(!(d->lct_data.device_flags&(1<<4)))
1623 +                 printk("P");       // Peer service enabled!
1624 +        if(!(d->lct_data.device_flags&(1<<5)))
1625 +                 printk("M");       // Mgmt service enabled!
1626 +        printk("\n");
1627 +}
1628 +
1629 +
1630 +/*
1631 + *     Do i2o class name lookup
1632 + */
1633 +const char *adpt_i2o_get_class_name(int class)
1634 +{
1635 +       int idx = 16;
1636 +       static char *i2o_class_name[] = {
1637 +               "Executive",
1638 +               "Device Driver Module",
1639 +               "Block Device",
1640 +               "Tape Device",
1641 +               "LAN Interface",
1642 +               "WAN Interface",
1643 +               "Fibre Channel Port",
1644 +               "Fibre Channel Device",
1645 +               "SCSI Device",
1646 +               "ATE Port",
1647 +               "ATE Device",
1648 +               "Floppy Controller",
1649 +               "Floppy Device",
1650 +               "Secondary Bus Port",
1651 +               "Peer Transport Agent",
1652 +               "Peer Transport",
1653 +               "Unknown"
1654 +       };
1655 +       
1656 +       switch(class&0xFFF) {
1657 +       case I2O_CLASS_EXECUTIVE:
1658 +               idx = 0; break;
1659 +       case I2O_CLASS_DDM:
1660 +               idx = 1; break;
1661 +       case I2O_CLASS_RANDOM_BLOCK_STORAGE:
1662 +               idx = 2; break;
1663 +       case I2O_CLASS_SEQUENTIAL_STORAGE:
1664 +               idx = 3; break;
1665 +       case I2O_CLASS_LAN:
1666 +               idx = 4; break;
1667 +       case I2O_CLASS_WAN:
1668 +               idx = 5; break;
1669 +       case I2O_CLASS_FIBRE_CHANNEL_PORT:
1670 +               idx = 6; break;
1671 +       case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
1672 +               idx = 7; break;
1673 +       case I2O_CLASS_SCSI_PERIPHERAL:
1674 +               idx = 8; break;
1675 +       case I2O_CLASS_ATE_PORT:
1676 +               idx = 9; break;
1677 +       case I2O_CLASS_ATE_PERIPHERAL:
1678 +               idx = 10; break;
1679 +       case I2O_CLASS_FLOPPY_CONTROLLER:
1680 +               idx = 11; break;
1681 +       case I2O_CLASS_FLOPPY_DEVICE:
1682 +               idx = 12; break;
1683 +       case I2O_CLASS_BUS_ADAPTER_PORT:
1684 +               idx = 13; break;
1685 +       case I2O_CLASS_PEER_TRANSPORT_AGENT:
1686 +               idx = 14; break;
1687 +       case I2O_CLASS_PEER_TRANSPORT:
1688 +               idx = 15; break;
1689 +       }
1690 +       return i2o_class_name[idx];
1691 +}
1692 +
1693 +
1694 +int adpt_open(struct inode *inode, struct file *file)
1695 +{
1696 +       int minor;
1697 +       adpt_hba* pHba;
1698 +
1699 +       //TODO check for root access
1700 +       //
1701 +       minor = MINOR(inode->i_rdev);
1702 +       if (minor >= hba_count) {
1703 +               return -ENXIO;
1704 +       }
1705 +       down(&adpt_configuration_lock);
1706 +       for (pHba = hba_chain; pHba; pHba = pHba->next) {
1707 +               if (pHba->unit == minor) {
1708 +                       break;  /* found adapter */
1709 +               }
1710 +       }
1711 +       if (pHba == NULL) {
1712 +               up(&adpt_configuration_lock);
1713 +               return -ENXIO;
1714 +       }
1715 +
1716 +//     if(pHba->in_use){
1717 +       //      up(&adpt_configuration_lock);
1718 +//             return -EBUSY;
1719 +//     }
1720 +
1721 +       pHba->in_use = 1;
1722 +       up(&adpt_configuration_lock);
1723 +
1724 +       return 0;
1725 +}
1726 +
1727 +int adpt_close(struct inode *inode, struct file *file)
1728 +{
1729 +       int minor;
1730 +       adpt_hba* pHba;
1731 +
1732 +       minor = MINOR(inode->i_rdev);
1733 +       if (minor >= hba_count) {
1734 +               return -ENXIO;
1735 +       }
1736 +       down(&adpt_configuration_lock);
1737 +       for (pHba = hba_chain; pHba; pHba = pHba->next) {
1738 +               if (pHba->unit == minor) {
1739 +                       break;  /* found adapter */
1740 +               }
1741 +       }
1742 +       up(&adpt_configuration_lock);
1743 +       if (pHba == NULL) {
1744 +               return -ENXIO;
1745 +       }
1746 +
1747 +       pHba->in_use = 0;
1748 +
1749 +       return 0;
1750 +}
1751 +
1752 +
1753 +int adpt_i2o_passthru(adpt_hba* pHba, u32* arg)
1754 +{
1755 +       u32 msg[MAX_MESSAGE_SIZE/4];
1756 +       u32* reply = NULL;
1757 +       u32 size = 0;
1758 +       u32 reply_size = 0;
1759 +       u32* user_msg = (u32*)arg;
1760 +       u32* user_reply = NULL;
1761 +       u32 sg_offset = 0;
1762 +       u32 sg_count = 0;
1763 +       u32 i = 0;
1764 +       u32 rcode = 0;
1765 +       caddr_t p = NULL;
1766 +       caddr_t sg_list[pHba->sg_tablesize];
1767 +       int sg_index = 0;
1768 +       ulong flags = 0;
1769 +       memset(&msg, 0, MAX_MESSAGE_SIZE);
1770 +       // get user msg size in u32s 
1771 +       get_user(size, &user_msg[0]);
1772 +       size = size>>16;
1773 +
1774 +       user_reply = &user_msg[size];
1775 +       size *= 4; // Convert to bytes
1776 +       if(size > MAX_MESSAGE_SIZE){
1777 +               return -EFAULT;
1778 +       }
1779 +
1780 +       /* Copy in the user's I2O command */
1781 +       if (copy_from_user ((void*)msg, (void*)user_msg, size)) {
1782 +               return -EFAULT;
1783 +       }
1784 +       get_user(reply_size, &user_reply[0]);
1785 +       reply_size = reply_size>>16;
1786 +       if(reply_size > REPLY_FRAME_SIZE){
1787 +               reply_size = REPLY_FRAME_SIZE;
1788 +       }
1789 +       reply_size *= 4;
1790 +       reply = kmalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
1791 +       if(reply == NULL) {
1792 +               printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
1793 +               return -ENOMEM;
1794 +       }
1795 +       memset(reply,0,REPLY_FRAME_SIZE*4);
1796 +       sg_offset = (msg[0]>>4)&0xf;
1797 +       msg[2] = 0x40000000; // IOCTL context
1798 +       msg[3] = (u32)reply;
1799 +       memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize);
1800 +       if(sg_offset) {
1801 +               struct sg_simple_element *sg =  (struct sg_simple_element*) (msg+sg_offset);
1802 +               sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
1803 +               if (sg_count > pHba->sg_tablesize){
1804 +                       printk(KERN_WARNING"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
1805 +                       kfree (reply);
1806 +                       return -EINVAL;
1807 +               }
1808 +
1809 +               for (i = 0; i < sg_count; i++) {
1810 +#if 0
1811 +                       u32 physical;
1812 +                       caddr_t virtual;
1813 +                       int residual, length, sub_length;
1814 +#endif
1815 +                       int sg_size;
1816 +
1817 +                       if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {
1818 +                               printk(KERN_WARNING"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i,  sg[i].flag_count);
1819 +                               rcode = -EINVAL;
1820 +                               goto cleanup;
1821 +                       }
1822 +                       sg_size = sg[i].flag_count & 0xffffff;      
1823 +                       /* Allocate memory for the transfer */
1824 +                       p = (caddr_t)kmalloc(sg_size, GFP_KERNEL|ADDR32);
1825 +                       if (p == NULL) {
1826 +                               printk(KERN_WARNING"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
1827 +                                               pHba->name,sg_size,i,sg_count);
1828 +                               rcode = -ENOMEM;
1829 +                               goto cleanup;
1830 +                       }
1831 +                       sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
1832 +                       /* Copy in the user's SG buffer if necessary */
1833 +                       if (sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
1834 +                               if (copy_from_user(p,(caddr_t)(sg[i].addr_bus), sg_size)) {
1835 +                                       printk(KERN_WARNING"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
1836 +                                       rcode = -EFAULT;
1837 +                                       goto cleanup;
1838 +                               }
1839 +                       }
1840 +                       sg[i].addr_bus = (u32)virt_to_bus(p);
1841 +#if 0
1842 +                       // Need to split requests should the buffer not be physically contiguous
1843 +                       // It gets ugly from here on in ...
1844 +                       physical = sg[i].addr_bus;
1845 +                       virtual = p;
1846 +                       residual = sg[i].flag_count&0xffffff;
1847 +                       length = 0;
1848 +                       while ((sub_length = (((physical + PAGE_SIZE) & PAGE_MASK) - physical)) < residual) {
1849 +                               // split this request?
1850 +                               length += sub_length;
1851 +                               residual -= sub_length;
1852 +                               physical += sub_length;
1853 +                               virtual += sub_length;
1854 +                               if (physical != (u32)virt_to_bus(virtual)) {
1855 +                                       int j;
1856 +                                       if (++sg_count > pHba->sg_tablesize){
1857 +                                               printk(KERN_WARNING"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
1858 +                                               rcode = -EINVAL;
1859 +                                               goto cleanup;
1860 +                                       }
1861 +                                       if((size += sizeof(struct sg_simple_element)) > MAX_MESSAGE_SIZE){
1862 +                                               printk(KERN_WARNING"%s:IOCTL Message too large (%u)\n", pHba->name,size);
1863 +                                               rcode = -EINVAL;
1864 +                                               goto cleanup;
1865 +                                       }
1866 +                                       // fixup message and scatter gather list.
1867 +                                       msg[0] &= 0xffff;
1868 +                                       msg[0] |= (size / sizeof(u32)) << 16;
1869 +                                       // shift upwards the scatter gather list.
1870 +                                       sg[i].flag_count &= ~0xffffff;
1871 +                                       for (j = sg_count; --j > i;) {
1872 +                                               sg[j] = sg[j-1];
1873 +                                       }
1874 +                                       // length &= 0xffffff;
1875 +                                       sg[i].flag_count |= length;
1876 +                                       length = 0;
1877 +                                       sg[++i].addr_bus = physical = (u32)virt_to_bus(virtual);
1878 +                                       // residual &= 0xffffff;
1879 +                                       sg[i].flag_count |= residual;
1880 +                               }
1881 +                       }
1882 +#endif
1883 +               }
1884 +       }
1885 +
1886 +       do {
1887 +               spin_lock_irqsave(&io_request_lock, flags);
1888 +               // This state stops any new commands from enterring the
1889 +               // controller while processing the ioctl
1890 +//             pHba->state |= DPTI_STATE_IOCTL;
1891 +//             We can't set this now - The scsi subsystem sets host_blocked and
1892 +//             the queue empties and stops.  We need a way to restart the queue
1893 +               rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
1894 +//             pHba->state &= ~DPTI_STATE_IOCTL;
1895 +               spin_unlock_irqrestore(&io_request_lock, flags);
1896 +       } while(rcode == -ETIMEDOUT);  
1897 +
1898 +       if(!rcode && sg_offset) {
1899 +       /* Copy back the Scatter Gather buffers back to user space */
1900 +               u32 j;
1901 +               struct sg_simple_element* sg;
1902 +               int sg_size;
1903 +
1904 +               // re-acquire the original message to handle correctly the sg copy operation
1905 +               memset(&msg, 0, MAX_MESSAGE_SIZE);
1906 +               // get user msg size in u32s 
1907 +               if(get_user(size, &user_msg[0])){
1908 +                       rcode = -EFAULT; 
1909 +                       goto cleanup; 
1910 +               }
1911 +               size = size>>16;
1912 +               size *= 4;
1913 +               /* Copy in the user's I2O command */
1914 +               if (copy_from_user ((void*)msg, (void*)user_msg, size)) {
1915 +                       rcode = -EFAULT;
1916 +                       goto cleanup;
1917 +               }
1918 +               sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
1919 +
1920 +               sg       = (struct sg_simple_element*)(msg + sg_offset);
1921 +               for (j = 0; j < sg_count; j++) {
1922 +                       /* Copy out the SG list to user's buffer if necessary */
1923 +                       if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
1924 +                               sg_size = sg[j].flag_count & 0xffffff; 
1925 +                               if (copy_to_user((caddr_t)(sg[j].addr_bus),sg_list[j], sg_size)) {
1926 +                                       printk(KERN_WARNING"%s: Could not copy %p TO user %p\n",pHba->name, sg_list[j], (caddr_t)sg[j].addr_bus);
1927 +                                       rcode = -EFAULT;
1928 +                                       goto cleanup;
1929 +                               }
1930 +                       }
1931 +               }
1932 +       } 
1933 +
1934 +       /* Copy back the reply to user space */
1935 +       if (reply_size) {
1936 +               // we wrote our own values for context - now restore the user supplied ones
1937 +               if (copy_from_user (reply+2, user_msg+2, sizeof(u32)*2)) {
1938 +                       printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);
1939 +                       rcode = -EFAULT;
1940 +               }
1941 +               if (copy_to_user(user_reply, reply, reply_size)) {
1942 +                       printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
1943 +                       rcode = -EFAULT;
1944 +               }
1945 +       }
1946 +
1947 +
1948 +cleanup:
1949 +       kfree (reply);
1950 +       while(sg_index) {
1951 +               if(sg_list[--sg_index]) {
1952 +                       kfree(sg_list[sg_index]);
1953 +               }
1954 +       }
1955 +       return rcode;
1956 +}
1957 +
1958 +
1959 +/*
1960 + * This routine returns information about the system.  This does not effect
1961 + * any logic and if the info is wrong - it doesn't matter.
1962 + */
1963 +
1964 +/* Get all the info we can not get from kernel services */
1965 +int adpt_system_info(void *buffer)
1966 +{
1967 +       sysInfo_S si;
1968 +
1969 +       memset(&si, 0, sizeof(si));
1970 +
1971 +       si.osType = OS_LINUX;
1972 +       si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16);
1973 +       si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff);
1974 +       si.osRevision =     (u8) (LINUX_VERSION_CODE & 0x0ff);
1975 +       si.busType = SI_PCI_BUS;
1976 +       si.processorFamily = DPTI_sig.dsProcessorFamily;
1977 +
1978 +#if defined __i386__ 
1979 +       adpt_i386_info(&si);
1980 +#elif defined __ia64__
1981 +       adpt_ia64_info(&si);
1982 +#elif define __sparc__
1983 +       adpt_sparc_info(&si);
1984 +#elif defined __alpha__ 
1985 +       adpt_alpha_info(&si);
1986 +#else
1987 +       si.processorType = 0xff ;
1988 +#endif
1989 +       if(copy_to_user(buffer, &si, sizeof(si))){
1990 +               printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
1991 +               return -EFAULT;
1992 +       }
1993 +
1994 +       return 0;
1995 +}
1996 +
1997 +#if defined __ia64__ 
1998 +void adpt_ia64_info(sysInfo_S* si)
1999 +{
2000 +       // This is all the info we need for now
2001 +       si->processorType = PROC_IA64;
2002 +}
2003 +#endif
2004 +
2005 +
2006 +#if defined __sparc__ 
2007 +void adpt_sparc_info(sysInfo_S* si)
2008 +{
2009 +       // This is all the info we need for now
2010 +       si->processorType = PROC_ULTRASPARC;
2011 +}
2012 +#endif
2013 +
2014 +#if defined __alpha__ 
2015 +void adpt_sparc_info(sysInfo_S* si)
2016 +{
2017 +       // This is all the info we need for now
2018 +       si->processorType = PROC_ALPHA;
2019 +}
2020 +#endif
2021 +
2022 +#if defined __i386__
2023 +
2024 +#include <linux/mc146818rtc.h>
2025 +
2026 +
2027 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2028 +
2029 +void adpt_i386_info(sysInfo_S* si)
2030 +{
2031 +       int i;
2032 +       int j;
2033 +       ulong flags=0;
2034 +
2035 +       switch (boot_cpu_data.x86) {
2036 +       case CPU_386:
2037 +               si->processorType = PROC_386;
2038 +               break;
2039 +       case CPU_486:
2040 +               si->processorType = PROC_486;
2041 +               break;
2042 +       case CPU_586:
2043 +               si->processorType = PROC_PENTIUM;
2044 +               break;
2045 +       default:  // Just in case 
2046 +               si->processorType = PROC_PENTIUM;
2047 +               break;
2048 +       }
2049 +
2050 +       spin_lock_irqsave(&rtc_lock, flags);
2051 +
2052 +       /* Get drive type for 1st drive*/
2053 +       i = CMOS_READ(0x12) >> 4;
2054 +       j = i >> 4;
2055 +       if (i == 0x0f) {
2056 +               j = CMOS_READ(0x19);
2057 +       }
2058 +       si->drive0CMOS = j;
2059 +
2060 +       /* Get driver type for 2nd drive*/
2061 +       j = i & 0x0f;
2062 +       if (i == 0x0f) {
2063 +               j = CMOS_READ(0x1a);
2064 +       }
2065 +       spin_unlock_irqrestore(&rtc_lock, flags);
2066 +
2067 +       si->drive1CMOS = j;
2068 +       /* Get number of drives sys bios found */
2069 +       si->numDrives = *((char *) phys_to_virt(0x475));
2070 +       /* What info in si is valid */
2071 +       si->flags = SI_CMOS_Valid | SI_NumDrivesValid | SI_OSversionValid | SI_BusTypeValid;
2072 +
2073 +       /* Go Out And Look For SmartROM revision */
2074 +       for (i = 0; i < 3; ++i) {
2075 +               int k;
2076 +               u32 addr = 0;
2077 +
2078 +               /* Decide which bank */
2079 +               if(i == 0) {
2080 +                       addr = 0xC8000;
2081 +               } else if(i == 1) {
2082 +                       addr = 0xD8000;
2083 +               } else {
2084 +                       addr = 0xDC000;
2085 +               }
2086 +
2087 +               /* Looking for our bios signature */
2088 +               if(isa_readw(addr) != 0xAA55) {
2089 +                       continue;
2090 +               }
2091 +               if(isa_readl( addr+6) != 0x202053) {
2092 +                       continue;
2093 +               }
2094 +               if(isa_readl(addr+10) != 0x545044) {
2095 +                       continue;
2096 +               }
2097 +
2098 +               addr += 0x24;
2099 +
2100 +               /* scan for " v" */
2101 +               for (k = 0; k < 64; ++k) {
2102 +                       if(isa_readb(addr++) == ' ' && isa_readb(addr) == 'v' ) {
2103 +                               break;
2104 +                       }
2105 +               }
2106 +
2107 +               /* Found it - get version */
2108 +               if(k < 64) {
2109 +                       si->smartROMMajorVersion = isa_readb(addr += 3) - '0';
2110 +                       si->smartROMMinorVersion = isa_readb(addr += 2);
2111 +                       si->smartROMRevision = isa_readb(++addr);
2112 +                       si->flags |= SI_SmartROMverValid;
2113 +                       break;
2114 +               }
2115 +       }
2116 +
2117 +       if(i >= 3) {
2118 +               /* if didn't find it - no smart ROM */
2119 +               si->flags |= SI_NO_SmartROM;
2120 +       }
2121 +
2122 +       if(si->numDrives > 0) {
2123 +               u32 addr = 0;
2124 +               /* Get The Pointer From Int 41 For The First
2125 +                * Drive Parameters
2126 +                */
2127 +               addr =  (((u32)isa_readw(0x104+2)) << 4) + (u16)isa_readw(0x104);
2128 +               /*
2129 +                * It appears that SmartROM's Int41/Int46 pointers
2130 +                * use memory that gets stepped on by the kernel
2131 +                * loading. We no longer have access to this
2132 +                * geometry information but try anyways (!?)
2133 +                */
2134 +               si->drives[0].cylinders = isa_readb(addr++);
2135 +               si->drives[0].cylinders += ((int)isa_readb(addr++)) << 8;
2136 +               si->drives[0].heads = isa_readb(addr);
2137 +               addr += 12;
2138 +               si->drives[0].sectors = isa_readb(addr);
2139 +               si->flags |= SI_DriveParamsValid;
2140 +               if((si->drives[0].cylinders != 0) && 
2141 +                  (si->drives[0].heads     != 0) &&
2142 +                  (si->drives[0].sectors   != 0)) {
2143 +                       si->flags |= SI_DriveParamsValid;
2144 +                       return;
2145 +               }
2146 +               if(si->numDrives > 1) {
2147 +                       /*
2148 +                        * Get Pointer From Int 46 For The 2nd Drive Parameters
2149 +                        */
2150 +                       addr =  (((u32)isa_readw(0x118+2)) << 4) + (u16)isa_readw(0x118);
2151 +                       si->drives[1].cylinders = isa_readb(addr++);
2152 +                       si->drives[1].cylinders += ((int)isa_readb(addr++)) << 8;
2153 +                       si->drives[1].heads = isa_readb(addr);
2154 +                       addr += 12;
2155 +                       si->drives[0].sectors = isa_readb(addr);
2156 +                       if(!((si->drives[1].cylinders != 0) && 
2157 +                            (si->drives[1].heads     != 0) &&
2158 +                            (si->drives[1].sectors   != 0))) {
2159 +                               si->flags &=  ~SI_DriveParamsValid;
2160 +                       }
2161 +               }
2162 +       }
2163 +
2164 +}
2165 +
2166 +#else
2167 +
2168 +void adpt_i386_info(sysInfo_S* si)
2169 +{
2170 +       int i;
2171 +       int j;
2172 +       caddr_t c_addr;
2173 +       ulong flags=0;
2174 +
2175 +       switch (boot_cpu_data.x86) {
2176 +       case CPU_386:
2177 +               si->processorType = PROC_386;
2178 +               break;
2179 +       case CPU_486:
2180 +               si->processorType = PROC_486;
2181 +               break;
2182 +       case CPU_586:
2183 +               si->processorType = PROC_PENTIUM;
2184 +               break;
2185 +       default:  // Just in case 
2186 +               si->processorType = PROC_PENTIUM;
2187 +               break;
2188 +       }
2189 +
2190 +//     spin_lock_irqsave(&rtc_lock, flags);
2191 +
2192 +       /* Get drive type for 1st drive*/
2193 +       i = CMOS_READ(0x12) >> 4;
2194 +       j = i >> 4;
2195 +       if (i == 0x0f) {
2196 +               j = CMOS_READ(0x19);
2197 +       }
2198 +       si->drive0CMOS = j;
2199 +
2200 +       /* Get driver type for 2nd drive*/
2201 +       j = i & 0x0f;
2202 +       if (i == 0x0f) {
2203 +               j = CMOS_READ(0x1a);
2204 +       }
2205 +//     spin_unlock_irqrestore(&rtc_lock, flags);
2206 +
2207 +       si->drive1CMOS = j;
2208 +       /* Get number of drives sys bios found */
2209 +       si->numDrives = *((char *) phys_to_virt(0x475));
2210 +       /* What info in si is valid */
2211 +       si->flags = SI_CMOS_Valid | SI_NumDrivesValid | SI_OSversionValid | SI_BusTypeValid;
2212 +
2213 +       /* Go Out And Look For SmartROM revision */
2214 +       for (i = 0; i < 3; ++i) {
2215 +               int k;
2216 +
2217 +               /* Decide which bank */
2218 +               if(i == 0) {
2219 +                       j = 0xC8000;
2220 +               } else if(i == 1) {
2221 +                       j = 0xD8000;
2222 +               } else {
2223 +                       j = 0xDC000;
2224 +               }
2225 +               c_addr = phys_to_virt(j);
2226 +
2227 +               /* Looking for our bios signature */
2228 +               if (*((unsigned short *) c_addr) != 0xAA55) {
2229 +                       continue;
2230 +               }
2231 +               if (*((unsigned long *) (c_addr + 6)) != 0x202053) {
2232 +                       continue;
2233 +               }
2234 +               if (*((unsigned long *) (c_addr + 10)) != 0x545044) {
2235 +                       continue;
2236 +               }
2237 +
2238 +               c_addr += 0x24;
2239 +
2240 +               /* scan for " v" */
2241 +               for (k = 0; k < 64; ++k) {
2242 +                       if ((*((unsigned char *) (c_addr++)) == ' ') &&
2243 +                           (*((unsigned char *) (c_addr))   == 'v')) {
2244 +                               break;
2245 +                       }
2246 +               }
2247 +
2248 +               /* Found it - get version */
2249 +               if(k < 64) {
2250 +                       si->smartROMMajorVersion = *((unsigned char *)(c_addr += 3)) - '0';
2251 +                       si->smartROMMinorVersion = *((unsigned char *)(c_addr += 2));
2252 +                       si->smartROMRevision = *((unsigned char *)(++c_addr));
2253 +                       si->flags |= SI_SmartROMverValid;
2254 +                       break;
2255 +               }
2256 +       }
2257 +
2258 +       if(i >= 3) {
2259 +               /* if didn't find it - no smart ROM */
2260 +               si->flags |= SI_NO_SmartROM;
2261 +       }
2262 +
2263 +       if(si->numDrives > 0) {
2264 +               /*
2265 +                * Get The Pointer From Int 41 For The First
2266 +                * Drive Parameters
2267 +                */
2268 +               j =  ((unsigned)(*((unsigned short *)phys_to_virt(0x104 + 2))) << 4)
2269 +                   + (unsigned)(*((unsigned short *)phys_to_virt(0x104 + 0)));
2270 +               /*
2271 +                * It appears that SmartROM's Int41/Int46 pointers
2272 +                * use memory that gets stepped on by the kernel
2273 +                * loading. We no longer have access to this
2274 +                * geometry information but try anyways (!?)
2275 +                */
2276 +               si->drives[0].cylinders = *((unsigned char *)phys_to_virt(j));
2277 +               si->drives[0].cylinders += ((int)*((unsigned char *)phys_to_virt(j))) << 8;
2278 +               si->drives[0].heads = *((unsigned char *) phys_to_virt(j));
2279 +               j += 12;
2280 +               si->drives[0].sectors = *((unsigned char *) phys_to_virt(j));
2281 +               si->flags |= SI_DriveParamsValid;
2282 +               if((si->drives[0].cylinders != 0) && 
2283 +                  (si->drives[0].heads     != 0) &&
2284 +                  (si->drives[0].sectors   != 0)) {
2285 +                       si->flags |= SI_DriveParamsValid;
2286 +                       return;
2287 +               }
2288 +               if(si->numDrives > 1) {
2289 +                       /*
2290 +                        * Get Pointer From Int 46 For The 2nd Drive Parameters
2291 +                        */
2292 +                       j =  ((unsigned)(*((unsigned short *)phys_to_virt(0x118 + 2))) << 4)
2293 +                           + (unsigned)(*((unsigned short *)phys_to_virt(0x118 + 0)));
2294 +                       si->drives[1].cylinders = *((unsigned char *)phys_to_virt(j));
2295 +                       si->drives[1].cylinders += ((int)*((unsigned char *)phys_to_virt(j))) << 8;
2296 +                       si->drives[1].heads = *((unsigned char *) phys_to_virt(j));
2297 +                       j += 12;
2298 +                       si->drives[1].sectors = *((unsigned char *) phys_to_virt(j));
2299 +                       if(!((si->drives[1].cylinders != 0) && 
2300 +                            (si->drives[1].heads     != 0) &&
2301 +                            (si->drives[1].sectors   != 0))) {
2302 +                               si->flags &=  ~SI_DriveParamsValid;
2303 +                       }
2304 +               }
2305 +       }
2306 +
2307 +}
2308 +
2309 +#endif
2310 +#endif
2311 +
2312 +
2313 +int adpt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
2314 +             unsigned long arg)
2315 +{
2316 +       int minor;
2317 +       int error = 0;
2318 +       adpt_hba* pHba;
2319 +
2320 +       minor = MINOR(inode->i_rdev);
2321 +       if (minor >= DPTI_MAX_HBA){
2322 +               return -ENXIO;
2323 +       }
2324 +       down(&adpt_configuration_lock);
2325 +       for (pHba = hba_chain; pHba; pHba = pHba->next) {
2326 +               if (pHba->unit == minor) {
2327 +                       break;  /* found adapter */
2328 +               }
2329 +       }
2330 +       up(&adpt_configuration_lock);
2331 +       if(pHba == NULL){
2332 +               return -ENXIO;
2333 +       }
2334 +
2335 +       while((volatile u32) pHba->state & DPTI_STATE_RESET ) {
2336 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2337 +               set_task_state(current,TASK_UNINTERRUPTIBLE);
2338 +#else
2339 +               current->state = TASK_UNINTERRUPTIBLE;
2340 +#endif
2341 +               schedule_timeout(2);
2342 +
2343 +       }
2344 +
2345 +       switch (cmd) {
2346 +       // TODO: handle 3 cases
2347 +       case DPT_SIGNATURE:
2348 +               if (copy_to_user((char*)arg, &DPTI_sig, sizeof(DPTI_sig))) {
2349 +                       return -EFAULT;
2350 +               }
2351 +               break;
2352 +       case I2OUSRCMD:
2353 +               return  adpt_i2o_passthru(pHba,(u32*)arg);
2354 +               break;
2355 +
2356 +       case DPT_CTRLINFO:{
2357 +               drvrHBAinfo_S HbaInfo;
2358 +
2359 +#define FLG_OSD_PCI_VALID 0x0001
2360 +#define FLG_OSD_DMA      0x0002
2361 +#define FLG_OSD_I2O      0x0004
2362 +               memset(&HbaInfo, 0, sizeof(HbaInfo));
2363 +               HbaInfo.drvrHBAnum = pHba->unit;
2364 +               HbaInfo.baseAddr = (ulong) pHba->base_addr_phys;
2365 +               HbaInfo.blinkState = adpt_getBlinkLED(pHba);
2366 +               HbaInfo.pciBusNum =  pHba->pDev->bus->number;
2367 +               HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn); 
2368 +               HbaInfo.Interrupt = pHba->pDev->irq; 
2369 +               HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
2370 +               if(copy_to_user((void *) arg, &HbaInfo, sizeof(HbaInfo))){
2371 +                       printk(KERN_WARNING"%s: Could not copy HbaInfo TO user\n",pHba->name);
2372 +                       return -EFAULT;
2373 +               }
2374 +               break;
2375 +               }
2376 +       case DPT_SYSINFO:
2377 +               return adpt_system_info((void*)arg);
2378 +               break;
2379 +       case DPT_BLINKLED:{
2380 +               u32 value;
2381 +               value = adpt_getBlinkLED(pHba);
2382 +               if (copy_to_user((char*)arg, &value, sizeof(value))) {
2383 +                       return -EFAULT;
2384 +               }
2385 +               break;
2386 +               }
2387 +       case I2ORESETCMD:
2388 +               adpt_hba_reset(pHba);
2389 +               break;
2390 +       case I2ORESCANCMD:
2391 +               adpt_rescan(pHba);
2392 +               break;
2393 +       case DPT_TARGET_BUSY & 0xFFFF:
2394 +       case DPT_TARGET_BUSY:
2395 +       {
2396 +               TARGET_BUSY_T busy;
2397 +               struct adpt_device* d;
2398 +
2399 +               if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
2400 +                       return -EFAULT;
2401 +               }
2402 +
2403 +               d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
2404 +               if(d == NULL){
2405 +                       return -ENODEV;
2406 +               }
2407 +               busy.isBusy = ((d->pScsi_dev) && (0 != d->pScsi_dev->access_count)) ? 1 : 0;
2408 +               if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
2409 +                       return -EFAULT;
2410 +               }
2411 +               break;
2412 +       }
2413 +       default:
2414 +               return -EINVAL;
2415 +       }
2416 +
2417 +       return error;
2418 +}
2419 +
2420 +
2421 +const char *adpt_info(struct Scsi_Host *host)
2422 +{
2423 +       adpt_hba* pHba;
2424 +
2425 +       pHba = (adpt_hba *) host->hostdata[0];
2426 +       return (char *) (pHba->detail);
2427 +}
2428 +
2429 +int adpt_proc_info(char *buffer, char **start, off_t offset,
2430 +                 int length, int hostno, int inout)
2431 +{
2432 +       struct adpt_device* d;
2433 +       int id;
2434 +       int chan;
2435 +       int len = 0;
2436 +       int begin = 0;
2437 +       int pos = 0;
2438 +       adpt_hba* pHba;
2439 +       struct Scsi_Host *host;
2440 +
2441 +       *start = buffer;
2442 +       if (inout == TRUE) {
2443 +               /*
2444 +                * The user has done a write and wants us to take the
2445 +                * data in the buffer and do something with it.
2446 +                * proc_scsiwrite calls us with inout = 1
2447 +                *
2448 +                * Read data from buffer (writing to us) - NOT SUPPORTED
2449 +                */
2450 +               return -ENOSYS;
2451 +       }
2452 +
2453 +       /*
2454 +        * inout = 0 means the user has done a read and wants information
2455 +        * returned, so we write information about the cards into the buffer
2456 +        * proc_scsiread() calls us with inout = 0
2457 +        */
2458 +
2459 +       /*
2460 +        * We have returned buffer to (buffer + offset) in previous calls
2461 +        * Set start to where we want the beginning of the new data to be.
2462 +        */
2463 +       *start = buffer + offset;
2464 +
2465 +       // Find HBA (host bus adapter) we are looking for
2466 +       down(&adpt_configuration_lock);
2467 +       for (pHba = hba_chain; pHba; pHba = pHba->next) {
2468 +               if (pHba->host->host_no == hostno) {
2469 +                       break;  /* found adapter */
2470 +               }
2471 +       }
2472 +       up(&adpt_configuration_lock);
2473 +       if (pHba == NULL) {
2474 +               return 0;
2475 +       }
2476 +       host = pHba->host;
2477 +
2478 +       len  = sprintf(buffer      , "Adaptec I2O RAID Driver Version: %s:\n\n", DPT_I2O_VERSION);
2479 +       len += sprintf(buffer+len, "%s:\n\n", pHba->detail);
2480 +       len += sprintf(buffer+len, "SCSI Host No. %d. Control Node =/dev/%s\n", pHba->host->host_no, pHba->name);
2481 +       len += sprintf(buffer+len, "  max channel = %d, max id = %d, max lun = %d,\n",
2482 +                                       host->max_channel, host->max_id - 1, host->max_lun - 1);
2483 +       len += sprintf(buffer+len, "  post fifo size = %d, reply fifo size = %d\n",
2484 +                                       host->can_queue, (int) pHba->reply_fifo_size );
2485 +       //TODO(defer) change this to something more meaningful
2486 +       len += sprintf(buffer+len, "  sg table size = %d, irq = %d\n\n",
2487 +                                       host->sg_tablesize, host->irq);
2488 +
2489 +       len +=  sprintf(buffer+len, "  Devices:\n");
2490 +       for (chan = 0; chan < MAX_CHANNEL; chan++) {
2491 +               for (id = 0; id < MAX_ID; id++) {
2492 +                       d = pHba->channel[chan].device[id];
2493 +                       while(d){
2494 +                               len += sprintf(buffer+len, "  Channel = %d, Target = %d, Lun = %d\n",
2495 +                                              (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun); 
2496 +                               pos = begin + len;
2497 +                               d = d->next_lun;
2498 +                       }
2499 +               }
2500 +               if (pos < offset) {
2501 +                       /*
2502 +                        * If we haven't even written to where we last left
2503 +                        * off (the last time we were called), reset the 
2504 +                        * beginning pointer.
2505 +                        */
2506 +                       len = 0;
2507 +                       begin = pos;
2508 +               }
2509 +               if (pos > offset + length) {
2510 +                       /*
2511 +                        * We have written past the end of the buffer 
2512 +                        * (proc_read/writescsi gives us 1K slop
2513 +                        *
2514 +                        * stop the output and calculate the correct length
2515 +                        */
2516 +                       goto stop_output;
2517 +               }
2518 +       }
2519 +       /*
2520 +        * begin is where we last checked our position with regards to offset
2521 +        * begin is always less than offset.  len is relative to begin.  It
2522 +        * is the number of bytes written past begin
2523 +        *
2524 +        */
2525 +stop_output:
2526 +       *(buffer + len) = '\0';
2527 +
2528 +       len -= (offset - begin);
2529 +       if (len > length) {
2530 +               len = length;
2531 +       }
2532 +       return len;
2533 +}
2534 +
2535 +
2536 +/*
2537 + * I2O System Table.  Contains information about
2538 + * all the IOPs in the system.  Used to inform IOPs
2539 + * about each other's existence.
2540 + *
2541 + * sys_tbl_ver is the CurrentChangeIndicator that is
2542 + * used by IOPs to track changes.
2543 + */
2544 +
2545 +
2546 +int adpt_i2o_build_sys_table(void)
2547 +{
2548 +       adpt_hba* pHba = NULL;
2549 +       int count = 0;
2550 +
2551 +       sys_tbl_len = sizeof(struct i2o_sys_tbl) +      // Header + IOPs
2552 +                               (hba_count) * sizeof(struct i2o_sys_tbl_entry);
2553 +
2554 +       if(sys_tbl)
2555 +               kfree(sys_tbl);
2556 +
2557 +       sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
2558 +       if(!sys_tbl) {
2559 +               printk(KERN_ERR "SysTab Set failed. Out of memory.\n"); 
2560 +               return -ENOMEM;
2561 +       }
2562 +       memset(sys_tbl, 0, sys_tbl_len);
2563 +
2564 +       sys_tbl->num_entries = hba_count;
2565 +       sys_tbl->version = I2OVERSION;
2566 +       sys_tbl->change_ind = sys_tbl_ind++;
2567 +
2568 +       for(pHba = hba_chain; pHba; pHba = pHba->next) {
2569 +               // Get updated Status Block so we have the latest information
2570 +               if (adpt_i2o_status_get(pHba)) {
2571 +                       sys_tbl->num_entries--;
2572 +                       continue; // try next one       
2573 +               }
2574 +
2575 +               sys_tbl->iops[count].org_id = pHba->status_block->org_id;
2576 +               sys_tbl->iops[count].iop_id = pHba->unit + 2;
2577 +               sys_tbl->iops[count].seg_num = 0;
2578 +               sys_tbl->iops[count].i2o_version = pHba->status_block->i2o_version;
2579 +               sys_tbl->iops[count].iop_state = pHba->status_block->iop_state;
2580 +               sys_tbl->iops[count].msg_type = pHba->status_block->msg_type;
2581 +               sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
2582 +               sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
2583 +               sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
2584 +               sys_tbl->iops[count].inbound_low = (u32)virt_to_bus((void*)pHba->post_port);
2585 +               sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus((void*)pHba->post_port)>>32);
2586 +
2587 +               count++;
2588 +       }
2589 +
2590 +#ifdef DEBUG
2591 +{
2592 +       u32 *table = (u32*)sys_tbl;
2593 +       printk(KERN_INFO"sys_tbl_len=%d in 32bit words\n",(sys_tbl_len >>2));
2594 +       for(count = 0; count < (sys_tbl_len >>2); count++) {
2595 +               printk(KERN_INFO "sys_tbl[%d] = %0#10x\n", 
2596 +                       count, table[count]);
2597 +       }
2598 +}
2599 +#endif
2600 +
2601 +       return 0;
2602 +}
2603 +
2604 +
2605 +s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
2606 +{
2607 +       u8 *status;
2608 +       u32 m;
2609 +       u32 *msg;
2610 +       int i;
2611 +       u32 timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
2612 +       u32* ptr;
2613 +       u32 outbound_frame;
2614 +
2615 +       do {
2616 +               rmb();
2617 +               m = readl(pHba->post_port);
2618 +               if (m != EMPTY_QUEUE) {
2619 +                       break;
2620 +               }
2621 +
2622 +               if(time_after(jiffies,timeout)){
2623 +                       printk("%s: Timeout waiting for message frame\n",pHba->name);
2624 +                       return -ETIMEDOUT;
2625 +               }
2626 +       } while(m == EMPTY_QUEUE);
2627 +
2628 +       msg=(u32 *)(pHba->msg_addr_virt+m);
2629 +
2630 +       status = kmalloc(4,GFP_KERNEL|ADDR32);
2631 +       if (status==NULL) {
2632 +               adpt_send_nop(pHba, m);
2633 +               printk(KERN_ERR "%s: IOP reset failed - no free memory.\n",
2634 +                       pHba->name);
2635 +               return -ENOMEM;
2636 +       }
2637 +       memset(status, 0, 4);
2638 +
2639 +       writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
2640 +       writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
2641 +       writel(0, &msg[2]);
2642 +       writel(0x0106, &msg[3]);        /* Transaction context */
2643 +       writel(4096, &msg[4]);          /* Host page frame size */
2644 +       writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]);   /* Outbound msg frame size and Initcode */
2645 +       writel(0xD0000004, &msg[6]);            /* Simple SG LE, EOB */
2646 +       writel(virt_to_bus(status), &msg[7]);
2647 +
2648 +       writel(m, pHba->post_port);
2649 +       wmb();
2650 +
2651 +       // Wait for the reply status to come back
2652 +       do {
2653 +               if ((volatile u32)*status) {
2654 +                       if ((volatile u32)*status != 0x01 /*I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS*/) {
2655 +                               break;
2656 +                       }
2657 +               }
2658 +               rmb();
2659 +               if(time_after(jiffies,timeout)){
2660 +                       printk("%s: Timeout Initializing\n",pHba->name);
2661 +                       kfree((void*)status);
2662 +                       return -ETIMEDOUT;
2663 +               }
2664 +       } while (1);
2665 +
2666 +       // If the command was successful, fill the fifo with our reply
2667 +       // message packets
2668 +       if ((volatile u32)(*status) != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
2669 +               kfree((void*)status);
2670 +               return -2;
2671 +       }
2672 +       kfree((void*)status);
2673 +
2674 +       if(pHba->reply_pool != NULL){
2675 +               kfree(pHba->reply_pool);
2676 +       }
2677 +
2678 +       pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
2679 +       if(!pHba->reply_pool){
2680 +               printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name);
2681 +               return -1;
2682 +       }
2683 +       memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
2684 +
2685 +       ptr = pHba->reply_pool;
2686 +       // TODO remove this code
2687 +       m = 0; 
2688 +       for(i = 0; i < pHba->reply_fifo_size; i++) {
2689 +               outbound_frame = (u32)virt_to_bus(ptr);
2690 +               if(m) {
2691 +                       if ((m + REPLY_FRAME_SIZE * 4) != outbound_frame) {
2692 +                               printk(KERN_WARNING"%s: Reply Frames are not in a contiguous pool, skipping one\n",pHba->name);
2693 +                       } else {
2694 +                               writel(m, pHba->reply_port);
2695 +                               wmb();
2696 +                       }
2697 +               }
2698 +               m = outbound_frame;
2699 +               ptr +=  REPLY_FRAME_SIZE;
2700 +       }
2701 +       // the last frame represented in m & outbound_frame is necessarily lost by the above algorithm.
2702 +       adpt_i2o_status_get(pHba);
2703 +       return 0;
2704 +}
2705 +
2706 +
2707 +void adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
2708 +{
2709 +       Scsi_Cmnd* cmd;
2710 +       adpt_hba* pHba=NULL;
2711 +       u32 m;
2712 +       ulong reply;
2713 +       u32 status=0;
2714 +       u32 context;
2715 +       ulong flags = 0;
2716 +
2717 +       pHba = dev_id;
2718 +       if (pHba == NULL ){
2719 +               printk("adpt_isr: NULL dev_id\n");
2720 +               return;
2721 +       }
2722 +       spin_lock_irqsave(&io_request_lock, flags);
2723 +       while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) {
2724 +               m = readl(pHba->reply_port);
2725 +               if(m == EMPTY_QUEUE){
2726 +                       // Try twice then give up
2727 +                       rmb();
2728 +                       m = readl(pHba->reply_port);
2729 +                       if(m == EMPTY_QUEUE){ 
2730 +                               // This really should not happen
2731 +                               printk(KERN_ERR"dpti: Could not get reply frame\n");
2732 +                               spin_unlock_irqrestore(&io_request_lock,flags);
2733 +                               return;
2734 +                       }
2735 +               }
2736 +               reply = (ulong)bus_to_virt(m);
2737 +
2738 +               if (readl(reply) & MSG_FAIL) {
2739 +                       u32 old_m = readl(reply+28); 
2740 +                       ulong msg;
2741 +                       u32 old_context;
2742 +                       PDEBUG("%s: Failed message\n",pHba->name);
2743 +                       if(old_m >= 0x100000){
2744 +                               printk(KERN_ERR"%s: Bad preserved MFA (%x)- dropping frame\n",pHba->name,old_m);
2745 +                               writel(m,pHba->reply_port);
2746 +                               continue;
2747 +                       }
2748 +                       // Transaction context is 0 in failed reply frame
2749 +                       msg = (ulong)(pHba->msg_addr_virt + old_m);
2750 +                       old_context = readl(msg+12);
2751 +                       writel(old_context, reply+12);
2752 +                       adpt_send_nop(pHba, old_m);
2753 +               } 
2754 +               context = readl(reply+8);
2755 +               if(context & 0x40000000){ // IOCTL
2756 +                       caddr_t p = (caddr_t)(readl(reply+12));
2757 +                       if( p != NULL) {
2758 +                               memcpy(p, (caddr_t)reply, REPLY_FRAME_SIZE * 4);
2759 +                       }
2760 +                       // All IOCTLs will also be post wait
2761 +               }
2762 +               if(context & 0x80000000){ // Post wait message
2763 +                       status = readl(reply+16);
2764 +                       if(status  >> 24){
2765 +                               status = -( status & 0xffff);
2766 +                       } else {
2767 +                               status = I2O_POST_WAIT_OK;
2768 +                       }
2769 +                       if(!(context & 0x40000000)) {
2770 +                               cmd = (Scsi_Cmnd*) readl(reply+12); 
2771 +                               if(cmd != NULL) {
2772 +                                       printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
2773 +                               }
2774 +                       }
2775 +                       adpt_i2o_post_wait_complete(context, status);
2776 +               } else { // SCSI message
2777 +                       cmd = (Scsi_Cmnd*) readl(reply+12); 
2778 +                       if(cmd != NULL){
2779 +                               if(cmd->serial_number != 0) { // If not timedout
2780 +                                       adpt_i2o_to_scsi(reply, cmd);
2781 +                               }
2782 +                       }
2783 +               }
2784 +               writel(m, pHba->reply_port);
2785 +               wmb();
2786 +               rmb();
2787 +       }
2788 +       spin_unlock_irqrestore(&io_request_lock, flags);
2789 +       return;
2790 +
2791 +}
2792 +
2793 +s32 adpt_send_nop(adpt_hba*pHba,u32 m)
2794 +{
2795 +       u32 *msg;
2796 +       u32 timeout = jiffies + 5*HZ;
2797 +
2798 +       while(m == EMPTY_QUEUE){
2799 +               rmb();
2800 +               m = readl(pHba->post_port);
2801 +               if(m != EMPTY_QUEUE){
2802 +                       break;
2803 +               }
2804 +               if(time_after(jiffies,timeout)){
2805 +                       printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
2806 +                       return 2;
2807 +               }
2808 +       }
2809 +       msg = (u32*)(pHba->msg_addr_virt + m);
2810 +       writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
2811 +       writel( I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0,&msg[1]);
2812 +       writel( 0,&msg[2]);
2813 +       wmb();
2814 +
2815 +       writel(m, pHba->post_port);
2816 +       wmb();
2817 +       return 0;
2818 +}
2819 +
2820 +
2821 +/*
2822 + * dpti2oscsi2.c contains a table of scsi commands that is used to determine
2823 + * the data direction of the command.  It is used in dpt_scsi_to_i2o to speed
2824 + * up the building of the scsi message.
2825 + */
2826 +#include "dpti2oscsi2.c"
2827 +
2828 +
2829 +s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
2830 +{
2831 +       int i;
2832 +       u32 msg[MAX_MESSAGE_SIZE/4];
2833 +       u32* mptr;
2834 +       u32 *lenptr;
2835 +       int direction;
2836 +       int scsidir;
2837 +       u32 len;
2838 +       u32 reqlen;
2839 +       s32 rcode;
2840 +
2841 +       memset(msg, 0 , sizeof(msg));
2842 +       len = cmd->request_bufflen;
2843 +       direction = 0x00000000; 
2844 +       
2845 +       scsidir = 0x00000000;                   // DATA NO XFER
2846 +       if(len) {
2847 +               /*
2848 +                * Set SCBFlags to indicate if data is being transferred
2849 +                * in or out, or no data transfer
2850 +                * Note:  Do not have to verify index is less than 0 since
2851 +                * cmd->cmnd[0] is an unsigned char
2852 +                */
2853 +               if (cmd->cmnd[0] < DISKXFERTBLSIZE) {
2854 +                       switch (i2oscsi2diskxfer[cmd->cmnd[0]]) {
2855 +                       case DATAIN:
2856 +                               scsidir  =0x40000000;   // DATA IN  (iop<--dev)
2857 +                               break;
2858 +                       case DATAOUT:
2859 +                               direction=0x04000000;   // SGL OUT
2860 +                               scsidir  =0x80000000;   // DATA OUT (iop-->dev)
2861 +                               break;
2862 +                       case NODATA:
2863 +                               break;
2864 +                       case NOSUPPORT:
2865 +                               scsidir  =0x40000000;   // DATA IN  (iop<--dev)
2866 +                               // Assume In - and continue;
2867 +                               break;
2868 +                       default:
2869 +                               printk("%s: scsi opcode 0x%x not supported.\n",
2870 +                                    pHba->name, cmd->cmnd[0]);
2871 +                               cmd->result = (DID_OK <<16) | (INITIATOR_ERROR << 8);
2872 +                               cmd->scsi_done(cmd);
2873 +                               return  0;
2874 +                       }
2875 +               } else {
2876 +                       printk("%s: cmd->cmnd[0] = %d is greater than table size, which is %d\n",
2877 +                            pHba->name, cmd->cmnd[0], DISKXFERTBLSIZE);
2878 +               }
2879 +       }
2880 +       // msg[0] is set later
2881 +       // I2O_CMD_SCSI_EXEC
2882 +       msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
2883 +       msg[2] = 0;
2884 +       msg[3] = (u32)cmd;      /* We want the SCSI control block back */
2885 +       // Our cards use the transaction context as the tag for queueing
2886 +       // Adaptec/DPT Private stuff 
2887 +       msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16);
2888 +       msg[5] = d->tid;
2889 +       /* Direction, disconnect ok | sense data | simple queue , CDBLen */
2890 +       // I2O_SCB_FLAG_ENABLE_DISCONNECT | 
2891 +       // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
2892 +       // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
2893 +       msg[6] = scsidir|0x20a00000|cmd->cmd_len;
2894 +
2895 +       mptr=msg+7;
2896 +
2897 +       // Write SCSI command into the message - always 16 byte block 
2898 +       memset(mptr, 0,  16);
2899 +       memcpy(mptr, cmd->cmnd, cmd->cmd_len);
2900 +       mptr+=4;
2901 +       lenptr=mptr++;          /* Remember me - fill in when we know */
2902 +       reqlen = 14;            // SINGLE SGE
2903 +       /* Now fill in the SGList and command */
2904 +       if(cmd->use_sg) {
2905 +               struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
2906 +               len = 0;
2907 +               for(i = 0 ; i < cmd->use_sg; i++) {
2908 +                       *mptr++ = direction|0x10000000|sg->length;
2909 +                       len+=sg->length;
2910 +                       *mptr++ = virt_to_bus(sg->address);
2911 +                       sg++;
2912 +               }
2913 +               /* Make this an end of list */
2914 +               mptr[-2] = direction|0xD0000000|(sg-1)->length;
2915 +               reqlen = mptr - msg;
2916 +               *lenptr = len;
2917 +               
2918 +               if(cmd->underflow && len != cmd->underflow){
2919 +                       printk("Cmd len %08X Cmd underflow %08X\n",
2920 +                               len, cmd->underflow);
2921 +               }
2922 +       } else {
2923 +               *lenptr = len = cmd->request_bufflen;
2924 +               if(len == 0) {
2925 +                       reqlen = 12;
2926 +               } else {
2927 +                       *mptr++ = 0xD0000000|direction|cmd->request_bufflen;
2928 +                       *mptr++ = virt_to_bus(cmd->request_buffer);
2929 +               }
2930 +       }
2931 +       
2932 +       /* Stick the headers on */
2933 +       msg[0] = reqlen<<16 | ((reqlen > 12) ? SGL_OFFSET_12 : SGL_OFFSET_0);
2934 +       
2935 +       // Send it on it's way
2936 +       rcode = adpt_i2o_post_this(pHba, msg, reqlen<<2);
2937 +       if (rcode == 0) {
2938 +               return 0;
2939 +       }
2940 +       return rcode;
2941 +}
2942 +
2943 +
2944 +int adpt_abort(Scsi_Cmnd * cmd)
2945 +{
2946 +       adpt_hba* pHba = NULL;  /* host bus adapter structure */
2947 +       struct adpt_device* dptdevice;  /* dpt per device information */
2948 +       u32 msg[5];
2949 +
2950 +       printk(KERN_INFO"%s: Aborting cmd=%p\n",pHba->name, cmd);
2951 +
2952 +       pHba = (adpt_hba*) cmd->host->hostdata[0];
2953 +       if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
2954 +               printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
2955 +               return SCSI_ABORT_NOT_RUNNING;
2956 +       }
2957 +
2958 +       memset(msg, 0, sizeof(msg));
2959 +       msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
2960 +       msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
2961 +       msg[2] = 0;
2962 +       msg[3]= 0; 
2963 +       msg[4] = (u32)cmd;
2964 +       if(adpt_i2o_post_wait(pHba, msg, sizeof(msg), 60) != 0){
2965 +               return FAILED; // Timedout
2966 +       } 
2967 +       return  SUCCESS;
2968 +}
2969 +
2970 +
2971 +/*
2972 + * When adpt_release is called (from scsi_unregister_host, etc.), there are
2973 + * no longer any scsi command or device structures for this host in the
2974 + * upper-level scsi code - cannot send any commands up
2975 + *
2976 + * scsi_unregister will be called AFTER we return. 
2977 + */
2978 +int adpt_release(struct Scsi_Host *host)
2979 +{
2980 +       adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
2981 +//     adpt_i2o_quiesce_hba(pHba);
2982 +       adpt_i2o_delete_hba(pHba);
2983 +       return 0;
2984 +}
2985 +
2986 +
2987 +void adpt_inquiry(adpt_hba* pHba)
2988 +{
2989 +       u32 msg[14]; 
2990 +       u32 *mptr;
2991 +       u32 *lenptr;
2992 +       int direction;
2993 +       int scsidir;
2994 +       u32 len;
2995 +       u32 reqlen;
2996 +       u8* buf;
2997 +       u8  scb[16];
2998 +       s32 rcode;
2999 +
3000 +       memset(msg, 0, sizeof(msg));
3001 +       buf = (u8*)kmalloc(36,GFP_KERNEL|ADDR32);
3002 +       if(!buf){
3003 +               printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
3004 +               return;
3005 +       }
3006 +       memset((void*)buf, 0, 36);
3007 +       
3008 +       len = 36;
3009 +       direction = 0x00000000; 
3010 +       scsidir  =0x40000000;   // DATA IN  (iop<--dev)
3011 +
3012 +       reqlen = 14;            // SINGLE SGE
3013 +       /* Stick the headers on */
3014 +       msg[0] = reqlen<<16 | SGL_OFFSET_12;
3015 +       msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
3016 +       msg[2] = 0;
3017 +       msg[3]  = 0;
3018 +       // Adaptec/DPT Private stuff 
3019 +       msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
3020 +       msg[5] = ADAPTER_TID | 1<<16 /* Interpret*/;
3021 +       /* Direction, disconnect ok | sense data | simple queue , CDBLen */
3022 +       // I2O_SCB_FLAG_ENABLE_DISCONNECT | 
3023 +       // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
3024 +       // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
3025 +       msg[6] = scsidir|0x20a00000| 6 /* cmd len*/;
3026 +
3027 +       mptr=msg+7;
3028 +
3029 +       memset(scb, 0, sizeof(scb));
3030 +       // Write SCSI command into the message - always 16 byte block 
3031 +       scb[0] = INQUIRY;
3032 +       scb[1] = 0;
3033 +       scb[2] = 0;
3034 +       scb[3] = 0;
3035 +       scb[4] = 36;
3036 +       scb[5] = 0;
3037 +       // Don't care about the rest of scb
3038 +
3039 +       memcpy(mptr, scb, sizeof(scb));
3040 +       mptr+=4;
3041 +       lenptr=mptr++;          /* Remember me - fill in when we know */
3042 +
3043 +       /* Now fill in the SGList and command */
3044 +       *lenptr = len;
3045 +       *mptr++ = 0xD0000000|direction|len;
3046 +       *mptr++ = virt_to_bus(buf);
3047 +
3048 +       // Send it on it's way
3049 +       rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
3050 +       if (rcode != 0) {
3051 +               sprintf(pHba->detail, "Adaptec I2O RAID");
3052 +               printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
3053 +       } else {
3054 +               memset(pHba->detail, 0, sizeof(pHba->detail));
3055 +               memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
3056 +               memcpy(&(pHba->detail[16]), " Model: ", 8);
3057 +               memcpy(&(pHba->detail[24]), (u8*) &buf[16], 16);
3058 +               memcpy(&(pHba->detail[40]), " Rev: ", 6);
3059 +               memcpy(&(pHba->detail[46]), (u8*) &buf[32], 4);
3060 +               pHba->detail[50] = '\0';        /* precautionary */
3061 +       }
3062 +       kfree(buf);
3063 +       adpt_i2o_status_get(pHba);
3064 +       return ;
3065 +}
3066 +
3067 +
3068 +// This version of reset is called by the eh_error_handler
3069 +int adpt_reset(Scsi_Cmnd* cmd)
3070 +{
3071 +       adpt_hba* pHba;
3072 +       pHba = (adpt_hba*)cmd->host->hostdata;
3073 +       return adpt_hba_reset(pHba);
3074 +}
3075 +
3076 +
3077 +int adpt_hba_reset(adpt_hba* pHba)
3078 +{
3079 +       int rcode;
3080 +       ulong flags;
3081 +
3082 +       pHba->state |= DPTI_STATE_RESET;
3083 +
3084 +       spin_lock_irqsave(&io_request_lock, flags);
3085 +       // Activate does get status , init outbound, and get hrt
3086 +       if ((rcode=adpt_i2o_activate_hba(pHba)) < 0) {
3087 +               spin_unlock_irqrestore(&io_request_lock, flags);
3088 +               printk(KERN_ERR "%s: Could not activate\n", pHba->name);
3089 +               adpt_i2o_delete_hba(pHba);
3090 +               return rcode;
3091 +       }
3092 +
3093 +       if ((rcode=adpt_i2o_build_sys_table()) < 0) {
3094 +               spin_unlock_irqrestore(&io_request_lock, flags);
3095 +               adpt_i2o_delete_hba(pHba);
3096 +               return rcode;
3097 +       }
3098 +       PDEBUG("%s: in HOLD state\n",pHba->name);
3099 +
3100 +       if ((rcode=adpt_i2o_online_hba(pHba)) < 0) {
3101 +               spin_unlock_irqrestore(&io_request_lock, flags);
3102 +               adpt_i2o_delete_hba(pHba);      
3103 +               return rcode;
3104 +       }
3105 +       PDEBUG("%s: in OPERATIONAL state\n",pHba->name);
3106 +
3107 +       if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
3108 +               spin_unlock_irqrestore(&io_request_lock, flags);
3109 +               adpt_i2o_delete_hba(pHba);
3110 +               return rcode;
3111 +       }
3112 +
3113 +       if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
3114 +               spin_unlock_irqrestore(&io_request_lock, flags);
3115 +               adpt_i2o_delete_hba(pHba);
3116 +               return rcode;
3117 +       }
3118 +       pHba->state &= ~DPTI_STATE_RESET;
3119 +
3120 +       adpt_fail_posted_scbs(pHba);
3121 +       spin_unlock_irqrestore(&io_request_lock, flags);
3122 +       return 0;       /* return success */
3123 +}
3124 +
3125 +
3126 +// This version of bus reset is called by the eh_error handler
3127 +int adpt_bus_reset(Scsi_Cmnd* cmd)
3128 +{
3129 +       adpt_hba* pHba;
3130 +       u32 msg[4];
3131 +       pHba = (adpt_hba*)cmd->host->hostdata;
3132 +#define I2O_HBA_BUS_RESET 0x87
3133 +       memset(msg, 0, sizeof(msg));
3134 +       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
3135 +       msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->channel].tid);
3136 +       msg[2] = 0;
3137 +       msg[3] = 0;
3138 +       if(  adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
3139 +               // TODO we need to watch out here for infinite loops
3140 +               cmd->result = (DID_OK<<16) | (QUEUE_FULL << 1);
3141 +               cmd->scsi_done(cmd);
3142 +               return SUCCESS;
3143 +       } else {
3144 +               cmd->result = (DID_OK<<16);
3145 +               cmd->scsi_done(cmd);
3146 +               return SUCCESS;
3147 +       }
3148 +}
3149 +
3150 +// This is not currently supported by our adapter but we issue it anyway
3151 +int adpt_device_reset(Scsi_Cmnd* cmd)
3152 +{
3153 +       adpt_hba* pHba;
3154 +       u32 msg[4];
3155 +       struct adpt_device* d = (void*) cmd->device->hostdata;
3156 +
3157 +       pHba = (void*) cmd->host->hostdata;
3158 +       if (!d) {
3159 +               printk("%s: Reset Device: Device Not found\n",pHba->name);
3160 +               return FAILED;
3161 +       }
3162 +#define I2O_DEVICE_RESET 0x27
3163 +       // This is the same for BLK and SCSI devices
3164 +       // NOTE this is wrong in the i2o.h definitions
3165 +       memset(msg, 0, sizeof(msg));
3166 +       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
3167 +       msg[1] = (I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);
3168 +       msg[2] = 0;
3169 +       msg[3] = 0;
3170 +       if( adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
3171 +               // TODO we need to watch out here for infinite loops
3172 +               cmd->result = (DID_OK<<16) | (QUEUE_FULL << 1);
3173 +               cmd->scsi_done(cmd);
3174 +               return SUCCESS;
3175 +       } else {
3176 +               cmd->result = (DID_OK<<16);
3177 +               cmd->scsi_done(cmd);
3178 +               return SUCCESS;
3179 +       }
3180 +}
3181 +
3182 +void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist)
3183 +{
3184 +       Scsi_Device *device;    /* scsi layer per device information */
3185 +       adpt_hba* pHba;
3186 +
3187 +       pHba = (adpt_hba *) host->hostdata[0];
3188 +
3189 +       for (device = devicelist; device != NULL; device = device->next) {
3190 +               if (device->host != host) {
3191 +                       continue;
3192 +               }
3193 +               // TODO find better number for this
3194 +               if (host->can_queue) {
3195 +                       device->queue_depth =  host->can_queue - 1;
3196 +               } else {
3197 +                       device->queue_depth = 1;
3198 +               }
3199 +       }
3200 +}
3201 +
3202 +int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
3203 +{
3204 +       adpt_hba* pHba = NULL;
3205 +       struct adpt_device* pDev = NULL;        /* dpt per device information */
3206 +       u32 timeout = jiffies + (TMOUT_SCSI*HZ);
3207 +
3208 +       cmd->scsi_done = done;
3209 +       /*
3210 +        * SCSI REQUEST_SENSE commands will be executed automatically by the 
3211 +        * Host Adapter for any errors, so they should not be executed 
3212 +        * explicitly unless the Sense Data is zero indicating that no error 
3213 +        * occurred.
3214 +        */
3215 +
3216 +       if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
3217 +               cmd->result = (DID_OK << 16);
3218 +               cmd->scsi_done(cmd);
3219 +               return 0;
3220 +       }
3221 +
3222 +       pHba = (adpt_hba*)cmd->host->hostdata[0];
3223 +       if (!pHba) {
3224 +               return FAILED;
3225 +       }
3226 +
3227 +       if((((volatile u32)pHba->state) & DPTI_STATE_IOCTL) ||
3228 +             (((volatile u32)pHba->state) & DPTI_STATE_RESET)) {
3229 +               pHba->host->last_reset = jiffies;
3230 +               pHba->host->resetting = 1;
3231 +               return 1;
3232 +       }
3233 +       mod_timer(&cmd->eh_timeout, timeout);
3234 +
3235 +       if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
3236 +               /*
3237 +                * First command request for this device.  Set up a pointer
3238 +                * to the device structure.  This should be a TEST_UNIT_READY
3239 +                * command from scan_scsis_single.
3240 +                */
3241 +               if ((pDev = adpt_find_device(pHba, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun)) == NULL) {
3242 +                       cmd->result = (DID_NO_CONNECT << 16);
3243 +                       cmd->scsi_done(cmd);
3244 +                       return 0;
3245 +               }
3246 +               (struct adpt_device*)(cmd->device->hostdata) = pDev;
3247 +       }
3248 +       pDev->pScsi_dev = cmd->device;
3249 +
3250 +       /*
3251 +        * Let the rescan handler notify the sd layer to rescan the devices
3252 +        */
3253 +       if (pDev->state & DPTI_DEV_OFFLINE) {
3254 +               if (cmd->device != NULL) {
3255 +                       cmd->device->online = FALSE;
3256 +               }
3257 +               cmd->result = (DID_NO_CONNECT << 16);
3258 +               cmd->scsi_done(cmd);
3259 +               return 0;
3260 +       }
3261 +
3262 +       /*
3263 +        * If we are being called from when the device is being reset, 
3264 +        * or while being rescanned,
3265 +        * delay processing of the command until later.
3266 +        * MS: UNSCANNED components are typically not an issue because the applications
3267 +        * ensure (race conditions though) that the device to be alterred is not mounted
3268 +        * before adjusting the configurations. TIDs that have gone missing are better
3269 +        * processed by bubbling up the FAILED reply frame as a catastrophic failure of
3270 +        * the command.
3271 +        */
3272 +       if (pDev->state & DPTI_DEV_RESET /* || pDev->state & DPTI_DEV_UNSCANNED */) {
3273 +               return FAILED;
3274 +       }
3275 +       return adpt_scsi_to_i2o(pHba, cmd, pDev);
3276 +}
3277 +
3278 +
3279 +s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
3280 +{
3281 +       struct Scsi_Host *host = NULL;
3282 +
3283 +       host = scsi_register(sht, sizeof(adpt_hba*));
3284 +       if (host == NULL) {
3285 +               printk ("%s: scsi_register returned NULL\n",pHba->name);
3286 +               return -1;
3287 +       }
3288 +       (adpt_hba*)(host->hostdata[0]) = pHba;
3289 +       pHba->host = host;
3290 +
3291 +       host->irq = pHba->pDev->irq;;
3292 +       /* no IO ports, so don't have to set host->io_port and 
3293 +        * host->n_io_port
3294 +        */
3295 +       host->io_port = 0;
3296 +       host->n_io_port = 0;
3297 +                               /* see comments in hosts.h */
3298 +       host->max_id = pHba->top_scsi_id + 1;
3299 +       host->max_lun = pHba->top_scsi_lun + 1;
3300 +       host->max_channel = pHba->top_scsi_channel;
3301 +       host->cmd_per_lun = 256;
3302 +       host->unique_id = (unsigned int) pHba;
3303 +       host->sg_tablesize = pHba->sg_tablesize;
3304 +       host->can_queue = pHba->post_fifo_size;
3305 +       host->select_queue_depths = adpt_select_queue_depths;
3306 +
3307 +       return 0;
3308 +}
3309 +
3310 +
3311 +int adpt_bios_param(Disk* disk, kdev_t dev, int geom[])
3312 +{
3313 +       int heads=-1;
3314 +       int sectors=-1;
3315 +       int cylinders=-1;
3316 +
3317 +       // *** First lets set the default geometry ****
3318 +       
3319 +       // If the capacity is less than ox2000
3320 +       if (disk->capacity < 0x2000 ) { // floppy
3321 +               heads = 18;
3322 +               sectors = 2;
3323 +       } 
3324 +       // else if between 0x2000 and 0x20000
3325 +       else if (disk->capacity < 0x20000) {
3326 +               heads = 64;
3327 +               sectors = 32;
3328 +       }
3329 +       // else if between 0x20000 and 0x40000
3330 +       else if (disk->capacity < 0x40000) {
3331 +               heads = 65;
3332 +               sectors = 63;
3333 +       }
3334 +       // else if between 0x4000 and 0x80000
3335 +       else if (disk->capacity < 0x80000) {
3336 +               heads = 128;
3337 +               sectors = 63;
3338 +       }
3339 +       // else if greater than 0x80000
3340 +       else {
3341 +               heads = 255;
3342 +               sectors = 63;
3343 +       }
3344 +       cylinders = disk->capacity / (heads * sectors);
3345 +
3346 +       // Special case if CDROM
3347 +       if(disk->device->type == 5) {  // CDROM
3348 +               heads = 252;
3349 +               sectors = 63;
3350 +               cylinders = 1111;
3351 +       }
3352 +       // *** Now lets read the partition table to see what it thinks ****
3353 +       //
3354 +       // TODO(defer) dmb - use marks algorythm
3355 +       if( disk->has_part_table == 1){
3356 +
3357 +
3358 +       }
3359 +
3360 +
3361 +
3362 +
3363 +       geom[0] = heads;
3364 +       geom[1] = sectors;
3365 +       geom[2] = cylinders;
3366 +
3367 +       
3368 +       
3369 +       PDEBUG("adpt_bios_param: exit\n");
3370 +       return 0;
3371 +}
3372 +
3373 +
3374 +
3375 +#if 0
3376 +int adpt_read_capacity(adpt_hba* pHba, struct adpt_device* d)
3377 +{
3378 +       u32 msg[MAX_MESSAGE_SIZE/4], *mptr;
3379 +       u32 *lenptr;
3380 +       int direction;
3381 +       int scsidir;
3382 +       u32 len;
3383 +       u32 reqlen;
3384 +       u8* buf;
3385 +       u8  scb[16];
3386 +       u8* ptr;
3387 +       s32 rcode;
3388 +
3389 +       memset(msg, 0, sizeof(msg));
3390 +       len = 8;
3391 +       buf = (u8*)kmalloc(len,GFP_KERNEL|ADDR32);
3392 +       memset((void*)buf, 0, len);
3393 +       direction = 0x00000000; 
3394 +       scsidir  =0x40000000;   // DATA IN  (iop<--dev)
3395 +       reqlen = 14;            // SINGLE SGE
3396 +
3397 +       /* Stick the headers on */
3398 +       msg[0] = reqlen<<16 | SGL_OFFSET_12;
3399 +       msg[1] = (0xff<<24|HOST_TID<<12|d->tid);
3400 +       msg[2] = 0;
3401 +       msg[3] = 0;
3402 +       // Adaptec/DPT Private stuff 
3403 +       msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
3404 +       msg[5] = d->tid | 1<<16 /* Interpret*/;
3405 +       /* Direction, disconnect ok | sense data | simple queue , CDBLen */
3406 +       // I2O_SCB_FLAG_ENABLE_DISCONNECT | 
3407 +       // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
3408 +       // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
3409 +       msg[6] = scsidir|0x20a00000| 10 /* cmd len*/;
3410 +
3411 +       mptr=msg+7;
3412 +
3413 +       memset(scb, 0, sizeof(scb));
3414 +       // Write SCSI command into the message - always 16 byte block 
3415 +       scb[0] = READ_CAPACITY; 
3416 +       scb[1] = 0;
3417 +       scb[2] = 0;
3418 +       scb[3] = 0;
3419 +       scb[4] = 8;
3420 +       scb[5] = 0;
3421 +       scb[6] = 0;
3422 +       scb[7] = 0;
3423 +       scb[8] = 0;
3424 +       scb[9] = 0;
3425 +       // Don't care about the rest of scb
3426 +
3427 +       memcpy(mptr, scb, 16);
3428 +       mptr+=4;
3429 +       lenptr=mptr++;          /* Remember me - fill in when we know */
3430 +
3431 +       /* Now fill in the SGList and command */
3432 +       *lenptr = len;
3433 +       *mptr++ = 0xD0000000|direction|len;
3434 +       *mptr++ = virt_to_bus(buf);
3435 +
3436 +       // Send it on it's way
3437 +       if( (rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2,120)) ){
3438 +               printk("%s: Read Capacity failed (%d)\n",pHba->name, rcode);
3439 +               d->capacity = 0;
3440 +               d->block_size = 0;
3441 +       } else {
3442 +               int i;
3443 +               ptr = (u8*) &d->capacity;
3444 +               for (i = 0; i < 4; ++i) {
3445 +                       ptr[i] = buf[3-i];
3446 +               }
3447 +               ptr = (u8*)&d->block_size;
3448 +               for (i = 0; i < 4; ++i) {
3449 +                       ptr[i] = buf[7-i];
3450 +               }
3451 +       }
3452 +
3453 +       kfree(buf);
3454 +       return rcode;
3455 +}
3456 +#endif
3457 +
3458 +
3459 +s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
3460 +{
3461 +       adpt_hba* pHba;
3462 +       // I know this would look cleaner if I just read bytes
3463 +       // but the model I have been using for all the rest of the
3464 +       // io is in 4 byte words - so I keep that model
3465 +       u8 req_status = ( readl(reply+16) >> 24)&0xff;
3466 +       u16 detailed_status = readl(reply+16) &0xffff;
3467 +       u32 hba_status;
3468 +       u32 dev_status;
3469 +       u32 reply_flags = readl(reply) & 0xff00; // Leave it shifted up 8 bits 
3470 +
3471 +       dev_status = detailed_status & 0xff;
3472 +       hba_status = detailed_status >> 8;
3473 +       pHba = (adpt_hba*) cmd->host->hostdata[0];
3474 +
3475 +       if (!(reply_flags & MSG_FAIL)) {
3476 +               if (req_status) {
3477 +                       switch (detailed_status & I2O_SCSI_DSC_MASK) {
3478 +                       case I2O_SCSI_DSC_SUCCESS:
3479 +                               cmd->result = (DID_OK << 16);
3480 +                               break;
3481 +                       case I2O_SCSI_DSC_REQUEST_ABORTED:
3482 +                               cmd->result = (DID_ABORT << 16);
3483 +                               break;
3484 +                       case I2O_SCSI_DSC_UNABLE_TO_ABORT:
3485 +                       case I2O_SCSI_DSC_COMPLETE_WITH_ERROR:
3486 +                       case I2O_SCSI_DSC_UNABLE_TO_TERMINATE:
3487 +                       case I2O_SCSI_DSC_MR_MESSAGE_RECEIVED:
3488 +                       case I2O_SCSI_DSC_AUTOSENSE_FAILED:
3489 +                       case I2O_SCSI_DSC_DATA_OVERRUN:
3490 +                       case I2O_SCSI_DSC_UNEXPECTED_BUS_FREE:
3491 +                       case I2O_SCSI_DSC_SEQUENCE_FAILURE:
3492 +                       case I2O_SCSI_DSC_REQUEST_LENGTH_ERROR:
3493 +                       case I2O_SCSI_DSC_PROVIDE_FAILURE:
3494 +                       case I2O_SCSI_DSC_REQUEST_TERMINATED:
3495 +                       case I2O_SCSI_DSC_IDE_MESSAGE_SENT:
3496 +                       case I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT:
3497 +                       case I2O_SCSI_DSC_MESSAGE_RECEIVED:
3498 +                       case I2O_SCSI_DSC_INVALID_CDB:
3499 +                       case I2O_SCSI_DSC_LUN_INVALID:
3500 +                       case I2O_SCSI_DSC_SCSI_TID_INVALID:
3501 +                       case I2O_SCSI_DSC_FUNCTION_UNAVAILABLE:
3502 +                       case I2O_SCSI_DSC_NO_NEXUS:
3503 +                       case I2O_SCSI_DSC_SCSI_IID_INVALID:
3504 +                       case I2O_SCSI_DSC_CDB_RECEIVED:
3505 +                       case I2O_SCSI_DSC_LUN_ALREADY_ENABLED:
3506 +                       case I2O_SCSI_DSC_QUEUE_FROZEN:
3507 +                               cmd->result = (DID_ERROR << 16);
3508 +                               break;
3509 +                       case I2O_SCSI_DSC_ADAPTER_BUSY:
3510 +                       case I2O_SCSI_DSC_BUS_BUSY:
3511 +                               cmd->result = (DID_BUS_BUSY << 16);
3512 +                               break;
3513 +                       case I2O_SCSI_DSC_REQUEST_INVALID:
3514 +                               cmd->result = (DID_ERROR << 16);
3515 +                               break;
3516 +                       case I2O_SCSI_DSC_PATH_INVALID:
3517 +                       case I2O_SCSI_DSC_DEVICE_NOT_PRESENT:
3518 +                       case I2O_SCSI_DSC_SELECTION_TIMEOUT:
3519 +                       case I2O_SCSI_DSC_COMMAND_TIMEOUT:
3520 +                       case I2O_SCSI_DSC_NO_ADAPTER:
3521 +                       case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE:
3522 +                               cmd->result = (DID_TIME_OUT << 16);
3523 +                               cmd->device->online = FALSE;
3524 +                               break;
3525 +                       case I2O_SCSI_DSC_SCSI_BUS_RESET:
3526 +                       case I2O_SCSI_DSC_BDR_MESSAGE_SENT:
3527 +                               cmd->result = (DID_RESET << 16);
3528 +                               break;
3529 +                       case I2O_SCSI_DSC_PARITY_ERROR_FAILURE:
3530 +                               cmd->result = (DID_ERROR << 16);
3531 +                               break;
3532 +                       default:
3533 +                               cmd->result = (DID_NO_CONNECT << 16);
3534 +                               break;
3535 +                       }
3536 +
3537 +                       // If there is a SCSI target status, save it off in the OS request 
3538 +                       // packet and copy over the request sense data if it was a check
3539 +                       // condition status
3540 +                       if (dev_status == 0x02 /*I2O_SCSI_DSC_CHECK_CONDITION*/) {
3541 +                               u32 len = sizeof(cmd->sense_buffer);
3542 +                               len = (len > 40) ?  40 : len;
3543 +                               // Copy over the sense data
3544 +                               memcpy(cmd->sense_buffer, (void*)(reply+28) , len);
3545 +                       }
3546 +               } else {
3547 +                       cmd->result = (DID_OK << 16);
3548 +               }
3549 +
3550 +       } else {
3551 +               /*
3552 +                * We would figure doing a
3553 +                *      cmd->result = (DID_NO_CONNECT << 16);
3554 +                * would be more appropriate, but this would take devices
3555 +                * offline for a transitory error. Lets allow the applications
3556 +                * to issue a ioctl rescan, and let that look after taking
3557 +                * the device offline.
3558 +                */
3559 +               cmd->result = (DID_TIME_OUT << 16);
3560 +               /*
3561 +                * Something in the SCSI subsystem is pulling a cruelly upon me.
3562 +                * The I/O system locks up if I return DID_TIME_OUT (!) but
3563 +                * handles gracefully DID_NO_CONNECT.
3564 +                */
3565 +               cmd->result = (DID_NO_CONNECT << 16);
3566 +               printk("%s: I2O MSG_FAIL - Device (%d,%d,%d) tid=%d hba_status = 0x%x, dev_status = 0x%x, cmd = 0x%x\n",pHba->name,
3567 +               (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
3568 +               ((struct adpt_device*)(cmd->device->hostdata))->tid,
3569 +                      hba_status, dev_status, cmd->cmnd[0]);
3570 +       }
3571 +
3572 +       // TODO test the timeout lockup thingie
3573 +       if (cmd->result == (DID_TIME_OUT <<16) ){
3574 +               cmd->result = (DID_NO_CONNECT << 16);
3575 +       }
3576 +
3577 +       if (cmd->result == (DID_ERROR << 16)) {
3578 +               printk("SCSI error - Device (%d,%d,%d) tid=%d hba_status = 0x%x, dev_status = 0x%x, cmd = 0x%x\n",
3579 +               (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
3580 +               ((struct adpt_device*)(cmd->device->hostdata))->tid,
3581 +                      hba_status, dev_status, cmd->cmnd[0]);
3582 +               printk("SCSI cmd serial number  %ld\n", cmd->serial_number);
3583 +       } 
3584 +       if (cmd->result == (DID_TIME_OUT << 16)) {
3585 +               printk("%s: SCSI timeout - Device (%d,%d,%d) tid=%d hba_status = 0x%x, dev_status = 0x%x, cmd = 0x%x\n",pHba->name,
3586 +               (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
3587 +               ((struct adpt_device*)(cmd->device->hostdata))->tid,
3588 +                      hba_status, dev_status, cmd->cmnd[0]);
3589 +               printk("SCSI cmd serial number  %ld\n", cmd->serial_number);
3590 +       } 
3591 +       cmd->result |= (dev_status);
3592 +
3593 +       if(cmd->scsi_done != NULL && cmd->serial_number != 0){
3594 +               cmd->scsi_done(cmd);
3595 +       } else if(cmd->serial_number == 0) {
3596 +               u32 context = readl(reply+8);
3597 +               printk(KERN_WARNING"%s: Interrupt Handler overcompletion - cmd = %p context=%x\n", pHba->name, cmd, context);
3598 +       }
3599 +       return cmd->result;
3600 +}
3601 +
3602 +
3603 +s32 adpt_rescan(adpt_hba* pHba)
3604 +{
3605 +       s32 rcode;
3606 +       u32 flags;
3607 +
3608 +       spin_lock_irqsave(&io_request_lock, flags);
3609 +       if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
3610 +//             adpt_i2o_delete_hba(pHba);
3611 +               spin_unlock_irqrestore(&io_request_lock, flags);
3612 +               return rcode;
3613 +       }
3614 +
3615 +       if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
3616 +//             adpt_i2o_delete_hba(pHba);
3617 +               spin_unlock_irqrestore(&io_request_lock, flags);
3618 +               return rcode;
3619 +       }
3620 +       spin_unlock_irqrestore(&io_request_lock, flags);
3621 +       return 0;
3622 +}
3623 +
3624 +
3625 +s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
3626 +{
3627 +       int i;
3628 +       int max;
3629 +       int tid;
3630 +       struct i2o_device *d;
3631 +       i2o_lct *lct = pHba->lct;
3632 +       u8 bus_no = 0;
3633 +       s16 scsi_id;
3634 +       s16 scsi_lun;
3635 +       u32 buf[10]; // at least 8 u32's
3636 +       struct adpt_device* pDev = NULL;
3637 +       struct i2o_device* pI2o_dev = NULL;
3638 +       
3639 +       if (lct == NULL) {
3640 +               printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
3641 +               return -1;
3642 +       }
3643 +       
3644 +       max = lct->table_size;  
3645 +       max -= 3;
3646 +       max /= 9;
3647 +
3648 +       // Mark each drive as unscanned
3649 +       for (d = pHba->devices; d; d = d->next) {
3650 +               pDev =(struct adpt_device*) d->owner;
3651 +               if(!pDev){
3652 +                       continue;
3653 +               }
3654 +               pDev->state |= DPTI_DEV_UNSCANNED;
3655 +       }
3656 +
3657 +       printk(KERN_INFO "%s: LCT has %d entries.\n", pHba->name,max);
3658 +       
3659 +       if(lct->iop_flags&(1<<0))
3660 +               printk(KERN_WARNING "%s: Configuration dialog desired.\n", pHba->name);
3661 +
3662 +       for(i=0;i<max;i++) {
3663 +               if( lct->lct_entry[i].user_tid != 0xfff){
3664 +                       continue;
3665 +               }
3666 +
3667 +               if( lct->lct_entry[i].class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
3668 +                   lct->lct_entry[i].class_id == I2O_CLASS_SCSI_PERIPHERAL ||
3669 +                   lct->lct_entry[i].class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
3670 +                       tid = lct->lct_entry[i].tid;
3671 +                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
3672 +                               printk(KERN_ERR"%s: Could not query device\n",pHba->name);
3673 +                               continue;
3674 +                       }
3675 +                       bus_no = buf[0]>>16;
3676 +                       scsi_id = buf[1];
3677 +                       scsi_lun = (buf[2]>>8 )&0xff;
3678 +                       pDev = pHba->channel[bus_no].device[scsi_id];
3679 +                       /* da lun */
3680 +                       while(pDev) {
3681 +                               if(pDev->scsi_lun == scsi_lun) {
3682 +                                       break;
3683 +                               }
3684 +                               pDev = pDev->next_lun;
3685 +                       }
3686 +                       if(!pDev ) { // Something new add it
3687 +                               d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
3688 +                               if(d==NULL)
3689 +                               {
3690 +                                       printk(KERN_CRIT "Out of memory for I2O device data.\n");
3691 +                                       return -ENOMEM;
3692 +                               }
3693 +                               
3694 +                               d->controller = (void*)pHba;
3695 +                               d->next = NULL;
3696 +
3697 +                               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
3698 +
3699 +                               d->flags = 0;
3700 +                               adpt_i2o_report_hba_unit(pHba, d);
3701 +                               adpt_i2o_install_device(pHba, d);
3702 +       
3703 +                               if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
3704 +                                       printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
3705 +                                       continue;
3706 +                               }
3707 +                               pDev = pHba->channel[bus_no].device[scsi_id];   
3708 +                               if( pDev == NULL){
3709 +                                       pDev =  kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
3710 +                                       pHba->channel[bus_no].device[scsi_id] = pDev;
3711 +                               } else {
3712 +                                       while (pDev->next_lun) {
3713 +                                               pDev = pDev->next_lun;
3714 +                                       }
3715 +                                       pDev = pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
3716 +                               }
3717 +                               memset(pDev,0,sizeof(struct adpt_device));
3718 +                               pDev->tid = d->lct_data.tid;
3719 +                               pDev->scsi_channel = bus_no;
3720 +                               pDev->scsi_id = scsi_id;
3721 +                               pDev->scsi_lun = scsi_lun;
3722 +                               pDev->pI2o_dev = d;
3723 +                               d->owner = (struct i2o_handler *)pDev;
3724 +                               pDev->type = (buf[0])&0xff;
3725 +                               pDev->flags = (buf[0]>>8)&0xff;
3726 +                               // Too late, SCSI system has made up it's mind, but what the hey ...
3727 +                               if(scsi_id > pHba->top_scsi_id){
3728 +                                       pHba->top_scsi_id = scsi_id;
3729 +                               }
3730 +                               if(scsi_lun > pHba->top_scsi_lun){
3731 +                                       pHba->top_scsi_lun = scsi_lun;
3732 +                               }
3733 +                               continue;
3734 +                       } // end of new i2o device
3735 +
3736 +                       // We found an old device - check it
3737 +                       while(pDev) {
3738 +                               if(pDev->scsi_lun == scsi_lun) {
3739 +                                       if (pDev->state & DPTI_DEV_OFFLINE) {
3740 +                                               printk(KERN_WARNING"%s: Device (%d,%d,%d) online\n",pHba->name,bus_no,scsi_id,scsi_lun);
3741 +                                               if (pDev->pScsi_dev) {
3742 +                                                       pDev->pScsi_dev->online = TRUE;
3743 +                                               }
3744 +                                       }
3745 +                                       d = pDev->pI2o_dev;
3746 +                                       if(d->lct_data.tid != tid) { // something changed
3747 +                                               pDev->tid = tid;
3748 +                                               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
3749 +                                               if (pDev->pScsi_dev) {
3750 +                                                       pDev->pScsi_dev->changed = TRUE;
3751 +                                                       pDev->pScsi_dev->removable = TRUE;
3752 +                                               }
3753 +                                       }
3754 +                                       // Found it - mark it scanned
3755 +                                       pDev->state &= ~(DPTI_DEV_UNSCANNED|DPTI_DEV_OFFLINE);
3756 +                                       break;
3757 +                               }
3758 +                               pDev = pDev->next_lun;
3759 +                       }
3760 +               }
3761 +       }
3762 +       for (pI2o_dev = pHba->devices; pI2o_dev; pI2o_dev = pI2o_dev->next) {
3763 +               pDev =(struct adpt_device*) pI2o_dev->owner;
3764 +               if(!pDev){
3765 +                       continue;
3766 +               }
3767 +               // Drive offline drives that previously existed but could not be found
3768 +               // in the LCT table
3769 +               if (pDev->state & DPTI_DEV_UNSCANNED){
3770 +                       pDev->state |= DPTI_DEV_OFFLINE;
3771 +                       pDev->state &= ~DPTI_DEV_UNSCANNED;     // just to be clean
3772 +                       printk(KERN_WARNING"%s: Device (%d,%d,%d) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
3773 +                       if (pDev->pScsi_dev) {
3774 +                               pDev->pScsi_dev->online = FALSE;
3775 +                               // TODO check if this all that is needed to
3776 +                               // notify SCSI layer about this
3777 +                               if (pDev->pScsi_dev->access_count) {
3778 +                                       // A drive that was mounted is no longer there... bad!
3779 +                                       SCSI_LOG_ERROR_RECOVERY(1, printk ("%s:Rescan: Previously "
3780 +                                                                "mounted drive not found!\n",pHba->name));
3781 +                               }
3782 +                       }
3783 +               }
3784 +       }
3785 +       return 0;
3786 +}
3787 +
3788 +void adpt_fail_posted_scbs(adpt_hba* pHba)
3789 +{
3790 +       Scsi_Cmnd*      cmd = NULL;
3791 +       Scsi_Device*    d = NULL;
3792 +
3793 +       if( pHba->host->host_queue != NULL ) {
3794 +               d = pHba->host->host_queue;
3795 +               if(!d){
3796 +                       return;
3797 +               }
3798 +               while( d->next != NULL ){
3799 +                       for(cmd = d->device_queue; cmd ; cmd = cmd->next){
3800 +                               if(cmd->serial_number == 0){
3801 +                                       continue;
3802 +                               }
3803 +                               cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
3804 +                               cmd->scsi_done(cmd);
3805 +                       }
3806 +                       d = d->next;
3807 +               }
3808 +       }
3809 +}
3810 +
3811 +#ifdef UARTDELAY 
3812 +
3813 +static void adpt_delay(int millisec)
3814 +{
3815 +       int i;
3816 +       for (i = 0; i < millisec; i++) {
3817 +               udelay(1000);   /* delay for one millisecond */
3818 +       }
3819 +}
3820 +
3821 +#endif
3822 +
3823 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
3824 +struct pci_dev *
3825 +adpt_pci_find_device(unsigned int vendor, struct pci_dev *from)
3826 +{
3827 +       if(!from){
3828 +               from = pci_devices;
3829 +       } else {
3830 +               from = from->next;
3831 +       }
3832 +       while (from && from->vendor != vendor) {
3833 +               from = from->next;
3834 +       }
3835 +       return from;
3836 +}
3837 +#endif
3838 +
3839 --- /dev/null   Sat Apr 14 07:06:21 2001
3840 +++ linux/drivers/scsi/dpti.h   Wed Jul 18 14:31:28 2001
3841 @@ -0,0 +1,395 @@
3842 +/***************************************************************************
3843 +                          dpti.h  -  description
3844 +                             -------------------
3845 +    begin                : Thu Sep 7 2000
3846 +    copyright            : (C) 2001 by Adaptec
3847 +    email                : deanna_bonds@adaptec.com
3848 +
3849 +    See README.dpti for history, notes, license info, and credits
3850 + ***************************************************************************/
3851 +
3852 +/***************************************************************************
3853 + *                                                                         *
3854 + *   This program is free software; you can redistribute it and/or modify  *
3855 + *   it under the terms of the GNU General Public License as published by  *
3856 + *   the Free Software Foundation; either version 2 of the License, or     *
3857 + *   (at your option) any later version.                                   *
3858 + *                                                                         *
3859 + ***************************************************************************/
3860 +
3861 +#ifndef _DPT_H
3862 +#define _DPT_H
3863 +
3864 +#define MAX_TO_IOP_MESSAGES   (210)
3865 +#define MAX_FROM_IOP_MESSAGES (56)
3866 +
3867 +#ifndef LINUX_VERSION_CODE
3868 +#include <linux/version.h>
3869 +#endif
3870 +
3871 +#include "sys_info.h"
3872 +
3873 +/*
3874 + * Function Prototypes
3875 + */
3876 +
3877 +int adpt_proc_info(char *buffer, char **start, off_t offset,
3878 +                 int length, int inode, int inout);
3879 +int adpt_detect(Scsi_Host_Template * sht);
3880 +int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *));
3881 +int adpt_abort(Scsi_Cmnd * cmd);
3882 +int adpt_reset(Scsi_Cmnd* cmd);
3883 +int adpt_release(struct Scsi_Host *host);
3884 +
3885 +const char *adpt_info(struct Scsi_Host *pSHost);
3886 +int adpt_bios_param(Disk * disk, kdev_t dev, int geom[]);
3887 +
3888 +int adpt_bus_reset(Scsi_Cmnd* cmd);
3889 +int adpt_device_reset(Scsi_Cmnd* cmd);
3890 +
3891 +
3892 +/*
3893 + * Scsi_Host_Template (see hosts.h) for DPT - some fields
3894 + * to do with card config are filled in after the card is detected.
3895 + */
3896 +
3897 +#define DPT_DRIVER_NAME        "Adaptec I2O RAID"
3898 +
3899 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
3900 +#define DPT_I2O { \
3901 +       proc_info: adpt_proc_info,                                      \
3902 +       name: DPT_DRIVER_NAME,                                          \
3903 +       detect: adpt_detect,                                            \
3904 +       release: adpt_release,                                          \
3905 +       info: adpt_info,                                                \
3906 +       queuecommand: adpt_queue,                                       \
3907 +       eh_abort_handler: adpt_abort,                                   \
3908 +       eh_device_reset_handler: adpt_device_reset,                     \
3909 +       eh_bus_reset_handler: adpt_bus_reset,                           \
3910 +       eh_host_reset_handler: adpt_reset,                              \
3911 +       bios_param: adpt_bios_param,                                    \
3912 +       can_queue: MAX_TO_IOP_MESSAGES ,/* max simultaneous cmds      */\
3913 +       this_id: 7,                     /* scsi id of host adapter    */\
3914 +       sg_tablesize: 0,                /* max scatter-gather cmds    */\
3915 +       cmd_per_lun: 1,         /* cmds per lun (linked cmds) */\
3916 +       use_clustering: ENABLE_CLUSTERING,                              \
3917 +       use_new_eh_code: 1                                              \
3918 +}
3919 +
3920 +#else                          /* KERNEL_VERSION > 2.2.16 */
3921 +
3922 +#define DPT_I2O { \
3923 +       proc_info: adpt_proc_info,                                      \
3924 +       name: DPT_DRIVER_NAME,                                          \
3925 +       detect: adpt_detect,                                            \
3926 +       release: adpt_release,                                          \
3927 +       info: adpt_info,                                                \
3928 +       queuecommand: adpt_queue,                                       \
3929 +       eh_abort_handler: adpt_abort,                                   \
3930 +       eh_device_reset_handler: adpt_device_reset,                     \
3931 +       eh_bus_reset_handler: adpt_bus_reset,                           \
3932 +       eh_host_reset_handler: adpt_reset,                              \
3933 +       bios_param: adpt_bios_param,                                    \
3934 +       can_queue: MAX_TO_IOP_MESSAGES, /* max simultaneous cmds      */\
3935 +       this_id: 7,                     /* scsi id of host adapter    */\
3936 +       sg_tablesize: 0,                /* max scatter-gather cmds    */\
3937 +       cmd_per_lun: 1,         /* cmds per lun (linked cmds) */\
3938 +       use_clustering: ENABLE_CLUSTERING,                              \
3939 +       use_new_eh_code: 1,                                             \
3940 +       proc_name: "dpt_i2o"                                            \
3941 +}
3942 +#endif
3943 +
3944 +#ifndef HOSTS_C
3945 +
3946 +#include <linux/wait.h>
3947 +#include "dpti_i2o.h"
3948 +#include "dpti_ioctl.h"
3949 +
3950 +#define DPT_I2O_VERSION "2.4 Build 2"
3951 +#define DPT_VERSION     2
3952 +#define DPT_REVISION    '4'
3953 +#define DPT_SUBREVISION '2'
3954 +#define DPT_BETA       ""
3955 +#define DPT_MONTH      7 
3956 +#define DPT_DAY        15
3957 +#define DPT_YEAR        (2001-1980)
3958 +
3959 +#define DPT_DRIVER     "dpt_i2o"
3960 +#define DPTI_I2O_MAJOR (151)
3961 +#define DPT_ORGANIZATION_ID (0x1B)        /* For Private Messages */
3962 +#define DPTI_MAX_HBA   (16)
3963 +#define MAX_CHANNEL     (5)    // Maximum Channel # Supported
3964 +#define MAX_ID         (128)   // Maximum Target ID Supported
3965 +
3966 +#define REPLY_FRAME_SIZE  (17)
3967 +#define SG_LIST_ELEMENTS  (56)
3968 +#define MAX_MESSAGE_SIZE  (512)
3969 +
3970 +#define EMPTY_QUEUE           0xffffffff
3971 +#define I2O_INTERRUPT_PENDING_B   (0x08)
3972 +
3973 +#define PCI_DPT_VENDOR_ID         (0x1044)     // DPT PCI Vendor ID
3974 +#define PCI_DPT_DEVICE_ID         (0xA501)     // DPT PCI I2O Device ID
3975 +#define PCI_DPT_RAPTOR_DEVICE_ID  (0xA511)     
3976 +
3977 +//#define REBOOT_NOTIFIER 1
3978 +/* Debugging macro from Linux Device Drivers - Rubini */
3979 +#undef PDEBUG
3980 +#ifdef DEBUG
3981 +//TODO add debug level switch
3982 +#  define PDEBUG(fmt, args...)  printk(KERN_DEBUG "dpti: " fmt, ##args)
3983 +#  define PDEBUGV(fmt, args...) printk(KERN_DEBUG "dpti: " fmt, ##args)
3984 +#else
3985 +# define PDEBUG(fmt, args...) /* not debugging: nothing */
3986 +# define PDEBUGV(fmt, args...) /* not debugging: nothing */
3987 +#endif
3988 +
3989 +#define PERROR(fmt, args...) printk(KERN_ERR fmt, ##args)
3990 +#define PWARN(fmt, args...) printk(KERN_WARNING fmt, ##args)
3991 +#define PINFO(fmt, args...) printk(KERN_INFO fmt, ##args)
3992 +#define PCRIT(fmt, args...) printk(KERN_CRIT fmt, ##args)
3993 +
3994 +#define SHUTDOWN_SIGS  (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
3995 +
3996 +// Command timeouts
3997 +#define FOREVER                        (0)
3998 +#define TMOUT_INQUIRY          (20)
3999 +#define TMOUT_FLUSH            (360/45)
4000 +#define TMOUT_ABORT            (30)
4001 +#define TMOUT_SCSI             (300)
4002 +#define TMOUT_IOPRESET         (360)
4003 +#define TMOUT_GETSTATUS                (15)
4004 +#define TMOUT_INITOUTBOUND     (15)
4005 +#define TMOUT_LCT              (360)
4006 +
4007 +#define I2O_SCSI_DSC_MASK                   0xFF00
4008 +#define I2O_SCSI_DSC_SUCCESS                0x0000
4009 +#define I2O_SCSI_DSC_REQUEST_ABORTED        0x0200
4010 +#define I2O_SCSI_DSC_UNABLE_TO_ABORT        0x0300
4011 +#define I2O_SCSI_DSC_COMPLETE_WITH_ERROR    0x0400
4012 +#define I2O_SCSI_DSC_ADAPTER_BUSY           0x0500
4013 +#define I2O_SCSI_DSC_REQUEST_INVALID        0x0600
4014 +#define I2O_SCSI_DSC_PATH_INVALID           0x0700
4015 +#define I2O_SCSI_DSC_DEVICE_NOT_PRESENT     0x0800
4016 +#define I2O_SCSI_DSC_UNABLE_TO_TERMINATE    0x0900
4017 +#define I2O_SCSI_DSC_SELECTION_TIMEOUT      0x0A00
4018 +#define I2O_SCSI_DSC_COMMAND_TIMEOUT        0x0B00
4019 +#define I2O_SCSI_DSC_MR_MESSAGE_RECEIVED    0x0D00
4020 +#define I2O_SCSI_DSC_SCSI_BUS_RESET         0x0E00
4021 +#define I2O_SCSI_DSC_PARITY_ERROR_FAILURE   0x0F00
4022 +#define I2O_SCSI_DSC_AUTOSENSE_FAILED       0x1000
4023 +#define I2O_SCSI_DSC_NO_ADAPTER             0x1100
4024 +#define I2O_SCSI_DSC_DATA_OVERRUN           0x1200
4025 +#define I2O_SCSI_DSC_UNEXPECTED_BUS_FREE    0x1300
4026 +#define I2O_SCSI_DSC_SEQUENCE_FAILURE       0x1400
4027 +#define I2O_SCSI_DSC_REQUEST_LENGTH_ERROR   0x1500
4028 +#define I2O_SCSI_DSC_PROVIDE_FAILURE        0x1600
4029 +#define I2O_SCSI_DSC_BDR_MESSAGE_SENT       0x1700
4030 +#define I2O_SCSI_DSC_REQUEST_TERMINATED     0x1800
4031 +#define I2O_SCSI_DSC_IDE_MESSAGE_SENT       0x3300
4032 +#define I2O_SCSI_DSC_RESOURCE_UNAVAILABLE   0x3400
4033 +#define I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT   0x3500
4034 +#define I2O_SCSI_DSC_MESSAGE_RECEIVED       0x3600
4035 +#define I2O_SCSI_DSC_INVALID_CDB            0x3700
4036 +#define I2O_SCSI_DSC_LUN_INVALID            0x3800
4037 +#define I2O_SCSI_DSC_SCSI_TID_INVALID       0x3900
4038 +#define I2O_SCSI_DSC_FUNCTION_UNAVAILABLE   0x3A00
4039 +#define I2O_SCSI_DSC_NO_NEXUS               0x3B00
4040 +#define I2O_SCSI_DSC_SCSI_IID_INVALID       0x3C00
4041 +#define I2O_SCSI_DSC_CDB_RECEIVED           0x3D00
4042 +#define I2O_SCSI_DSC_LUN_ALREADY_ENABLED    0x3E00
4043 +#define I2O_SCSI_DSC_BUS_BUSY               0x3F00
4044 +#define I2O_SCSI_DSC_QUEUE_FROZEN           0x4000
4045 +
4046 +#ifndef TRUE
4047 +#define TRUE                  1
4048 +#define FALSE                 0
4049 +#endif
4050 +
4051 +#define HBA_FLAGS_INSTALLED_B       0x00000001 // Adapter Was Installed
4052 +#define HBA_FLAGS_BLINKLED_B        0x00000002 // Adapter In Blink LED State
4053 +#define HBA_FLAGS_IN_RESET     0x00000040      /* in reset */
4054 +#define HBA_HOSTRESET_FAILED   0x00000080      /* adpt_resethost failed */
4055 +
4056 +
4057 +// Device state flags
4058 +#define DPTI_DEV_UNSCANNED 0x01
4059 +#define DPTI_DEV_RESET    0x02
4060 +#define DPTI_DEV_OFFLINE   0x04
4061 +
4062 +
4063 +struct adpt_device {
4064 +       struct adpt_device* next_lun;
4065 +       u32     flags;
4066 +       u32     type;
4067 +       u32     capacity;
4068 +       u32     block_size;
4069 +       u8      scsi_channel;
4070 +       u8      scsi_id;
4071 +       u8      scsi_lun;
4072 +       u8      state;
4073 +       u16     tid;
4074 +       struct i2o_device* pI2o_dev;
4075 +       Scsi_Device *pScsi_dev;
4076 +};
4077 +
4078 +struct adpt_channel {
4079 +       struct adpt_device* device[MAX_ID];     /* used as an array of 128 scsi ids */
4080 +       u8      scsi_id;
4081 +       u8      type;
4082 +       u16     tid;
4083 +       u32     state;
4084 +       struct i2o_device* pI2o_dev;
4085 +};
4086 +
4087 +// HBA state flags
4088 +#define DPTI_STATE_RESET       (0x01)
4089 +#define DPTI_STATE_IOCTL       (0x02)
4090 +
4091 +typedef struct _adpt_hba {
4092 +       struct _adpt_hba *next;
4093 +       struct pci_dev *pDev;
4094 +       struct Scsi_Host *host;
4095 +       u32 state;
4096 +       spinlock_t state_lock;
4097 +       int unit;
4098 +       int host_no;            /* SCSI host number */
4099 +       u8 initialized;
4100 +       u8 in_use;              /* is the management node open*/
4101 +
4102 +       char name[32];
4103 +       char detail[55];
4104 +
4105 +       caddr_t base_addr_virt;
4106 +       caddr_t msg_addr_virt;
4107 +       caddr_t base_addr_phys;
4108 +       ulong  post_port;
4109 +       ulong  reply_port;
4110 +       ulong  irq_mask;
4111 +       u16  post_count;
4112 +       u32  post_fifo_size;
4113 +       u32  reply_fifo_size;
4114 +       u32* reply_pool;
4115 +       u32  sg_tablesize;      // Scatter/Gather List Size.       
4116 +       u8  top_scsi_channel;
4117 +       u8  top_scsi_id;
4118 +       u8  top_scsi_lun;
4119 +
4120 +       i2o_status_block* status_block;
4121 +       i2o_hrt* hrt;
4122 +       i2o_lct* lct;
4123 +       unsigned lct_size;
4124 +       struct i2o_device* devices;
4125 +       struct adpt_channel channel[MAX_CHANNEL];
4126 +
4127 +       caddr_t FwDebugBuffer_P;        // Virtual Address Of FW Debug Buffer
4128 +       u32 FwDebugBufferSize;  // FW Debug Buffer Size In Bytes
4129 +       u32* FwDebugStrLength_P;        // Virtual Addr Of FW Debug String Len
4130 +       volatile u32* FwDebugFlags_P;   // Virtual Address Of FW Debug Flags 
4131 +       volatile u8* FwDebugBLEDflag_P; // Virtual Addr Of FW Debug BLED
4132 +       volatile u8* FwDebugBLEDvalue_P;        // Virtual Addr Of FW Debug BLED
4133 +       u32 FwDebugFlags;
4134 +} adpt_hba;
4135 +
4136 +struct sg_simple_element {
4137 +   u32  flag_count;
4138 +   u32 addr_bus;
4139 +}; 
4140 +
4141 +/*
4142 + * Function Prototypes
4143 + */
4144 +
4145 +void adpt_i2o_sys_shutdown(void);
4146 +int adpt_init(void);
4147 +int adpt_i2o_build_sys_table(void);
4148 +void adpt_isr(int irq, void *dev_id, struct pt_regs *regs);
4149 +#ifdef REBOOT_NOTIFIER
4150 +int adpt_reboot_event(struct notifier_block *n, unsigned long code, void *p);
4151 +#endif
4152 +
4153 +void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
4154 +int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
4155 +                       int group, int field, void *buf, int buflen);
4156 +const char *adpt_i2o_get_class_name(int class);
4157 +int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
4158 +                 void *opblk, int oplen, void *resblk, int reslen);
4159 +int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
4160 +int adpt_i2o_lct_get(adpt_hba* pHba);
4161 +int adpt_i2o_parse_lct(adpt_hba* pHba);
4162 +int adpt_i2o_activate_hba(adpt_hba* pHba);
4163 +int adpt_i2o_online_controller(adpt_hba* pHba);
4164 +int adpt_i2o_enable_hba(adpt_hba* pHba);
4165 +int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d);
4166 +s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len);
4167 +s32 adpt_i2o_quiesce_hba(adpt_hba* pHba);
4168 +s32 adpt_i2o_status_get(adpt_hba* pHba);
4169 +s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
4170 +s32 adpt_i2o_hrt_get(adpt_hba* pHba);
4171 +s32 adpt_i2o_parse_hrt(adpt_hba* pHba);
4172 +s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* dptdevice);
4173 +s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd);
4174 +s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht);
4175 +s32 adpt_hba_reset(adpt_hba* pHba);
4176 +s32 adpt_scsi_bus_reset(adpt_hba* pHba, u32 chan);
4177 +s32 adpt_i2o_reset_hba(adpt_hba* pHba);
4178 +s32 adpt_scsi_device_reset(adpt_hba* pHba, u8 chan, u8 id, u8 lun);
4179 +s32 adpt_reinit(adpt_hba* pHba);
4180 +s32 adpt_rescan(adpt_hba* pHba);
4181 +s32 adpt_i2o_reparse_lct(adpt_hba* pHba);
4182 +s32 adpt_send_nop(adpt_hba*pHba,u32 m);
4183 +void adpt_i2o_delete_hba(adpt_hba* pHba);
4184 +void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist);
4185 +int adpt_read_capacity(adpt_hba* pHba, struct adpt_device* d);
4186 +void adpt_inquiry(adpt_hba* pHba);
4187 +void adpt_fail_posted_scbs(adpt_hba* pHba);
4188 +
4189 +int adpt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
4190 +int adpt_open(struct inode *inode, struct file *file);
4191 +int adpt_close(struct inode *inode, struct file *file);
4192 +
4193 +void adpt_start_complete_queue(void);
4194 +void adpt_done_cmds_complete(void * data);
4195 +void adpt_queue_cmd_complete(Scsi_Cmnd *cmd);
4196 +
4197 +#ifdef DEBUG
4198 +static void adpt_delay(int millisec);
4199 +#endif
4200 +
4201 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
4202 +struct pci_dev* adpt_pci_find_device(unsigned int vendor, struct pci_dev* from);
4203 +#endif
4204 +
4205 +#if defined __ia64__ 
4206 +void adpt_ia64_info(sysInfo_S* si);
4207 +#endif
4208 +#if defined __sparc__ 
4209 +void adpt_sparc_info(sysInfo_S* si);
4210 +#endif
4211 +#if defined __alpha__ 
4212 +void adpt_sparc_info(sysInfo_S* si);
4213 +#endif
4214 +#if defined __i386__
4215 +void adpt_i386_info(sysInfo_S* si);
4216 +#endif
4217 +
4218 +#define PRINT_BUFFER_SIZE     512
4219 +
4220 +#define HBA_FLAGS_DBG_FLAGS_MASK         0xffff0000    // Mask for debug flags
4221 +#define HBA_FLAGS_DBG_KERNEL_PRINT_B     0x00010000    // Kernel Debugger Print
4222 +#define HBA_FLAGS_DBG_FW_PRINT_B         0x00020000    // Firmware Debugger Print
4223 +#define HBA_FLAGS_DBG_FUNCTION_ENTRY_B   0x00040000    // Function Entry Point
4224 +#define HBA_FLAGS_DBG_FUNCTION_EXIT_B    0x00080000    // Function Exit
4225 +#define HBA_FLAGS_DBG_ERROR_B            0x00100000    // Error Conditions
4226 +#define HBA_FLAGS_DBG_INIT_B             0x00200000    // Init Prints
4227 +#define HBA_FLAGS_DBG_OS_COMMANDS_B      0x00400000    // OS Command Info
4228 +#define HBA_FLAGS_DBG_SCAN_B             0x00800000    // Device Scan
4229 +
4230 +#define FW_DEBUG_STR_LENGTH_OFFSET 0
4231 +#define FW_DEBUG_FLAGS_OFFSET      4
4232 +#define FW_DEBUG_BLED_OFFSET       8
4233 +
4234 +#define FW_DEBUG_FLAGS_NO_HEADERS_B    0x01
4235 +#endif                         /* !HOSTS_C */
4236 +#endif                         /* _DPT_H */
4237 --- /dev/null   Sat Apr 14 07:06:21 2001
4238 +++ linux/drivers/scsi/dpti2oscsi2.c    Wed Jul 18 14:31:28 2001
4239 @@ -0,0 +1,239 @@
4240 +
4241 +/*
4242 + * NOTE:  You must include i2obscsi.h before including this file
4243 + */
4244 +
4245 +/*
4246 + *      SCSI opcodes
4247 + */
4248 +/*
4249 + * i2oscsi2dixkxfer is a table of data transfer direction for SCSI Disk 
4250 + * device commands.  The table indicates if the command will transfer 
4251 + * data in (from device to system) or data out (from system to device)
4252 + * NOSUPPORT indicates the command is not used for a disk device
4253 + */
4254 +
4255 +/* #define     DATAIN  I2O_SCB_FLAG_XFER_FROM_DEVICE */
4256 +#define        DATAIN  0x01
4257 +/* #define     DATAOUT I2O_SCB_FLAG_XFER_TO_DEVICE */
4258 +#define        DATAOUT 0x02
4259 +/* #define     NODATA  I2O_SCB_FLAG_NO_DATA_XFER */
4260 +#define        NODATA  0x00
4261 +#define        NOSUPPORT       0xFF
4262 +
4263 +unsigned char i2oscsi2diskxfer[] = {
4264 +
4265 +
4266 +/* TEST_UNIT_READY       0x00 */ NODATA,
4267 +/* REZERO_UNIT           0x01 */ NODATA,
4268 +/*                      0x02 */ NOSUPPORT,
4269 +/* REQUEST_SENSE         0x03 */ DATAIN,
4270 +/* FORMAT_UNIT           0x04 */ DATAOUT,
4271 +/* READ_BLOCK_LIMITS     0x05 */ DATAIN,
4272 +/*                      0x06 */ NOSUPPORT,
4273 +/* REASSIGN_BLOCKS       0x07 */ DATAOUT,
4274 +/* READ_6                0x08 */ DATAIN,
4275 +
4276 +/*                      0x09 */ NOSUPPORT,
4277 +
4278 +/* WRITE_6               0x0a */ DATAOUT,
4279 +/* SEEK_6                0x0b */ NODATA,
4280 +/*                      0x0c */ NOSUPPORT,
4281 +/*                      0x0d */ NOSUPPORT,
4282 +/*                      0x0e */ NOSUPPORT,
4283 +/* READ_REVERSE          0x0f */ NOSUPPORT,
4284 +/* WRITE_FILEMARKS       0x10 */ NODATA,
4285 +/* SPACE                 0x11 */ NOSUPPORT,
4286 +/* INQUIRY               0x12 */ DATAIN,
4287 +/*                      0x13 */ NOSUPPORT,
4288 +/* RECOVER_BUFFERED_DATA 0x14 */ NOSUPPORT,
4289 +/* MODE_SELECT           0x15 */ DATAOUT,
4290 +/* RESERVE               0x16 */ DATAOUT,
4291 +/* RELEASE               0x17 */ NODATA,
4292 +/* COPY                  0x18 */ DATAOUT,
4293 +       /* ERASE                 0x19 */ NOSUPPORT,
4294 +       /* NODATA if supported */
4295 +/* MODE_SENSE            0x1a */ DATAIN,
4296 +/* START_STOP            0x1b */ NODATA,
4297 +/* RECEIVE_DIAGNOSTIC    0x1c */ DATAIN,
4298 +/* SEND_DIAGNOSTIC       0x1d */ DATAOUT,
4299 +/* ALLOW_MEDIUM_REMOVAL  0x1e */ NODATA,
4300 +
4301 +/*                      0x1f */ NOSUPPORT,
4302 +/*                      0x20 */ NOSUPPORT,
4303 +/*                      0x21 */ NOSUPPORT,
4304 +/*                      0x22 */ NOSUPPORT,
4305 +/*                      0x23 */ NOSUPPORT,
4306 +
4307 +/* SET_WINDOW            0x24 */ DATAOUT,
4308 +/* READ_CAPACITY         0x25 */ DATAIN,
4309 +
4310 +/*                      0x26 */ NOSUPPORT,
4311 +/*                      0x27 */ NOSUPPORT,
4312 +
4313 +/* READ_10               0x28 */ DATAIN,
4314 +
4315 +/*                      0x29 */ NOSUPPORT,
4316 +
4317 +/* WRITE_10              0x2a */ DATAOUT,
4318 +/* SEEK_10               0x2b */ NODATA,
4319 +
4320 +/*                      0x2c */ NOSUPPORT,
4321 +/*                      0x2d */ NOSUPPORT,
4322 +
4323 +/* WRITE_VERIFY          0x2e */ DATAOUT,
4324 +/* VERIFY                0x2f */ NODATA,
4325 +/* SEARCH_HIGH           0x30 */ DATAOUT,
4326 +/* SEARCH_EQUAL          0x31 */ DATAOUT,
4327 +/* SEARCH_LOW            0x32 */ DATAOUT,
4328 +/* SET_LIMITS            0x33 */ NODATA,
4329 +/* PRE_FETCH             0x34 */ DATAIN,
4330 +/* SYNCHRONIZE_CACHE     0x35 */ NODATA,
4331 +/* LOCK_UNLOCK_CACHE     0x36 */ NODATA,
4332 +/* READ_DEFECT_DATA      0x37 */ DATAIN,
4333 +/* MEDIUM_SCAN           0x38 */ DATAOUT,
4334 +/* COMPARE               0x39 */ DATAOUT,
4335 +/* COPY_VERIFY           0x3a */ DATAOUT,
4336 +/* WRITE_BUFFER          0x3b */ DATAOUT,
4337 +/* READ_BUFFER           0x3c */ DATAIN,
4338 +/* UPDATE_BLOCK          0x3d */ DATAOUT,
4339 +/* READ_LONG             0x3e */ DATAIN,
4340 +/* WRITE_LONG            0x3f */ DATAOUT,
4341 +/* CHANGE_DEFINITION     0x40 */ DATAOUT,
4342 +/* WRITE_SAME            0x41 */ DATAOUT,
4343 +
4344 +/*                      0x42 */ DATAIN,
4345 +
4346 +/* READ_TOC              0x43 */ DATAIN,
4347 +
4348 +/*                      0x44 */ DATAIN,
4349 +/*                      0x45 */ NOSUPPORT,
4350 +/*                      0x46 */ NOSUPPORT,
4351 +/*                      0x47 */ NOSUPPORT,
4352 +/*                      0x48 */ NOSUPPORT,
4353 +/*                      0x49 */ NOSUPPORT,
4354 +/*                      0x4a */ NOSUPPORT,
4355 +/*                      0x4b */ NOSUPPORT,
4356 +
4357 +/* LOG_SELECT            0x4c */ DATAOUT,
4358 +/* LOG_SENSE             0x4d */ DATAIN,
4359 +
4360 +/*                      0x4e */ NOSUPPORT,
4361 +/*                      0x4f */ NOSUPPORT,
4362 +/*                      0x50 */ NOSUPPORT,
4363 +/*                      0x51 */ DATAIN,
4364 +/*                      0x52 */ DATAIN,
4365 +/*                      0x53 */ DATAOUT,
4366 +/*                      0x54 */ NOSUPPORT,
4367 +
4368 +/* MODE_SELECT_10        0x55 */ DATAOUT,
4369 +
4370 +/*                      0x56 */ NODATA,
4371 +/*                      0x57 */ NODATA,
4372 +/*                      0x58 */ NOSUPPORT,
4373 +/*                      0x59 */ NOSUPPORT,
4374 +
4375 +/* MODE_SENSE_10         0x5a */ DATAIN,
4376 +
4377 +/*                      0x5b */ DATAIN,
4378 +/*                      0x5c */ DATAIN,
4379 +/*                      0x5d */ NOSUPPORT,
4380 +/*                      0x5e */ NOSUPPORT,
4381 +/*                      0x5f */ NOSUPPORT,
4382 +
4383 +/* assign NOSUPPORT for 0x60 - 0x9f */
4384 +       /* 0x60 - 0x6f */
4385 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4386 +       NOSUPPORT, NOSUPPORT,
4387 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4388 +       NOSUPPORT, NOSUPPORT,
4389 +       /* 0x70 - 0x7f */
4390 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4391 +       NOSUPPORT, NOSUPPORT,
4392 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4393 +       NOSUPPORT, NOSUPPORT,
4394 +       /* 0x80 - 0x8f */
4395 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4396 +       NOSUPPORT, NOSUPPORT,
4397 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4398 +       NOSUPPORT, NOSUPPORT,
4399 +       /* 0x90 - 0x9f */
4400 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4401 +       NOSUPPORT, NOSUPPORT,
4402 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4403 +       NOSUPPORT, NOSUPPORT,
4404 +
4405 +/*                      0xa0 */ NOSUPPORT,
4406 +/*                      0xa1 */ NOSUPPORT,
4407 +/*                      0xa2 */ NOSUPPORT,
4408 +/*                      0xa3 */ NOSUPPORT,
4409 +/*                      0xa4 */ NOSUPPORT,
4410 +
4411 +/* MOVE_MEDIUM           0xa5 */ NODATA,
4412 +
4413 +/*                      0xa6 */ NOSUPPORT,
4414 +/*                      0xa7 */ NOSUPPORT,
4415 +
4416 +/* READ_12               0xa8 */ DATAIN,
4417 +
4418 +/*                      0xa9 */ NOSUPPORT,
4419 +
4420 +/* WRITE_12              0xaa */ DATAOUT,
4421 +
4422 +/*                      0xab */ NOSUPPORT,
4423 +/*                      0xac */ NOSUPPORT,
4424 +/*                      0xad */ NOSUPPORT,
4425 +
4426 +/* WRITE_VERIFY_12       0xae */ DATAOUT,
4427 +
4428 +/*                      0xaf */ NOSUPPORT,
4429 +
4430 +/* SEARCH_HIGH_12        0xb0 */ DATAOUT,
4431 +/* SEARCH_EQUAL_12       0xb1 */ DATAOUT,
4432 +/* SEARCH_LOW_12         0xb2 */ DATAOUT,
4433 +
4434 +/*                      0xb3 */ NOSUPPORT,
4435 +/*                      0xb4 */ NOSUPPORT,
4436 +/*                      0xb5 */ NOSUPPORT,
4437 +
4438 +/* SEND_VOLUME_TAG       0xb6 */ DATAOUT,
4439 +
4440 +/*                      0xb7 */ NOSUPPORT,
4441 +
4442 +/* READ_ELEMENT_STATUS   0xb8 */ DATAIN,
4443 +
4444 +/*                      0xb9 */ NOSUPPORT,
4445 +/*                      0xba */ NOSUPPORT,
4446 +/*                      0xbb */ DATAOUT,
4447 +/*                      0xbc */ NOSUPPORT,
4448 +/*                      0xbd */ DATAIN,
4449 +/*                      0xbe */ NOSUPPORT,
4450 +/*                      0xbf */ NOSUPPORT,
4451 +
4452 +/* assign NOSUPPORT for 0xc0 - 0xdf */
4453 +       /* 0xc0 - 0xcf */
4454 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4455 +       NOSUPPORT, NOSUPPORT,
4456 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4457 +       NOSUPPORT, NOSUPPORT,
4458 +       /* 0xd0 - 0xdf */
4459 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4460 +       NOSUPPORT, NOSUPPORT,
4461 +       NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4462 +       NOSUPPORT, NOSUPPORT,
4463 +
4464 +/*                      0xe0 */ NOSUPPORT,
4465 +/*                      0xe1 */ NOSUPPORT,
4466 +/*                      0xe2 */ NOSUPPORT,
4467 +/*                      0xe3 */ NOSUPPORT,
4468 +/*                      0xe4 */ NOSUPPORT,
4469 +/*                      0xe5 */ NOSUPPORT,
4470 +/*                      0xe6 */ NOSUPPORT,
4471 +/*                      0xe7 */ NOSUPPORT,
4472 +/*                      0xe8 */ NOSUPPORT,
4473 +/*                      0xe9 */ NOSUPPORT,
4474 +
4475 +/* WRITE_LONG_2          0xea */ DATAOUT
4476 +};
4477 +
4478 +#define        DISKXFERTBLSIZE sizeof(i2oscsi2diskxfer)
4479 --- /dev/null   Sat Apr 14 07:06:21 2001
4480 +++ linux/drivers/scsi/dpti_ioctl.h     Wed Jul 18 14:31:28 2001
4481 @@ -0,0 +1,139 @@
4482 +/***************************************************************************
4483 +                          dpti_ioctl.h  -  description
4484 +                             -------------------
4485 +    begin                : Thu Sep 7 2000
4486 +    copyright            : (C) 2001 by Adaptec
4487 +    email                : deanna_bonds@adaptec.com
4488 +
4489 +    See README.dpti for history, notes, license info, and credits
4490 + ***************************************************************************/
4491 +
4492 +/***************************************************************************
4493 + *                                                                         *
4494 + *   This program is free software; you can redistribute it and/or modify  *
4495 + *   it under the terms of the GNU General Public License as published by  *
4496 + *   the Free Software Foundation; either version 2 of the License, or     *
4497 + *   (at your option) any later version.                                   *
4498 + *                                                                         *
4499 + ***************************************************************************/
4500 +
4501 +/***************************************************************************
4502 + * This file is generated from  osd_unix.h                                 *
4503 + * *************************************************************************/
4504 +
4505 +#ifndef _dpti_ioctl_h
4506 +#define _dpti_ioctl_h
4507 +
4508 +// IOCTL interface commands
4509 +
4510 +#ifndef _IOWR
4511 +# define _IOWR(x,y,z)  (((x)<<8)|y)
4512 +#endif
4513 +#ifndef _IOW
4514 +# define _IOW(x,y,z)   (((x)<<8)|y)
4515 +#endif
4516 +#ifndef _IOR
4517 +# define _IOR(x,y,z)   (((x)<<8)|y)
4518 +#endif
4519 +#ifndef _IO
4520 +# define _IO(x,y)      (((x)<<8)|y)
4521 +#endif
4522 +/* EATA PassThrough Command    */
4523 +#define EATAUSRCMD      _IOWR('D',65,EATA_CP)
4524 +/* Set Debug Level If Enabled  */
4525 +#define DPT_DEBUG       _IOW('D',66,int)
4526 +/* Get Signature Structure     */
4527 +#define DPT_SIGNATURE   _IOR('D',67,dpt_sig_S)
4528 +#if defined __bsdi__
4529 +#define DPT_SIGNATURE_PACKED   _IOR('D',67,dpt_sig_S_Packed)
4530 +#endif
4531 +/* Get Number Of DPT Adapters  */
4532 +#define DPT_NUMCTRLS    _IOR('D',68,int)
4533 +/* Get Adapter Info Structure  */
4534 +#define DPT_CTRLINFO    _IOR('D',69,CtrlInfo)
4535 +/* Get Statistics If Enabled   */
4536 +#define DPT_STATINFO    _IO('D',70)
4537 +/* Clear Stats If Enabled      */
4538 +#define DPT_CLRSTAT     _IO('D',71)
4539 +/* Get System Info Structure   */
4540 +#define DPT_SYSINFO     _IOR('D',72,sysInfo_S)
4541 +/* Set Timeout Value           */
4542 +#define DPT_TIMEOUT     _IO('D',73)
4543 +/* Get config Data             */
4544 +#define DPT_CONFIG      _IO('D',74)
4545 +/* Get Blink LED Code          */
4546 +#define DPT_BLINKLED    _IOR('D',75,int)
4547 +/* Get Statistical information (if available) */
4548 +#define DPT_STATS_INFO        _IOR('D',80,STATS_DATA)
4549 +/* Clear the statistical information          */
4550 +#define DPT_STATS_CLEAR       _IO('D',81)
4551 +/* Get Performance metrics */
4552 +#define DPT_PERF_INFO        _IOR('D',82,dpt_perf_t)
4553 +/* Send an I2O command */
4554 +#define I2OUSRCMD      _IO('D',76)
4555 +/* Inform driver to re-acquire LCT information */
4556 +#define I2ORESCANCMD   _IO('D',77)
4557 +/* Inform driver to reset adapter */
4558 +#define I2ORESETCMD    _IO('D',78)
4559 +/* See if the target is mounted */
4560 +#define DPT_TARGET_BUSY        _IOR('D',79, TARGET_BUSY_T)
4561 +
4562 +
4563 +  /* Structure Returned From Get Controller Info                             */
4564 +
4565 +typedef struct {
4566 +       uCHAR    state;            /* Operational state               */
4567 +       uCHAR    id;               /* Host adapter SCSI id            */
4568 +       int      vect;             /* Interrupt vector number         */
4569 +       int      base;             /* Base I/O address                */
4570 +       int      njobs;            /* # of jobs sent to HA            */
4571 +       int      qdepth;           /* Controller queue depth.         */
4572 +       int      wakebase;         /* mpx wakeup base index.          */
4573 +       uLONG    SGsize;           /* Scatter/Gather list size.       */
4574 +       unsigned heads;            /* heads for drives on cntlr.      */
4575 +       unsigned sectors;          /* sectors for drives on cntlr.    */
4576 +       uCHAR    do_drive32;       /* Flag for Above 16 MB Ability    */
4577 +       uCHAR    BusQuiet;         /* SCSI Bus Quiet Flag             */
4578 +       char     idPAL[4];         /* 4 Bytes Of The ID Pal           */
4579 +       uCHAR    primary;          /* 1 For Primary, 0 For Secondary  */
4580 +       uCHAR    eataVersion;      /* EATA Version                    */
4581 +       uLONG    cpLength;         /* EATA Command Packet Length      */
4582 +       uLONG    spLength;         /* EATA Status Packet Length       */
4583 +       uCHAR    drqNum;           /* DRQ Index (0,5,6,7)             */ 
4584 +       uCHAR    flag1;            /* EATA Flags 1 (Byte 9)           */
4585 +       uCHAR    flag2;            /* EATA Flags 2 (Byte 30)          */
4586 +} CtrlInfo;
4587 +
4588 +typedef struct {
4589 +       uSHORT length;          // Remaining length of this
4590 +       uSHORT drvrHBAnum;      // Relative HBA # used by the driver
4591 +       uLONG baseAddr;         // Base I/O address
4592 +       uSHORT blinkState;      // Blink LED state (0=Not in blink LED)
4593 +       uCHAR pciBusNum;        // PCI Bus # (Optional)
4594 +       uCHAR pciDeviceNum;     // PCI Device # (Optional)
4595 +       uSHORT hbaFlags;        // Miscellaneous HBA flags
4596 +       uSHORT Interrupt;       // Interrupt set for this device.
4597 +#   if (defined(_DPT_ARC))
4598 +       uLONG baseLength;
4599 +       ADAPTER_OBJECT *AdapterObject;
4600 +       LARGE_INTEGER DmaLogicalAddress;
4601 +       PVOID DmaVirtualAddress;
4602 +       LARGE_INTEGER ReplyLogicalAddress;
4603 +       PVOID ReplyVirtualAddress;
4604 +#   else
4605 +       uLONG reserved1;        // Reserved for future expansion
4606 +       uLONG reserved2;        // Reserved for future expansion
4607 +       uLONG reserved3;        // Reserved for future expansion
4608 +#   endif
4609 +} drvrHBAinfo_S;
4610 +
4611 +typedef struct TARGET_BUSY
4612 +{
4613 +  uLONG channel;
4614 +  uLONG id;
4615 +  uLONG lun;
4616 +  uLONG isBusy;
4617 +} TARGET_BUSY_T;
4618 +
4619 +#endif
4620 +
4621 --- /dev/null   Sat Apr 14 07:06:21 2001
4622 +++ linux/drivers/scsi/dptsig.h Wed Jul 18 14:31:28 2001
4623 @@ -0,0 +1,339 @@
4624 +/*     BSDI dptsig.h,v 1.7 1998/06/03 19:15:00 karels Exp      */
4625 +
4626 +/*
4627 + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
4628 + * All rights reserved.
4629 + *
4630 + * Redistribution and use in source form, with or without modification, are
4631 + * permitted provided that redistributions of source code must retain the
4632 + * above copyright notice, this list of conditions and the following disclaimer.
4633 + *
4634 + * This software is provided `as is' by Distributed Processing Technology and
4635 + * any express or implied warranties, including, but not limited to, the
4636 + * implied warranties of merchantability and fitness for a particular purpose,
4637 + * are disclaimed. In no event shall Distributed Processing Technology be
4638 + * liable for any direct, indirect, incidental, special, exemplary or
4639 + * consequential damages (including, but not limited to, procurement of
4640 + * substitute goods or services; loss of use, data, or profits; or business
4641 + * interruptions) however caused and on any theory of liability, whether in
4642 + * contract, strict liability, or tort (including negligence or otherwise)
4643 + * arising in any way out of the use of this driver software, even if advised
4644 + * of the possibility of such damage.
4645 + *
4646 + */
4647 +
4648 +#ifndef __DPTSIG_H_
4649 +#define __DPTSIG_H_
4650 +#ifdef _SINIX_ADDON
4651 +#include "dpt.h"
4652 +#endif
4653 +/* DPT SIGNATURE SPEC AND HEADER FILE                           */
4654 +/* Signature Version 1 (sorry no 'A')                           */
4655 +
4656 +/* to make sure we are talking the same size under all OS's     */
4657 +typedef unsigned char sigBYTE;
4658 +typedef unsigned short sigWORD;
4659 +#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32))
4660 +typedef uint32_t sigLONG;
4661 +#else
4662 +typedef unsigned long sigLONG;
4663 +#endif
4664 +
4665 +/*
4666 + * use sigWORDLittleEndian for:
4667 + *  dsCapabilities
4668 + *  dsDeviceSupp
4669 + *  dsAdapterSupp
4670 + *  dsApplication
4671 + * use sigLONGLittleEndian for:
4672 + *      dsOS
4673 + * so that the sig can be standardised to Little Endian
4674 + */
4675 +#if (defined(_DPT_BIG_ENDIAN))
4676 +# define sigWORDLittleEndian(x) ((((x)&0xFF)<<8)|(((x)>>8)&0xFF))
4677 +# define sigLONGLittleEndian(x) \
4678 +        ((((x)&0xFF)<<24) |             \
4679 +         (((x)&0xFF00)<<8) |    \
4680 +         (((x)&0xFF0000L)>>8) | \
4681 +         (((x)&0xFF000000L)>>24))
4682 +#else
4683 +# define sigWORDLittleEndian(x) (x)
4684 +# define sigLONGLittleEndian(x) (x)
4685 +#endif
4686 +
4687 +/* must make sure the structure is not word or double-word aligned      */
4688 +/* ---------------------------------------------------------------      */
4689 +/* Borland will ignore the following pragma:                            */
4690 +/* Word alignment is OFF by default.  If in the, IDE make               */
4691 +/* sure that Options | Compiler | Code Generation | Word Alignment      */
4692 +/* is not checked.  If using BCC, do not use the -a option.             */
4693 +
4694 +#ifndef NO_PACK
4695 +#if defined (_DPT_AIX)
4696 +#pragma options align=packed
4697 +#else
4698 +#pragma pack(1)
4699 +#endif  /* aix */
4700 +#endif
4701 +/* For the Macintosh */
4702 +#if STRUCTALIGNMENTSUPPORTED
4703 +#pragma options align=mac68k
4704 +#endif
4705 +
4706 +
4707 +/* Current Signature Version - sigBYTE dsSigVersion; */
4708 +/* ------------------------------------------------------------------ */
4709 +#define SIG_VERSION 1
4710 +
4711 +/* Processor Family - sigBYTE dsProcessorFamily;  DISTINCT VALUES */
4712 +/* ------------------------------------------------------------------ */
4713 +/* What type of processor the file is meant to run on. */
4714 +/* This will let us know whether to read sigWORDs as high/low or low/high. */
4715 +#define PROC_INTEL      0x00    /* Intel 80x86 */
4716 +#define PROC_MOTOROLA   0x01    /* Motorola 68K */
4717 +#define PROC_MIPS4000   0x02    /* MIPS RISC 4000 */
4718 +#define PROC_ALPHA      0x03    /* DEC Alpha */
4719 +#define PROC_POWERPC    0x04    /* IBM Power PC */
4720 +#define PROC_i960       0x05    /* Intel i960 */
4721 +#define PROC_ULTRASPARC 0x06    /* SPARC processor */
4722 +
4723 +/* Specific Minimim Processor - sigBYTE dsProcessor;    FLAG BITS */
4724 +/* ------------------------------------------------------------------ */
4725 +/* Different bit definitions dependent on processor_family */
4726 +
4727 +/* PROC_INTEL: */
4728 +#define PROC_8086       0x01    /* Intel 8086 */
4729 +#define PROC_286        0x02    /* Intel 80286 */
4730 +#define PROC_386        0x04    /* Intel 80386 */
4731 +#define PROC_486        0x08    /* Intel 80486 */
4732 +#define PROC_PENTIUM    0x10    /* Intel 586 aka P5 aka Pentium */
4733 +#define PROC_SEXIUM    0x20    /* Intel 686 aka P6 aka Pentium Pro or MMX */
4734 +
4735 +/* PROC_i960: */
4736 +#define PROC_960RX      0x01    /* Intel 80960RC/RD */
4737 +#define PROC_960HX      0x02    /* Intel 80960HA/HD/HT */
4738 +
4739 +/* PROC_MOTOROLA: */
4740 +#define PROC_68000      0x01    /* Motorola 68000 */
4741 +#define PROC_68010     0x02    /* Motorola 68010 */
4742 +#define PROC_68020      0x04    /* Motorola 68020 */
4743 +#define PROC_68030      0x08    /* Motorola 68030 */
4744 +#define PROC_68040      0x10    /* Motorola 68040 */
4745 +
4746 +/* PROC_POWERPC */
4747 +#define PROC_PPC601            0x01    /* PowerPC 601 */
4748 +#define PROC_PPC603            0x02    /* PowerPC 603 */
4749 +#define PROC_PPC604            0x04    /* PowerPC 604 */
4750 +
4751 +/* PROC_MIPS4000: */
4752 +#define PROC_R4000      0x01    /* MIPS R4000 */
4753 +
4754 +/* Filetype - sigBYTE dsFiletype;       DISTINCT VALUES */
4755 +/* ------------------------------------------------------------------ */
4756 +#define FT_EXECUTABLE   0       /* Executable Program */
4757 +#define FT_SCRIPT       1       /* Script/Batch File??? */
4758 +#define FT_HBADRVR      2       /* HBA Driver */
4759 +#define FT_OTHERDRVR    3       /* Other Driver */
4760 +#define FT_IFS          4       /* Installable Filesystem Driver */
4761 +#define FT_ENGINE       5       /* DPT Engine */
4762 +#define FT_COMPDRVR     6       /* Compressed Driver Disk */
4763 +#define FT_LANGUAGE     7       /* Foreign Language file */
4764 +#define FT_FIRMWARE     8       /* Downloadable or actual Firmware */
4765 +#define FT_COMMMODL     9       /* Communications Module */
4766 +#define FT_INT13        10      /* INT 13 style HBA Driver */
4767 +#define FT_HELPFILE     11      /* Help file */
4768 +#define FT_LOGGER       12      /* Event Logger */
4769 +#define FT_INSTALL      13      /* An Install Program */
4770 +#define FT_LIBRARY      14      /* Storage Manager Real-Mode Calls */
4771 +#define FT_RESOURCE    15      /* Storage Manager Resource File */
4772 +#define FT_MODEM_DB    16      /* Storage Manager Modem Database */
4773 +
4774 +/* Filetype flags - sigBYTE dsFiletypeFlags;    FLAG BITS */
4775 +/* ------------------------------------------------------------------ */
4776 +#define FTF_DLL         0x01    /* Dynamic Link Library */
4777 +#define FTF_NLM         0x02    /* Netware Loadable Module */
4778 +#define FTF_OVERLAYS    0x04    /* Uses overlays */
4779 +#define FTF_DEBUG       0x08    /* Debug version */
4780 +#define FTF_TSR         0x10    /* TSR */
4781 +#define FTF_SYS         0x20    /* DOS Loadable driver */
4782 +#define FTF_PROTECTED   0x40    /* Runs in protected mode */
4783 +#define FTF_APP_SPEC    0x80    /* Application Specific */
4784 +#define FTF_ROM                (FTF_SYS|FTF_TSR)       /* Special Case */
4785 +
4786 +/* OEM - sigBYTE dsOEM;         DISTINCT VALUES */
4787 +/* ------------------------------------------------------------------ */
4788 +#define OEM_DPT         0       /* DPT */
4789 +#define OEM_ATT         1       /* ATT */
4790 +#define OEM_NEC         2       /* NEC */
4791 +#define OEM_ALPHA       3       /* Alphatronix */
4792 +#define OEM_AST         4       /* AST */
4793 +#define OEM_OLIVETTI    5       /* Olivetti */
4794 +#define OEM_SNI         6       /* Siemens/Nixdorf */
4795 +#define OEM_SUN         7       /* SUN Microsystems */
4796 +
4797 +/* Operating System  - sigLONG dsOS;    FLAG BITS */
4798 +/* ------------------------------------------------------------------ */
4799 +#define OS_DOS          0x00000001 /* PC/MS-DOS                                */
4800 +#define OS_WINDOWS      0x00000002 /* Microsoft Windows 3.x            */
4801 +#define OS_WINDOWS_NT   0x00000004 /* Microsoft Windows NT             */
4802 +#define OS_OS2M         0x00000008 /* OS/2 1.2.x,MS 1.3.0,IBM 1.3.x - Monolithic */
4803 +#define OS_OS2L         0x00000010 /* Microsoft OS/2 1.301 - LADDR     */
4804 +#define OS_OS22x        0x00000020 /* IBM OS/2 2.x                     */
4805 +#define OS_NW286        0x00000040 /* Novell NetWare 286               */
4806 +#define OS_NW386        0x00000080 /* Novell NetWare 386               */
4807 +#define OS_GEN_UNIX     0x00000100 /* Generic Unix                     */
4808 +#define OS_SCO_UNIX     0x00000200 /* SCO Unix                         */
4809 +#define OS_ATT_UNIX     0x00000400 /* ATT Unix                         */
4810 +#define OS_UNIXWARE     0x00000800 /* USL Unix                         */
4811 +#define OS_INT_UNIX     0x00001000 /* Interactive Unix                 */
4812 +#define OS_SOLARIS      0x00002000 /* SunSoft Solaris                  */
4813 +#define OS_QNX          0x00004000 /* QNX for Tom Moch                 */
4814 +#define OS_NEXTSTEP     0x00008000 /* NeXTSTEP/OPENSTEP/MACH           */
4815 +#define OS_BANYAN       0x00010000 /* Banyan Vines                     */
4816 +#define OS_OLIVETTI_UNIX 0x00020000/* Olivetti Unix                    */
4817 +#define OS_MAC_OS      0x00040000 /* Mac OS                            */
4818 +#define OS_WINDOWS_95  0x00080000 /* Microsoft Windows '95             */
4819 +#define OS_NW4x                0x00100000 /* Novell Netware 4.x                */
4820 +#define OS_BSDI_UNIX   0x00200000 /* BSDi Unix BSD/OS 2.0 and up       */
4821 +#define OS_AIX_UNIX     0x00400000 /* AIX Unix                         */
4822 +#define OS_FREE_BSD    0x00800000 /* FreeBSD Unix                      */
4823 +#define OS_LINUX       0x01000000 /* Linux                             */
4824 +#define OS_DGUX_UNIX   0x02000000 /* Data General Unix                 */
4825 +#define OS_SINIX_N      0x04000000 /* SNI SINIX-N                      */
4826 +#define OS_PLAN9       0x08000000 /* ATT Plan 9                        */
4827 +#define OS_TSX         0x10000000 /* SNH TSX-32                        */
4828 +
4829 +#define OS_OTHER        0x80000000 /* Other                            */
4830 +
4831 +/* Capabilities - sigWORD dsCapabilities;        FLAG BITS */
4832 +/* ------------------------------------------------------------------ */
4833 +#define CAP_RAID0       0x0001  /* RAID-0 */
4834 +#define CAP_RAID1       0x0002  /* RAID-1 */
4835 +#define CAP_RAID3       0x0004  /* RAID-3 */
4836 +#define CAP_RAID5       0x0008  /* RAID-5 */
4837 +#define CAP_SPAN        0x0010  /* Spanning */
4838 +#define CAP_PASS        0x0020  /* Provides passthrough */
4839 +#define CAP_OVERLAP     0x0040  /* Passthrough supports overlapped commands */
4840 +#define CAP_ASPI        0x0080  /* Supports ASPI Command Requests */
4841 +#define CAP_ABOVE16MB   0x0100  /* ISA Driver supports greater than 16MB */
4842 +#define CAP_EXTEND      0x8000  /* Extended info appears after description */
4843 +#ifdef SNI_MIPS
4844 +#define CAP_CACHEMODE   0x1000  /* dpt_force_cache is set in driver */
4845 +#endif
4846 +
4847 +/* Devices Supported - sigWORD dsDeviceSupp;    FLAG BITS */
4848 +/* ------------------------------------------------------------------ */
4849 +#define DEV_DASD        0x0001  /* DASD (hard drives) */
4850 +#define DEV_TAPE        0x0002  /* Tape drives */
4851 +#define DEV_PRINTER     0x0004  /* Printers */
4852 +#define DEV_PROC        0x0008  /* Processors */
4853 +#define DEV_WORM        0x0010  /* WORM drives */
4854 +#define DEV_CDROM       0x0020  /* CD-ROM drives */
4855 +#define DEV_SCANNER     0x0040  /* Scanners */
4856 +#define DEV_OPTICAL     0x0080  /* Optical Drives */
4857 +#define DEV_JUKEBOX     0x0100  /* Jukebox */
4858 +#define DEV_COMM        0x0200  /* Communications Devices */
4859 +#define DEV_OTHER       0x0400  /* Other Devices */
4860 +#define DEV_ALL         0xFFFF  /* All SCSI Devices */
4861 +
4862 +/* Adapters Families Supported - sigWORD dsAdapterSupp; FLAG BITS */
4863 +/* ------------------------------------------------------------------ */
4864 +#define ADF_2001        0x0001  /* PM2001           */
4865 +#define ADF_2012A       0x0002  /* PM2012A          */
4866 +#define ADF_PLUS_ISA    0x0004  /* PM2011,PM2021    */
4867 +#define ADF_PLUS_EISA   0x0008  /* PM2012B,PM2022   */
4868 +#define ADF_SC3_ISA    0x0010  /* PM2021           */
4869 +#define ADF_SC3_EISA   0x0020  /* PM2022,PM2122, etc */
4870 +#define ADF_SC3_PCI    0x0040  /* SmartCache III PCI */
4871 +#define ADF_SC4_ISA    0x0080  /* SmartCache IV ISA */
4872 +#define ADF_SC4_EISA   0x0100  /* SmartCache IV EISA */
4873 +#define ADF_SC4_PCI    0x0200  /* SmartCache IV PCI */
4874 +#define ADF_SC5_PCI    0x0400  /* Fifth Generation I2O products */
4875 +/*
4876 + *     Combinations of products
4877 + */
4878 +#define ADF_ALL_2000   (ADF_2001|ADF_2012A)
4879 +#define ADF_ALL_PLUS   (ADF_PLUS_ISA|ADF_PLUS_EISA)
4880 +#define ADF_ALL_SC3    (ADF_SC3_ISA|ADF_SC3_EISA|ADF_SC3_PCI)
4881 +#define ADF_ALL_SC4    (ADF_SC4_ISA|ADF_SC4_EISA|ADF_SC4_PCI)
4882 +#define ADF_ALL_SC5    (ADF_SC5_PCI)
4883 +/* All EATA Cacheing Products */
4884 +#define ADF_ALL_CACHE  (ADF_ALL_PLUS|ADF_ALL_SC3|ADF_ALL_SC4)
4885 +/* All EATA Bus Mastering Products */
4886 +#define ADF_ALL_MASTER (ADF_2012A|ADF_ALL_CACHE)
4887 +/* All EATA Adapter Products */
4888 +#define ADF_ALL_EATA   (ADF_2001|ADF_ALL_MASTER)
4889 +#define ADF_ALL                ADF_ALL_EATA
4890 +
4891 +/* Application - sigWORD dsApplication;         FLAG BITS */
4892 +/* ------------------------------------------------------------------ */
4893 +#define APP_DPTMGR      0x0001  /* DPT Storage Manager */
4894 +#define APP_ENGINE      0x0002  /* DPT Engine */
4895 +#define APP_SYTOS       0x0004  /* Sytron Sytos Plus */
4896 +#define APP_CHEYENNE    0x0008  /* Cheyenne ARCServe + ARCSolo */
4897 +#define APP_MSCDEX      0x0010  /* Microsoft CD-ROM extensions */
4898 +#define APP_NOVABACK    0x0020  /* NovaStor Novaback */
4899 +#define APP_AIM         0x0040  /* Archive Information Manager */
4900 +
4901 +/* Requirements - sigBYTE dsRequirements;         FLAG BITS             */
4902 +/* ------------------------------------------------------------------   */
4903 +#define REQ_SMARTROM    0x01    /* Requires SmartROM to be present      */
4904 +#define REQ_DPTDDL      0x02    /* Requires DPTDDL.SYS to be loaded     */
4905 +#define REQ_HBA_DRIVER  0x04    /* Requires an HBA driver to be loaded  */
4906 +#define REQ_ASPI_TRAN   0x08    /* Requires an ASPI Transport Modules   */
4907 +#define REQ_ENGINE      0x10    /* Requires a DPT Engine to be loaded   */
4908 +#define REQ_COMM_ENG    0x20    /* Requires a DPT Communications Engine */
4909 +
4910 +/*
4911 + * You may adjust dsDescription_size with an override to a value less than
4912 + * 50 so that the structure allocates less real space.
4913 + */
4914 +#if (!defined(dsDescription_size))
4915 +# define dsDescription_size 50
4916 +#endif
4917 +
4918 +typedef struct dpt_sig {
4919 +    char    dsSignature[6];      /* ALWAYS "dPtSiG" */
4920 +    sigBYTE dsSigVersion;        /* signature version (currently 1) */
4921 +    sigBYTE dsProcessorFamily;   /* what type of processor */
4922 +    sigBYTE dsProcessor;         /* precise processor */
4923 +    sigBYTE dsFiletype;          /* type of file */
4924 +    sigBYTE dsFiletypeFlags;     /* flags to specify load type, etc. */
4925 +    sigBYTE dsOEM;               /* OEM file was created for */
4926 +    sigLONG dsOS;                /* which Operating systems */
4927 +    sigWORD dsCapabilities;      /* RAID levels, etc. */
4928 +    sigWORD dsDeviceSupp;        /* Types of SCSI devices supported */
4929 +    sigWORD dsAdapterSupp;       /* DPT adapter families supported */
4930 +    sigWORD dsApplication;       /* applications file is for */
4931 +    sigBYTE dsRequirements;      /* Other driver dependencies */
4932 +    sigBYTE dsVersion;           /* 1 */
4933 +    sigBYTE dsRevision;          /* 'J' */
4934 +    sigBYTE dsSubRevision;       /* '9'   ' ' if N/A */
4935 +    sigBYTE dsMonth;             /* creation month */
4936 +    sigBYTE dsDay;               /* creation day */
4937 +    sigBYTE dsYear;              /* creation year since 1980 (1993=13) */
4938 +    /* description (NULL terminated) */
4939 +    char  dsDescription[dsDescription_size];
4940 +} dpt_sig_S;
4941 +/* 32 bytes minimum - with no description.  Put NULL at description[0] */
4942 +/* 81 bytes maximum - with 49 character description plus NULL. */
4943 +
4944 +/* This line added at Roycroft's request */
4945 +/* Microsoft's NT compiler gets confused if you do a pack and don't */
4946 +/* restore it. */
4947 +
4948 +#ifndef NO_UNPACK
4949 +#if defined (_DPT_AIX)
4950 +#pragma options align=reset
4951 +#elif defined (UNPACK_FOUR)
4952 +#pragma pack(4)
4953 +#else
4954 +#pragma pack()
4955 +#endif  /* aix */
4956 +#endif
4957 +/* For the Macintosh */
4958 +#if STRUCTALIGNMENTSUPPORTED
4959 +#pragma options align=reset
4960 +#endif
4961 +
4962 +#endif
4963 --- /dev/null   Sat Apr 14 07:06:21 2001
4964 +++ linux/drivers/scsi/sys_info.h       Wed Jul 18 14:31:28 2001
4965 @@ -0,0 +1,417 @@
4966 +/*     BSDI sys_info.h,v 1.6 1998/06/03 19:14:59 karels Exp    */
4967 +
4968 +/*
4969 + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
4970 + * All rights reserved.
4971 + *
4972 + * Redistribution and use in source form, with or without modification, are
4973 + * permitted provided that redistributions of source code must retain the
4974 + * above copyright notice, this list of conditions and the following disclaimer.
4975 + *
4976 + * This software is provided `as is' by Distributed Processing Technology and
4977 + * any express or implied warranties, including, but not limited to, the
4978 + * implied warranties of merchantability and fitness for a particular purpose,
4979 + * are disclaimed. In no event shall Distributed Processing Technology be
4980 + * liable for any direct, indirect, incidental, special, exemplary or
4981 + * consequential damages (including, but not limited to, procurement of
4982 + * substitute goods or services; loss of use, data, or profits; or business
4983 + * interruptions) however caused and on any theory of liability, whether in
4984 + * contract, strict liability, or tort (including negligence or otherwise)
4985 + * arising in any way out of the use of this driver software, even if advised
4986 + * of the possibility of such damage.
4987 + *
4988 + */
4989 +
4990 +#ifndef         __SYS_INFO_H
4991 +#define         __SYS_INFO_H
4992 +
4993 +/*File - SYS_INFO.H
4994 + ****************************************************************************
4995 + *
4996 + *Description:
4997 + *
4998 + *      This file contains structure definitions for the OS dependent
4999 + *layer system information buffers.
5000 + *
5001 + *Copyright Distributed Processing Technology, Corp.
5002 + *        140 Candace Dr.
5003 + *        Maitland, Fl. 32751   USA
5004 + *        Phone: (407) 830-5522  Fax: (407) 260-5366
5005 + *        All Rights Reserved
5006 + *
5007 + *Author:       Don Kemper
5008 + *Date:         5/10/94
5009 + *
5010 + *Editors:
5011 + *
5012 + *Remarks:
5013 + *
5014 + *
5015 + *****************************************************************************/
5016 +
5017 +
5018 +/*Include Files ------------------------------------------------------------- */
5019 +
5020 +#include        "osd_util.h"
5021 +
5022 +#ifndef NO_PACK
5023 +#if defined (_DPT_AIX)
5024 +#pragma options align=packed
5025 +#else
5026 +#pragma pack(1)
5027 +#endif  /* aix */
5028 +#endif  // no unpack
5029 +
5030 +
5031 +/*struct - driveParam_S - start
5032 + *===========================================================================
5033 + *
5034 + *Description:
5035 + *
5036 + *      This structure defines the drive parameters seen during
5037 + *booting.
5038 + *
5039 + *---------------------------------------------------------------------------*/
5040 +
5041 +#ifdef  __cplusplus
5042 +   struct driveParam_S {
5043 +#else
5044 +   typedef struct  {
5045 +#endif
5046 +
5047 +   uSHORT       cylinders;      /* Upto 1024 */
5048 +   uCHAR        heads;          /* Upto 255 */
5049 +   uCHAR        sectors;        /* Upto 63 */
5050 +
5051 +#ifdef  __cplusplus
5052 +
5053 +//---------- Portability Additions ----------- in sp_sinfo.cpp
5054 +#ifdef DPT_PORTABLE
5055 +       uSHORT          netInsert(dptBuffer_S *buffer);
5056 +       uSHORT          netExtract(dptBuffer_S *buffer);
5057 +#endif // DPT PORTABLE
5058 +//--------------------------------------------
5059 +
5060 +   };
5061 +#else
5062 +   } driveParam_S;
5063 +#endif
5064 +/*driveParam_S - end */
5065 +
5066 +
5067 +/*struct - sysInfo_S - start
5068 + *===========================================================================
5069 + *
5070 + *Description:
5071 + *
5072 + *      This structure defines the command system information that
5073 + *should be returned by every OS dependent layer.
5074 + *
5075 + *---------------------------------------------------------------------------*/
5076 +
5077 +/*flags - bit definitions */
5078 +#define SI_CMOS_Valid           0x0001
5079 +#define SI_NumDrivesValid       0x0002
5080 +#define SI_ProcessorValid       0x0004
5081 +#define SI_MemorySizeValid      0x0008
5082 +#define SI_DriveParamsValid     0x0010
5083 +#define SI_SmartROMverValid     0x0020
5084 +#define SI_OSversionValid       0x0040
5085 +#define SI_OSspecificValid      0x0080  /* 1 if OS structure returned */
5086 +#define SI_BusTypeValid         0x0100
5087 +
5088 +#define SI_ALL_VALID            0x0FFF  /* All Std SysInfo is valid */
5089 +#define SI_NO_SmartROM          0x8000
5090 +
5091 +/*busType - definitions */
5092 +#define SI_ISA_BUS      0x00
5093 +#define SI_MCA_BUS      0x01
5094 +#define SI_EISA_BUS     0x02
5095 +#define SI_PCI_BUS      0x04
5096 +
5097 +#ifdef  __cplusplus
5098 +   struct sysInfo_S {
5099 +#else
5100 +   typedef struct  {
5101 +#endif
5102 +
5103 +   uCHAR        drive0CMOS;             /* CMOS Drive 0 Type */
5104 +   uCHAR        drive1CMOS;             /* CMOS Drive 1 Type */
5105 +   uCHAR        numDrives;              /* 0040:0075 contents */
5106 +   uCHAR        processorFamily;        /* Same as DPTSIG's definition */
5107 +   uCHAR        processorType;          /* Same as DPTSIG's definition */
5108 +   uCHAR        smartROMMajorVersion;
5109 +   uCHAR        smartROMMinorVersion;   /* SmartROM version */
5110 +   uCHAR        smartROMRevision;
5111 +   uSHORT       flags;                  /* See bit definitions above */
5112 +   uSHORT       conventionalMemSize;    /* in KB */
5113 +   uLONG        extendedMemSize;        /* in KB */
5114 +   uLONG        osType;                 /* Same as DPTSIG's definition */
5115 +   uCHAR        osMajorVersion;
5116 +   uCHAR        osMinorVersion;         /* The OS version */
5117 +   uCHAR        osRevision;
5118 +#ifdef _SINIX_ADDON
5119 +   uCHAR        busType;                /* See defininitions above */
5120 +   uSHORT       osSubRevision;
5121 +   uCHAR        pad[2];                 /* For alignment */
5122 +#else
5123 +   uCHAR        osSubRevision;
5124 +   uCHAR        busType;                /* See defininitions above */
5125 +   uCHAR        pad[3];                 /* For alignment */
5126 +#endif
5127 +   driveParam_S drives[16];             /* SmartROM Logical Drives */
5128 +
5129 +#ifdef  __cplusplus
5130 +
5131 +//---------- Portability Additions ----------- in sp_sinfo.cpp
5132 +#ifdef DPT_PORTABLE
5133 +       uSHORT          netInsert(dptBuffer_S *buffer);
5134 +       uSHORT          netExtract(dptBuffer_S *buffer);
5135 +#endif // DPT PORTABLE
5136 +//--------------------------------------------
5137 +
5138 +   };
5139 +#else
5140 +   } sysInfo_S;
5141 +#endif
5142 +/*sysInfo_S - end */
5143 +
5144 +
5145 +/*struct - DOS_Info_S - start
5146 + *===========================================================================
5147 + *
5148 + *Description:
5149 + *
5150 + *      This structure defines the system information specific to a
5151 + *DOS workstation.
5152 + *
5153 + *---------------------------------------------------------------------------*/
5154 +
5155 +/*flags - bit definitions */
5156 +#define DI_DOS_HIGH             0x01    /* DOS is loaded high */
5157 +#define DI_DPMI_VALID           0x02    /* DPMI version is valid */
5158 +
5159 +#ifdef  __cplusplus
5160 +   struct DOS_Info_S {
5161 +#else
5162 +   typedef struct {
5163 +#endif
5164 +
5165 +   uCHAR        flags;          /* See bit definitions above */
5166 +   uSHORT       driverLocation; /* SmartROM BIOS address */
5167 +   uSHORT       DOS_version;
5168 +   uSHORT       DPMI_version;
5169 +
5170 +#ifdef  __cplusplus
5171 +
5172 +//---------- Portability Additions ----------- in sp_sinfo.cpp
5173 +#ifdef DPT_PORTABLE
5174 +       uSHORT          netInsert(dptBuffer_S *buffer);
5175 +       uSHORT          netExtract(dptBuffer_S *buffer);
5176 +#endif // DPT PORTABLE
5177 +//--------------------------------------------
5178 +
5179 +   };
5180 +#else
5181 +   } DOS_Info_S;
5182 +#endif
5183 +/*DOS_Info_S - end */
5184 +
5185 +
5186 +/*struct - Netware_Info_S - start
5187 + *===========================================================================
5188 + *
5189 + *Description:
5190 + *
5191 + *      This structure defines the system information specific to a
5192 + *Netware machine.
5193 + *
5194 + *---------------------------------------------------------------------------*/
5195 +
5196 +#ifdef  __cplusplus
5197 +   struct Netware_Info_S {
5198 +#else
5199 +   typedef struct {
5200 +#endif
5201 +
5202 +   uCHAR        driverName[13];         /* ie PM12NW31.DSK */
5203 +   uCHAR        serverName[48];
5204 +   uCHAR        netwareVersion;         /* The Netware OS version */
5205 +   uCHAR        netwareSubVersion;
5206 +   uCHAR        netwareRevision;
5207 +   uSHORT       maxConnections;         /* Probably  250 or 1000 */
5208 +   uSHORT       connectionsInUse;
5209 +   uSHORT       maxVolumes;
5210 +   uCHAR        unused;
5211 +   uCHAR        SFTlevel;
5212 +   uCHAR        TTSlevel;
5213 +
5214 +   uCHAR        clibMajorVersion;       /* The CLIB.NLM version */
5215 +   uCHAR        clibMinorVersion;
5216 +   uCHAR        clibRevision;
5217 +
5218 +#ifdef  __cplusplus
5219 +
5220 +//---------- Portability Additions ----------- in sp_sinfo.cpp
5221 +#ifdef DPT_PORTABLE
5222 +       uSHORT          netInsert(dptBuffer_S *buffer);
5223 +       uSHORT          netExtract(dptBuffer_S *buffer);
5224 +#endif // DPT PORTABLE
5225 +//--------------------------------------------
5226 +
5227 +   };
5228 +#else
5229 +   } Netware_Info_S;
5230 +#endif
5231 +/*Netware_Info_S - end */
5232 +
5233 +
5234 +/*struct - OS2_Info_S - start
5235 + *===========================================================================
5236 + *
5237 + *Description:
5238 + *
5239 + *      This structure defines the system information specific to an
5240 + *OS/2 machine.
5241 + *
5242 + *---------------------------------------------------------------------------*/
5243 +
5244 +#ifdef  __cplusplus
5245 +   struct OS2_Info_S {
5246 +#else
5247 +   typedef struct {
5248 +#endif
5249 +
5250 +   uCHAR        something;
5251 +
5252 +#ifdef  __cplusplus
5253 +
5254 +//---------- Portability Additions ----------- in sp_sinfo.cpp
5255 +#ifdef DPT_PORTABLE
5256 +       uSHORT          netInsert(dptBuffer_S *buffer);
5257 +       uSHORT          netExtract(dptBuffer_S *buffer);
5258 +#endif // DPT PORTABLE
5259 +//--------------------------------------------
5260 +
5261 +   };
5262 +#else
5263 +   } OS2_Info_S;
5264 +#endif
5265 +/*OS2_Info_S - end */
5266 +
5267 +
5268 +/*struct - WinNT_Info_S - start
5269 + *===========================================================================
5270 + *
5271 + *Description:
5272 + *
5273 + *      This structure defines the system information specific to a
5274 + *Windows NT machine.
5275 + *
5276 + *---------------------------------------------------------------------------*/
5277 +
5278 +#ifdef  __cplusplus
5279 +   struct WinNT_Info_S {
5280 +#else
5281 +   typedef struct {
5282 +#endif
5283 +
5284 +   uCHAR        something;
5285 +
5286 +#ifdef  __cplusplus
5287 +
5288 +//---------- Portability Additions ----------- in sp_sinfo.cpp
5289 +#ifdef DPT_PORTABLE
5290 +       uSHORT          netInsert(dptBuffer_S *buffer);
5291 +       uSHORT          netExtract(dptBuffer_S *buffer);
5292 +#endif // DPT PORTABLE
5293 +//--------------------------------------------
5294 +
5295 +   };
5296 +#else
5297 +   } WinNT_Info_S;
5298 +#endif
5299 +/*WinNT_Info_S - end */
5300 +
5301 +
5302 +/*struct - SCO_Info_S - start
5303 + *===========================================================================
5304 + *
5305 + *Description:
5306 + *
5307 + *      This structure defines the system information specific to an
5308 + *SCO UNIX machine.
5309 + *
5310 + *---------------------------------------------------------------------------*/
5311 +
5312 +#ifdef  __cplusplus
5313 +   struct SCO_Info_S {
5314 +#else
5315 +   typedef struct {
5316 +#endif
5317 +
5318 +   uCHAR        something;
5319 +
5320 +#ifdef  __cplusplus
5321 +
5322 +//---------- Portability Additions ----------- in sp_sinfo.cpp
5323 +#ifdef DPT_PORTABLE
5324 +       uSHORT          netInsert(dptBuffer_S *buffer);
5325 +       uSHORT          netExtract(dptBuffer_S *buffer);
5326 +#endif // DPT PORTABLE
5327 +//--------------------------------------------
5328 +
5329 +   };
5330 +#else
5331 +   } SCO_Info_S;
5332 +#endif
5333 +/*SCO_Info_S - end */
5334 +
5335 +
5336 +/*struct - USL_Info_S - start
5337 + *===========================================================================
5338 + *
5339 + *Description:
5340 + *
5341 + *      This structure defines the system information specific to a
5342 + *USL UNIX machine.
5343 + *
5344 + *---------------------------------------------------------------------------*/
5345 +
5346 +#ifdef  __cplusplus
5347 +   struct USL_Info_S {
5348 +#else
5349 +   typedef struct {
5350 +#endif
5351 +
5352 +   uCHAR        something;
5353 +
5354 +#ifdef  __cplusplus
5355 +
5356 +//---------- Portability Additions ----------- in sp_sinfo.cpp
5357 +#ifdef DPT_PORTABLE
5358 +       uSHORT          netInsert(dptBuffer_S *buffer);
5359 +       uSHORT          netExtract(dptBuffer_S *buffer);
5360 +#endif // DPT PORTABLE
5361 +//--------------------------------------------
5362 +
5363 +   };
5364 +#else
5365 +   } USL_Info_S;
5366 +#endif
5367 +/*USL_Info_S - end */
5368 +
5369 +
5370 +  /* Restore default structure packing */
5371 +#ifndef NO_UNPACK
5372 +#if defined (_DPT_AIX)
5373 +#pragma options align=reset
5374 +#elif defined (UNPACK_FOUR)
5375 +#pragma pack(4)
5376 +#else
5377 +#pragma pack()
5378 +#endif  /* aix */
5379 +#endif  // no unpack
5380 +
5381 +#endif  // __SYS_INFO_H
5382 +
5383 --- /dev/null   Sat Apr 14 07:06:21 2001
5384 +++ linux/drivers/scsi/README.dpti      Wed Jul 18 14:31:28 2001
5385 @@ -0,0 +1,41 @@
5386 + /* TERMS AND CONDITIONS OF USE
5387 + * 
5388 + * Redistribution and use in source form, with or without modification, are
5389 + * permitted provided that redistributions of source code must retain the
5390 + * above copyright notice, this list of conditions and the following disclaimer.
5391 + * 
5392 + * This software is provided `as is' by Adaptec and
5393 + * any express or implied warranties, including, but not limited to, the
5394 + * implied warranties of merchantability and fitness for a particular purpose,
5395 + * are disclaimed. In no event shall Adaptec be
5396 + * liable for any direct, indirect, incidental, special, exemplary or
5397 + * consequential damages (including, but not limited to, procurement of
5398 + * substitute goods or services; loss of use, data, or profits; or business
5399 + * interruptions) however caused and on any theory of liability, whether in
5400 + * contract, strict liability, or tort (including negligence or otherwise)
5401 + * arising in any way out of the use of this driver software, even if advised
5402 + * of the possibility of such damage.
5403 + * 
5404 + ****************************************************************
5405 + * This driver supports the Adaptec I2O RAID and DPT SmartRAID V I2O boards.
5406 + *
5407 + * CREDITS:
5408 + * The original linux driver was ported to Linux by Karen White while at 
5409 + * Dell Computer.  It was ported from Bob Pasteur's (of DPT) original 
5410 + * non-Linux driver.  Mark Salyzyn and Bob Pasteur consulted on the original
5411 + * driver. 
5412 + * 
5413 + * Thanks to Ricky Beam for supplying porting information to 2.3 kernel.
5414 + *
5415 + * 2.0 version of the driver by Deanna Bonds and Mark Salyzyn.
5416 + *
5417 + * HISTORY:
5418 + * The driver was originally ported to linux version 2.0.34.  
5419 + * SMP support was added in version 2.2.1 and 2.2.2.
5420 + *
5421 + * The DPT card optimizes the order of processing commands.  Consequently,
5422 + * a command may take up to 6 minutes to complete after it has been sent
5423 + * to the board.  
5424 + *
5425 + */
5426 +
5427 --- /dev/null   Sat Apr 14 07:06:21 2001
5428 +++ linux/drivers/scsi/osd_util.h       Wed Jul 18 14:31:28 2001
5429 @@ -0,0 +1,358 @@
5430 +/*     BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp    */
5431 +
5432 +/*
5433 + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
5434 + * All rights reserved.
5435 + *
5436 + * Redistribution and use in source form, with or without modification, are
5437 + * permitted provided that redistributions of source code must retain the
5438 + * above copyright notice, this list of conditions and the following disclaimer.
5439 + *
5440 + * This software is provided `as is' by Distributed Processing Technology and
5441 + * any express or implied warranties, including, but not limited to, the
5442 + * implied warranties of merchantability and fitness for a particular purpose,
5443 + * are disclaimed. In no event shall Distributed Processing Technology be
5444 + * liable for any direct, indirect, incidental, special, exemplary or
5445 + * consequential damages (including, but not limited to, procurement of
5446 + * substitute goods or services; loss of use, data, or profits; or business
5447 + * interruptions) however caused and on any theory of liability, whether in
5448 + * contract, strict liability, or tort (including negligence or otherwise)
5449 + * arising in any way out of the use of this driver software, even if advised
5450 + * of the possibility of such damage.
5451 + *
5452 + */
5453 +
5454 +#ifndef         __OSD_UTIL_H
5455 +#define         __OSD_UTIL_H
5456 +
5457 +/*File - OSD_UTIL.H
5458 + ****************************************************************************
5459 + *
5460 + *Description:
5461 + *
5462 + *      This file contains defines and function prototypes that are
5463 + *operating system dependent.  The resources defined in this file
5464 + *are not specific to any particular application.
5465 + *
5466 + *Copyright Distributed Processing Technology, Corp.
5467 + *        140 Candace Dr.
5468 + *        Maitland, Fl. 32751   USA
5469 + *        Phone: (407) 830-5522  Fax: (407) 260-5366
5470 + *        All Rights Reserved
5471 + *
5472 + *Author:       Doug Anderson
5473 + *Date:         1/7/94
5474 + *
5475 + *Editors:
5476 + *
5477 + *Remarks:
5478 + *
5479 + *
5480 + *****************************************************************************/
5481 +
5482 +
5483 +/*Definitions - Defines & Constants ----------------------------------------- */
5484 +
5485 +/*----------------------------- */
5486 +/* Operating system selections: */
5487 +/*----------------------------- */
5488 +
5489 +/*#define               _DPT_MSDOS      */
5490 +/*#define               _DPT_WIN_3X     */
5491 +/*#define               _DPT_WIN_4X     */
5492 +/*#define               _DPT_WIN_NT     */
5493 +/*#define               _DPT_NETWARE    */
5494 +/*#define               _DPT_OS2        */
5495 +/*#define               _DPT_SCO        */
5496 +/*#define               _DPT_UNIXWARE   */
5497 +/*#define               _DPT_SOLARIS    */
5498 +/*#define               _DPT_NEXTSTEP   */
5499 +/*#define               _DPT_BANYAN     */
5500 +
5501 +/*-------------------------------- */
5502 +/* Include the OS specific defines */
5503 +/*-------------------------------- */
5504 +
5505 +/*#define       OS_SELECTION    From Above List */
5506 +/*#define       SEMAPHORE_T     ??? */
5507 +/*#define       DLL_HANDLE_T    ??? */
5508 +
5509 +#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
5510 +# include        "i386/isa/dpt_osd_defs.h"
5511 +#else
5512 +# include        "osd_defs.h"
5513 +#endif
5514 +
5515 +#ifndef DPT_UNALIGNED
5516 +   #define      DPT_UNALIGNED
5517 +#endif
5518 +
5519 +#ifndef DPT_EXPORT
5520 +   #define      DPT_EXPORT
5521 +#endif
5522 +
5523 +#ifndef DPT_IMPORT
5524 +   #define      DPT_IMPORT
5525 +#endif
5526 +
5527 +#ifndef DPT_RUNTIME_IMPORT
5528 +   #define      DPT_RUNTIME_IMPORT  DPT_IMPORT
5529 +#endif
5530 +
5531 +/*--------------------- */
5532 +/* OS dependent defines */
5533 +/*--------------------- */
5534 +
5535 +#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
5536 +   #define      _DPT_16_BIT
5537 +#else
5538 +   #define      _DPT_32_BIT
5539 +#endif
5540 +
5541 +#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
5542 +   #define      _DPT_UNIX
5543 +#endif
5544 +
5545 +#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
5546 +           || defined (_DPT_OS2)
5547 +   #define      _DPT_DLL_SUPPORT
5548 +#endif
5549 +
5550 +#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
5551 +   #define      _DPT_PREEMPTIVE
5552 +#endif
5553 +
5554 +#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
5555 +   #define      _DPT_MULTI_THREADED
5556 +#endif
5557 +
5558 +#if !defined (_DPT_MSDOS)
5559 +   #define      _DPT_MULTI_TASKING
5560 +#endif
5561 +
5562 +  /* These exist for platforms that   */
5563 +  /* chunk when accessing mis-aligned */
5564 +  /* data                             */
5565 +#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
5566 +   #if defined (_DPT_BIG_ENDIAN)
5567 +       #if !defined (_DPT_STRICT_ALIGN)
5568 +            #define _DPT_STRICT_ALIGN
5569 +       #endif
5570 +   #endif
5571 +#endif
5572 +
5573 +  /* Determine if in C or C++ mode */
5574 +#ifdef  __cplusplus
5575 +   #define      _DPT_CPP
5576 +#else
5577 +   #define      _DPT_C
5578 +#endif
5579 +
5580 +/*-------------------------------------------------------------------*/
5581 +/* Under Solaris the compiler refuses to accept code like:           */
5582 +/*   { {"DPT"}, 0, NULL .... },                                      */
5583 +/* and complains about the {"DPT"} part by saying "cannot use { }    */
5584 +/* to initialize char*".                                             */
5585 +/*                                                                   */
5586 +/* By defining these ugly macros we can get around this and also     */
5587 +/* not have to copy and #ifdef large sections of code.  I know that  */
5588 +/* these macros are *really* ugly, but they should help reduce       */
5589 +/* maintenance in the long run.                                      */
5590 +/*                                                                   */
5591 +/*-------------------------------------------------------------------*/
5592 +#if !defined (DPTSQO)
5593 +   #if defined (_DPT_SOLARIS)
5594 +      #define DPTSQO
5595 +      #define DPTSQC
5596 +   #else
5597 +      #define DPTSQO {
5598 +      #define DPTSQC }
5599 +   #endif  /* solaris */
5600 +#endif  /* DPTSQO */
5601 +
5602 +
5603 +/*---------------------- */
5604 +/* OS dependent typedefs */
5605 +/*---------------------- */
5606 +
5607 +#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
5608 +   #define BYTE unsigned char
5609 +   #define WORD unsigned short
5610 +#endif
5611 +
5612 +#ifndef _DPT_TYPEDEFS
5613 +   #define _DPT_TYPEDEFS
5614 +   typedef unsigned char   uCHAR;
5615 +   typedef unsigned short  uSHORT;
5616 +   typedef unsigned int    uINT;
5617 +   typedef unsigned long   uLONG;
5618 +
5619 +   typedef union {
5620 +        uCHAR        u8[4];
5621 +        uSHORT       u16[2];
5622 +        uLONG        u32;
5623 +   } access_U;
5624 +#endif
5625 +
5626 +#if !defined (NULL)
5627 +   #define      NULL    0
5628 +#endif
5629 +
5630 +
5631 +/*Prototypes - function ----------------------------------------------------- */
5632 +
5633 +#ifdef  __cplusplus
5634 +   extern "C" {         /* Declare all these functions as "C" functions */
5635 +#endif
5636 +
5637 +/*------------------------ */
5638 +/* Byte reversal functions */
5639 +/*------------------------ */
5640 +
5641 +  /* Reverses the byte ordering of a 2 byte variable */
5642 +#if (!defined(osdSwap2))
5643 + uSHORT       osdSwap2(DPT_UNALIGNED uSHORT *);
5644 +#endif  // !osdSwap2
5645 +
5646 +  /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
5647 +#if (!defined(osdSwap3))
5648 + uLONG        osdSwap3(DPT_UNALIGNED uLONG *);
5649 +#endif  // !osdSwap3
5650 +
5651 +
5652 +#ifdef  _DPT_NETWARE
5653 +   #include "novpass.h" /* For DPT_Bswapl() prototype */
5654 +       /* Inline the byte swap */
5655 +   #ifdef __cplusplus
5656 +        inline uLONG osdSwap4(uLONG *inLong) {
5657 +        return *inLong = DPT_Bswapl(*inLong);
5658 +        }
5659 +   #else
5660 +        #define osdSwap4(inLong)       DPT_Bswapl(inLong)
5661 +   #endif  // cplusplus
5662 +#else
5663 +       /* Reverses the byte ordering of a 4 byte variable */
5664 +# if (!defined(osdSwap4))
5665 +   uLONG        osdSwap4(DPT_UNALIGNED uLONG *);
5666 +# endif  // !osdSwap4
5667 +
5668 +  /* The following functions ALWAYS swap regardless of the *
5669 +   * presence of DPT_BIG_ENDIAN                            */
5670 +
5671 +   uSHORT       trueSwap2(DPT_UNALIGNED uSHORT *);
5672 +   uLONG        trueSwap4(DPT_UNALIGNED uLONG *);
5673 +
5674 +#endif  // netware
5675 +
5676 +
5677 +/*-------------------------------------*
5678 + * Network order swap functions        *
5679 + *                                     *
5680 + * These functions/macros will be used *
5681 + * by the structure insert()/extract() *
5682 + * functions.                          *
5683 + *
5684 + * We will enclose all structure       *
5685 + * portability modifications inside    *
5686 + * #ifdefs.  When we are ready, we     *
5687 + * will #define DPT_PORTABLE to begin  *
5688 + * using the modifications.            *
5689 + *-------------------------------------*/
5690 +uLONG  netSwap4(uLONG val);
5691 +
5692 +#if defined (_DPT_BIG_ENDIAN)
5693 +
5694 +// for big-endian we need to swap
5695 +
5696 +#ifndef NET_SWAP_2
5697 +#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
5698 +#endif  // NET_SWAP_2
5699 +
5700 +#ifndef NET_SWAP_4
5701 +#define NET_SWAP_4(x) netSwap4((x))
5702 +#endif  // NET_SWAP_4
5703 +
5704 +#else
5705 +
5706 +// for little-endian we don't need to do anything
5707 +
5708 +#ifndef NET_SWAP_2
5709 +#define NET_SWAP_2(x) (x)
5710 +#endif  // NET_SWAP_2
5711 +
5712 +#ifndef NET_SWAP_4
5713 +#define NET_SWAP_4(x) (x)
5714 +#endif  // NET_SWAP_4
5715 +
5716 +#endif  // big endian
5717 +
5718 +
5719 +
5720 +/*----------------------------------- */
5721 +/* Run-time loadable module functions */
5722 +/*----------------------------------- */
5723 +
5724 +  /* Loads the specified run-time loadable DLL */
5725 +DLL_HANDLE_T    osdLoadModule(uCHAR *);
5726 +  /* Unloads the specified run-time loadable DLL */
5727 +uSHORT          osdUnloadModule(DLL_HANDLE_T);
5728 +  /* Returns a pointer to a function inside a run-time loadable DLL */
5729 +void *          osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
5730 +
5731 +/*--------------------------------------- */
5732 +/* Mutually exclusive semaphore functions */
5733 +/*--------------------------------------- */
5734 +
5735 +  /* Create a named semaphore */
5736 +SEMAPHORE_T     osdCreateNamedSemaphore(char *);
5737 +  /* Create a mutually exlusive semaphore */
5738 +SEMAPHORE_T     osdCreateSemaphore(void);
5739 +       /* create an event semaphore */
5740 +SEMAPHORE_T              osdCreateEventSemaphore(void);
5741 +       /* create a named event semaphore */
5742 +SEMAPHORE_T             osdCreateNamedEventSemaphore(char *);
5743 +
5744 +  /* Destroy the specified mutually exclusive semaphore object */
5745 +uSHORT          osdDestroySemaphore(SEMAPHORE_T);
5746 +  /* Request access to the specified mutually exclusive semaphore */
5747 +uLONG           osdRequestSemaphore(SEMAPHORE_T,uLONG);
5748 +  /* Release access to the specified mutually exclusive semaphore */
5749 +uSHORT          osdReleaseSemaphore(SEMAPHORE_T);
5750 +       /* wait for a event to happen */
5751 +uLONG                            osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
5752 +       /* signal an event */
5753 +uLONG                            osdSignalEventSemaphore(SEMAPHORE_T);
5754 +       /* reset the event */
5755 +uLONG                            osdResetEventSemaphore(SEMAPHORE_T);
5756 +
5757 +/*----------------- */
5758 +/* Thread functions */
5759 +/*----------------- */
5760 +
5761 +  /* Releases control to the task switcher in non-preemptive */
5762 +  /* multitasking operating systems. */
5763 +void            osdSwitchThreads(void);
5764 +
5765 +  /* Starts a thread function */
5766 +uLONG   osdStartThread(void *,void *);
5767 +
5768 +/* what is my thread id */
5769 +uLONG osdGetThreadID(void);
5770 +
5771 +/* wakes up the specifed thread */
5772 +void osdWakeThread(uLONG);
5773 +
5774 +/* osd sleep for x miliseconds */
5775 +void osdSleep(uLONG);
5776 +
5777 +#define DPT_THREAD_PRIORITY_LOWEST 0x00
5778 +#define DPT_THREAD_PRIORITY_NORMAL 0x01
5779 +#define DPT_THREAD_PRIORITY_HIGHEST 0x02
5780 +
5781 +uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
5782 +
5783 +#ifdef __cplusplus
5784 +   }    /* end the xtern "C" declaration */
5785 +#endif
5786 +
5787 +#endif  /* osd_util_h */
5788 --- /dev/null   Sat Apr 14 07:06:21 2001
5789 +++ linux/drivers/scsi/osd_defs.h       Wed Jul 18 14:31:28 2001
5790 @@ -0,0 +1,79 @@
5791 +/*     BSDI osd_defs.h,v 1.4 1998/06/03 19:14:58 karels Exp    */
5792 +/*
5793 + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
5794 + * All rights reserved.
5795 + *
5796 + * Redistribution and use in source form, with or without modification, are
5797 + * permitted provided that redistributions of source code must retain the
5798 + * above copyright notice, this list of conditions and the following disclaimer.
5799 + *
5800 + * This software is provided `as is' by Distributed Processing Technology and
5801 + * any express or implied warranties, including, but not limited to, the
5802 + * implied warranties of merchantability and fitness for a particular purpose,
5803 + * are disclaimed. In no event shall Distributed Processing Technology be
5804 + * liable for any direct, indirect, incidental, special, exemplary or
5805 + * consequential damages (including, but not limited to, procurement of
5806 + * substitute goods or services; loss of use, data, or profits; or business
5807 + * interruptions) however caused and on any theory of liability, whether in
5808 + * contract, strict liability, or tort (including negligence or otherwise)
5809 + * arising in any way out of the use of this driver software, even if advised
5810 + * of the possibility of such damage.
5811 + *
5812 + */
5813 +
5814 +#ifndef                _OSD_DEFS_H
5815 +#define                _OSD_DEFS_H
5816 +
5817 +/*File - OSD_DEFS.H
5818 + ****************************************************************************
5819 + *
5820 + *Description:
5821 + *
5822 + *     This file contains the OS dependent defines.  This file is included
5823 + *in osd_util.h and provides the OS specific defines for that file.
5824 + *
5825 + *Copyright Distributed Processing Technology, Corp.
5826 + *       140 Candace Dr.
5827 + *       Maitland, Fl. 32751   USA
5828 + *       Phone: (407) 830-5522  Fax: (407) 260-5366
5829 + *       All Rights Reserved
5830 + *
5831 + *Author:      Doug Anderson
5832 + *Date:                1/31/94
5833 + *
5834 + *Editors:
5835 + *
5836 + *Remarks:
5837 + *
5838 + *
5839 + *****************************************************************************/
5840 +
5841 +
5842 +/*Definitions - Defines & Constants ----------------------------------------- */
5843 +
5844 +  /* Define the operating system */
5845 +#if (defined(__linux__))
5846 +# define _DPT_LINUX
5847 +#elif (defined(__bsdi__))
5848 +# define _DPT_BSDI
5849 +#elif (defined(__FreeBSD__))
5850 +# define _DPT_FREE_BSD
5851 +#else
5852 +# define _DPT_SCO
5853 +#endif
5854 +
5855 +#if defined (ZIL_CURSES)
5856 +#define                _DPT_CURSES
5857 +#else
5858 +#define         _DPT_MOTIF
5859 +#endif
5860 +
5861 +  /* Redefine 'far' to nothing - no far pointer type required in UNIX */
5862 +#define                far
5863 +
5864 +  /* Define the mutually exclusive semaphore type */
5865 +#define                SEMAPHORE_T     unsigned int *
5866 +  /* Define a handle to a DLL */
5867 +#define                DLL_HANDLE_T    unsigned int *
5868 +
5869 +#endif
5870 --- /dev/null   Sat Apr 14 07:06:21 2001
5871 +++ linux/drivers/scsi/dpti_i2o-dev.h   Wed Jul 18 14:31:28 2001
5872 @@ -0,0 +1,397 @@
5873 +/*
5874 + * I2O user space accessible structures/APIs
5875 + * 
5876 + * (c) Copyright 1999, 2000 Red Hat Software
5877 + *
5878 + * This program is free software; you can redistribute it and/or 
5879 + * modify it under the terms of the GNU General Public License 
5880 + * as published by the Free Software Foundation; either version 
5881 + * 2 of the License, or (at your option) any later version.  
5882 + * 
5883 + *************************************************************************
5884 + *
5885 + * This header file defines the I2O APIs that are available to both
5886 + * the kernel and user level applications.  Kernel specific structures
5887 + * are defined in i2o_osm. OSMs should include _only_ i2o_osm.h which
5888 + * automatically includs this file.
5889 + *
5890 + */
5891 +
5892 +#ifndef _I2O_DEV_H
5893 +#define _I2O_DEV_H
5894 +
5895 +/* How many controllers are we allowing */
5896 +#define MAX_I2O_CONTROLLERS    32
5897 +
5898 +#include <linux/ioctl.h>
5899 +
5900 +/*
5901 + * I2O Control IOCTLs and structures
5902 + */
5903 +#define I2O_MAGIC_NUMBER       'i'
5904 +#define I2OGETIOPS             _IOR(I2O_MAGIC_NUMBER,0,u8[MAX_I2O_CONTROLLERS])
5905 +#define I2OHRTGET              _IOWR(I2O_MAGIC_NUMBER,1,struct i2o_cmd_hrtlct)
5906 +#define I2OLCTGET              _IOWR(I2O_MAGIC_NUMBER,2,struct i2o_cmd_hrtlct)
5907 +#define I2OPARMSET             _IOWR(I2O_MAGIC_NUMBER,3,struct i2o_cmd_psetget)
5908 +#define I2OPARMGET             _IOWR(I2O_MAGIC_NUMBER,4,struct i2o_cmd_psetget)
5909 +#define I2OSWDL                        _IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer)
5910 +#define I2OSWUL                        _IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer)
5911 +#define I2OSWDEL               _IOWR(I2O_MAGIC_NUMBER,7,struct i2o_sw_xfer)
5912 +#define I2OVALIDATE            _IOR(I2O_MAGIC_NUMBER,8,u32)
5913 +#define I2OHTML                        _IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html)
5914 +#define I2OEVTREG              _IOW(I2O_MAGIC_NUMBER,10,struct i2o_evt_id)
5915 +#define I2OEVTGET              _IOR(I2O_MAGIC_NUMBER,11,struct i2o_evt_info)
5916 +
5917 +struct i2o_cmd_hrtlct
5918 +{
5919 +       unsigned int iop;       /* IOP unit number */
5920 +       void *resbuf;           /* Buffer for result */
5921 +       unsigned int *reslen;   /* Buffer length in bytes */
5922 +};
5923 +
5924 +struct i2o_cmd_psetget
5925 +{
5926 +       unsigned int iop;       /* IOP unit number */
5927 +       unsigned int tid;       /* Target device TID */
5928 +       void *opbuf;            /* Operation List buffer */
5929 +       unsigned int oplen;     /* Operation List buffer length in bytes */
5930 +       void *resbuf;           /* Result List buffer */
5931 +       unsigned int *reslen;   /* Result List buffer length in bytes */
5932 +};
5933 +
5934 +struct i2o_sw_xfer
5935 +{
5936 +       unsigned int iop;       /* IOP unit number */
5937 +       unsigned char flags;    /* Flags field */
5938 +       unsigned char sw_type;  /* Software type */
5939 +       unsigned int sw_id;     /* Software ID */
5940 +       void *buf;              /* Pointer to software buffer */
5941 +       unsigned int *swlen;    /* Length of software data */
5942 +       unsigned int *maxfrag;  /* Maximum fragment count */
5943 +        unsigned int *curfrag; /* Current fragment count */
5944 +};
5945 +
5946 +struct i2o_html
5947 +{
5948 +       unsigned int iop;       /* IOP unit number */
5949 +       unsigned int tid;       /* Target device ID */
5950 +       unsigned int page;      /* HTML page */
5951 +       void *resbuf;           /* Buffer for reply HTML page */
5952 +       unsigned int *reslen;   /* Length in bytes of reply buffer */
5953 +       void *qbuf;             /* Pointer to HTTP query string */
5954 +       unsigned int qlen;      /* Length in bytes of query string buffer */
5955 +};
5956 +
5957 +#define I2O_EVT_Q_LEN 32
5958 +
5959 +struct i2o_evt_id
5960 +{
5961 +       unsigned int iop;
5962 +       unsigned int tid;
5963 +       unsigned int evt_mask;
5964 +};
5965 +
5966 +/* Event data size = frame size - message header + evt indicator */
5967 +#define I2O_EVT_DATA_SIZE 88
5968 +
5969 +struct i2o_evt_info
5970 +{
5971 +       struct i2o_evt_id id;
5972 +       unsigned char evt_data[I2O_EVT_DATA_SIZE];
5973 +       unsigned int data_size;
5974 +};
5975 +
5976 +struct i2o_evt_get
5977 +{
5978 +       struct i2o_evt_info info;
5979 +       int pending;
5980 +       int lost;
5981 +};
5982 +
5983 +
5984 +/**************************************************************************
5985 + * HRT related constants and structures
5986 + **************************************************************************/
5987 +#define I2O_BUS_LOCAL  0
5988 +#define I2O_BUS_ISA    1
5989 +#define I2O_BUS_EISA   2
5990 +#define I2O_BUS_MCA    3
5991 +#define I2O_BUS_PCI    4
5992 +#define I2O_BUS_PCMCIA 5
5993 +#define I2O_BUS_NUBUS  6
5994 +#define I2O_BUS_CARDBUS        7
5995 +#define I2O_BUS_UNKNOWN        0x80
5996 +
5997 +#ifndef __KERNEL__
5998 +
5999 +typedef unsigned char u8;
6000 +typedef unsigned short u16;
6001 +typedef unsigned int u32;
6002 +
6003 +#endif /* __KERNEL__ */
6004 +
6005 +typedef struct _i2o_pci_bus {
6006 +       u8 PciFunctionNumber;
6007 +       u8 PciDeviceNumber;
6008 +       u8 PciBusNumber;
6009 +       u8 reserved;
6010 +       u16 PciVendorID;
6011 +       u16 PciDeviceID;
6012 +} i2o_pci_bus;
6013 +
6014 +typedef struct _i2o_local_bus {
6015 +       u16 LbBaseIOPort;
6016 +       u16 reserved;
6017 +       u32 LbBaseMemoryAddress;
6018 +} i2o_local_bus;
6019 +
6020 +typedef struct _i2o_isa_bus {
6021 +       u16 IsaBaseIOPort;
6022 +       u8 CSN;
6023 +       u8 reserved;
6024 +       u32 IsaBaseMemoryAddress;
6025 +} i2o_isa_bus;
6026 +
6027 +typedef struct _i2o_eisa_bus_info {
6028 +       u16 EisaBaseIOPort;
6029 +       u8 reserved;
6030 +       u8 EisaSlotNumber;
6031 +       u32 EisaBaseMemoryAddress;
6032 +} i2o_eisa_bus;
6033 +
6034 +typedef struct _i2o_mca_bus {
6035 +       u16 McaBaseIOPort;
6036 +       u8 reserved;
6037 +       u8 McaSlotNumber;
6038 +       u32 McaBaseMemoryAddress;
6039 +} i2o_mca_bus;
6040 +
6041 +typedef struct _i2o_other_bus {
6042 +       u16 BaseIOPort;
6043 +       u16 reserved;
6044 +       u32 BaseMemoryAddress;
6045 +} i2o_other_bus;
6046 +
6047 +typedef struct _i2o_hrt_entry {
6048 +       u32 adapter_id;
6049 +       u32 parent_tid:12;
6050 +       u32 state:4;
6051 +       u32 bus_num:8;
6052 +       u32 bus_type:8;
6053 +       union {
6054 +               i2o_pci_bus pci_bus;
6055 +               i2o_local_bus local_bus;
6056 +               i2o_isa_bus isa_bus;
6057 +               i2o_eisa_bus eisa_bus;
6058 +               i2o_mca_bus mca_bus;
6059 +               i2o_other_bus other_bus;
6060 +       } bus;
6061 +} i2o_hrt_entry;
6062 +
6063 +typedef struct _i2o_hrt {
6064 +       u16 num_entries;
6065 +       u8 entry_len;
6066 +       u8 hrt_version;
6067 +       u32 change_ind;
6068 +       i2o_hrt_entry hrt_entry[1];
6069 +} i2o_hrt;
6070 +
6071 +typedef struct _i2o_lct_entry {
6072 +       u32 entry_size:16;
6073 +       u32 tid:12;
6074 +       u32 reserved:4;
6075 +       u32 change_ind;
6076 +       u32 device_flags;
6077 +       u32 class_id:12;
6078 +       u32 version:4;
6079 +       u32 vendor_id:16;
6080 +       u32 sub_class;
6081 +       u32 user_tid:12;
6082 +       u32 parent_tid:12;
6083 +       u32 bios_info:8;
6084 +       u8 identity_tag[8];
6085 +       u32 event_capabilities;
6086 +} i2o_lct_entry;
6087 +
6088 +typedef struct _i2o_lct {
6089 +       u32 table_size:16;
6090 +       u32 boot_tid:12;
6091 +       u32 lct_ver:4;
6092 +       u32 iop_flags;
6093 +       u32 change_ind;
6094 +       i2o_lct_entry lct_entry[1];
6095 +} i2o_lct;
6096 +
6097 +typedef struct _i2o_status_block {
6098 +       u16 org_id;
6099 +       u16 reserved;
6100 +       u16 iop_id:12;
6101 +       u16 reserved1:4;
6102 +       u16 host_unit_id;
6103 +       u16 segment_number:12;
6104 +       u16 i2o_version:4;
6105 +       u8 iop_state;
6106 +       u8 msg_type;
6107 +       u16 inbound_frame_size;
6108 +       u8 init_code;   
6109 +       u8 reserved2;
6110 +       u32 max_inbound_frames;
6111 +       u32 cur_inbound_frames;
6112 +       u32 max_outbound_frames;
6113 +       char product_id[24];    
6114 +       u32 expected_lct_size;
6115 +       u32 iop_capabilities;
6116 +       u32 desired_mem_size;
6117 +       u32 current_mem_size;
6118 +       u32 current_mem_base;
6119 +       u32 desired_io_size;
6120 +       u32 current_io_size;
6121 +       u32 current_io_base;
6122 +       u32 reserved3:24;
6123 +       u32 cmd_status:8;
6124 +} i2o_status_block;
6125
6126 +/* Event indicator mask flags */
6127 +#define I2O_EVT_IND_STATE_CHANGE               0x80000000
6128 +#define I2O_EVT_IND_GENERAL_WARNING            0x40000000
6129 +#define I2O_EVT_IND_CONFIGURATION_FLAG         0x20000000
6130 +#define I2O_EVT_IND_LOCK_RELEASE               0x10000000
6131 +#define I2O_EVT_IND_CAPABILITY_CHANGE          0x08000000
6132 +#define I2O_EVT_IND_DEVICE_RESET               0x04000000
6133 +#define I2O_EVT_IND_EVT_MASK_MODIFIED          0x02000000
6134 +#define I2O_EVT_IND_FIELD_MODIFIED             0x01000000
6135 +#define I2O_EVT_IND_VENDOR_EVT                 0x00800000
6136 +#define I2O_EVT_IND_DEVICE_STATE               0x00400000
6137 +
6138 +/* Executive event indicitors */
6139 +#define I2O_EVT_IND_EXEC_RESOURCE_LIMITS       0x00000001
6140 +#define I2O_EVT_IND_EXEC_CONNECTION_FAIL       0x00000002
6141 +#define I2O_EVT_IND_EXEC_ADAPTER_FAULT         0x00000004
6142 +#define I2O_EVT_IND_EXEC_POWER_FAIL            0x00000008
6143 +#define I2O_EVT_IND_EXEC_RESET_PENDING         0x00000010
6144 +#define I2O_EVT_IND_EXEC_RESET_IMMINENT                0x00000020
6145 +#define I2O_EVT_IND_EXEC_HW_FAIL               0x00000040
6146 +#define I2O_EVT_IND_EXEC_XCT_CHANGE            0x00000080
6147 +#define I2O_EVT_IND_EXEC_NEW_LCT_ENTRY         0x00000100
6148 +#define I2O_EVT_IND_EXEC_MODIFIED_LCT          0x00000200
6149 +#define I2O_EVT_IND_EXEC_DDM_AVAILABILITY      0x00000400
6150 +
6151 +/* Random Block Storage Event Indicators */
6152 +#define I2O_EVT_IND_BSA_VOLUME_LOAD            0x00000001
6153 +#define I2O_EVT_IND_BSA_VOLUME_UNLOAD          0x00000002
6154 +#define I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ      0x00000004
6155 +#define I2O_EVT_IND_BSA_CAPACITY_CHANGE                0x00000008
6156 +#define I2O_EVT_IND_BSA_SCSI_SMART             0x00000010
6157 +
6158 +/* Event data for generic events */
6159 +#define I2O_EVT_STATE_CHANGE_NORMAL            0x00
6160 +#define I2O_EVT_STATE_CHANGE_SUSPENDED         0x01
6161 +#define I2O_EVT_STATE_CHANGE_RESTART           0x02
6162 +#define I2O_EVT_STATE_CHANGE_NA_RECOVER                0x03
6163 +#define I2O_EVT_STATE_CHANGE_NA_NO_RECOVER     0x04
6164 +#define I2O_EVT_STATE_CHANGE_QUIESCE_REQUEST   0x05
6165 +#define I2O_EVT_STATE_CHANGE_FAILED            0x10
6166 +#define I2O_EVT_STATE_CHANGE_FAULTED           0x11
6167 +
6168 +#define I2O_EVT_GEN_WARNING_NORMAL             0x00
6169 +#define I2O_EVT_GEN_WARNING_ERROR_THRESHOLD    0x01
6170 +#define I2O_EVT_GEN_WARNING_MEDIA_FAULT                0x02
6171 +
6172 +#define I2O_EVT_CAPABILITY_OTHER               0x01
6173 +#define I2O_EVT_CAPABILITY_CHANGED             0x02
6174 +
6175 +#define I2O_EVT_SENSOR_STATE_CHANGED           0x01
6176 +
6177 +/*
6178 + *     I2O classes / subclasses
6179 + */
6180 +
6181 +/*  Class ID and Code Assignments
6182 + *  (LCT.ClassID.Version field)
6183 + */
6184 +#define    I2O_CLASS_VERSION_10                        0x00
6185 +#define    I2O_CLASS_VERSION_11                        0x01
6186 +
6187 +/*  Class code names
6188 + *  (from v1.5 Table 6-1 Class Code Assignments.)
6189 + */
6190
6191 +#define    I2O_CLASS_EXECUTIVE                         0x000
6192 +#define    I2O_CLASS_DDM                               0x001
6193 +#define    I2O_CLASS_RANDOM_BLOCK_STORAGE              0x010
6194 +#define    I2O_CLASS_SEQUENTIAL_STORAGE                0x011
6195 +#define    I2O_CLASS_LAN                               0x020
6196 +#define    I2O_CLASS_WAN                               0x030
6197 +#define    I2O_CLASS_FIBRE_CHANNEL_PORT                0x040
6198 +#define    I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL          0x041
6199 +#define    I2O_CLASS_SCSI_PERIPHERAL                   0x051
6200 +#define    I2O_CLASS_ATE_PORT                          0x060
6201 +#define    I2O_CLASS_ATE_PERIPHERAL                    0x061
6202 +#define    I2O_CLASS_FLOPPY_CONTROLLER                 0x070
6203 +#define    I2O_CLASS_FLOPPY_DEVICE                     0x071
6204 +#define    I2O_CLASS_BUS_ADAPTER_PORT                  0x080
6205 +#define    I2O_CLASS_PEER_TRANSPORT_AGENT              0x090
6206 +#define    I2O_CLASS_PEER_TRANSPORT                    0x091
6207 +
6208 +/* 
6209 + *  Rest of 0x092 - 0x09f reserved for peer-to-peer classes
6210 + */
6211
6212 +#define    I2O_CLASS_MATCH_ANYCLASS                    0xffffffff
6213 +
6214 +/* 
6215 + *  Subclasses
6216 + */
6217 +
6218 +#define    I2O_SUBCLASS_i960                           0x001
6219 +#define    I2O_SUBCLASS_HDM                            0x020
6220 +#define    I2O_SUBCLASS_ISM                            0x021
6221
6222 +/* Operation functions */
6223 +
6224 +#define I2O_PARAMS_FIELD_GET   0x0001
6225 +#define I2O_PARAMS_LIST_GET    0x0002
6226 +#define I2O_PARAMS_MORE_GET    0x0003
6227 +#define I2O_PARAMS_SIZE_GET    0x0004
6228 +#define I2O_PARAMS_TABLE_GET   0x0005
6229 +#define I2O_PARAMS_FIELD_SET   0x0006
6230 +#define I2O_PARAMS_LIST_SET    0x0007
6231 +#define I2O_PARAMS_ROW_ADD     0x0008
6232 +#define I2O_PARAMS_ROW_DELETE  0x0009
6233 +#define I2O_PARAMS_TABLE_CLEAR 0x000A
6234 +
6235 +/*
6236 + * I2O serial number conventions / formats 
6237 + * (circa v1.5)
6238 + */
6239 +
6240 +#define    I2O_SNFORMAT_UNKNOWN                        0
6241 +#define    I2O_SNFORMAT_BINARY                         1
6242 +#define    I2O_SNFORMAT_ASCII                          2
6243 +#define    I2O_SNFORMAT_UNICODE                        3
6244 +#define    I2O_SNFORMAT_LAN48_MAC                      4
6245 +#define    I2O_SNFORMAT_WAN                            5
6246 +
6247 +/* 
6248 + * Plus new in v2.0 (Yellowstone pdf doc)
6249 + */
6250 +
6251 +#define    I2O_SNFORMAT_LAN64_MAC                      6
6252 +#define    I2O_SNFORMAT_DDM                            7
6253 +#define    I2O_SNFORMAT_IEEE_REG64                     8
6254 +#define    I2O_SNFORMAT_IEEE_REG128                    9
6255 +#define    I2O_SNFORMAT_UNKNOWN2                       0xff
6256 +
6257 +/*
6258 + *     I2O Get Status State values 
6259 + */
6260 +
6261 +#define        ADAPTER_STATE_INITIALIZING              0x01
6262 +#define        ADAPTER_STATE_RESET                     0x02
6263 +#define        ADAPTER_STATE_HOLD                      0x04
6264 +#define        ADAPTER_STATE_READY                     0x05
6265 +#define        ADAPTER_STATE_OPERATIONAL               0x08
6266 +#define        ADAPTER_STATE_FAILED                    0x10
6267 +#define        ADAPTER_STATE_FAULTED                   0x11
6268 +       
6269 +#endif /* _I2O_DEV_H */
6270 --- /dev/null   Sat Apr 14 07:06:21 2001
6271 +++ linux/drivers/scsi/dpti_i2o.h       Wed Jul 18 14:31:28 2001
6272 @@ -0,0 +1,660 @@
6273 +#ifndef _I2O_H
6274 +#define _I2O_H
6275 +/* I2O kernel space accessible structures/APIs
6276 + *
6277 + * (c) Copyright 1999, 2000 Red Hat Software
6278 + *
6279 + * This program is free software; you can redistribute it and/or
6280 + * modify it under the terms of the GNU General Public License
6281 + * as published by the Free Software Foundation; either version
6282 + * 2 of the License, or (at your option) any later version.
6283 + *
6284 + *************************************************************************
6285 + *
6286 + * This header file defined the I2O APIs/structures for use by
6287 + * the I2O kernel modules.
6288 + *
6289 + */
6290 +
6291 +#ifdef __KERNEL__       /* This file to be included by kernel only */
6292 +
6293 +#include "dpti_i2o-dev.h"
6294 +
6295 +#include <asm/semaphore.h> /* Needed for MUTEX init macros */
6296 +#include <linux/config.h>
6297 +#include <linux/notifier.h>
6298 +#include <asm/atomic.h>
6299 +
6300 +
6301 +/*
6302 + *     Tunable parameters first
6303 + */
6304 +
6305 +/* How many different OSM's are we allowing */ 
6306 +#define MAX_I2O_MODULES                64
6307 +
6308 +#define I2O_EVT_CAPABILITY_OTHER               0x01
6309 +#define I2O_EVT_CAPABILITY_CHANGED             0x02
6310 +
6311 +#define I2O_EVT_SENSOR_STATE_CHANGED           0x01
6312 +
6313 +//#ifdef __KERNEL__   /* ioctl stuff only thing exported to users */
6314 +
6315 +#define I2O_MAX_MANAGERS       4
6316 +
6317 +#include <asm/semaphore.h> /* Needed for MUTEX init macros */
6318 +
6319 +/*
6320 + *     I2O Interface Objects
6321 + */
6322 +
6323 +#include <linux/config.h>
6324 +#include <linux/notifier.h>
6325 +#include <asm/atomic.h>
6326 +
6327 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
6328 +
6329 +#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
6330 +
6331 +typedef struct wait_queue *adpt_wait_queue_head_t;
6332 +#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) adpt_wait_queue_head_t wait = NULL
6333 +typedef struct wait_queue adpt_wait_queue_t;
6334 +#else
6335 +
6336 +#include <linux/wait.h>
6337 +typedef wait_queue_head_t adpt_wait_queue_head_t;
6338 +#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait)
6339 +typedef wait_queue_t adpt_wait_queue_t;
6340 +
6341 +#endif
6342 +/*
6343 + * message structures
6344 + */
6345 +
6346 +struct i2o_message
6347 +{
6348 +       u8      version_offset;
6349 +       u8      flags;
6350 +       u16     size;
6351 +       u32     target_tid:12;
6352 +       u32     init_tid:12;
6353 +       u32     function:8;     
6354 +       u32     initiator_context;
6355 +       /* List follows */
6356 +};
6357 +
6358 +/*
6359 + *     Each I2O device entity has one or more of these. There is one
6360 + *     per device. *FIXME* how to handle multiple types on one unit.
6361 + */
6362
6363 +struct i2o_device
6364 +{
6365 +       i2o_lct_entry lct_data;/* Device LCT information */
6366 +       u32 flags;              
6367 +       int i2oversion;         /* I2O version supported. Actually there
6368 +                                * should be high and low version */
6369 +
6370 +       struct proc_dir_entry* proc_entry;      /* /proc dir */
6371 +
6372 +       /* Primary user */
6373 +       struct i2o_handler *owner;
6374 +
6375 +       /* Management users */
6376 +       struct i2o_handler *managers[I2O_MAX_MANAGERS];         
6377 +       int num_managers;
6378 +
6379 +       struct i2o_controller *controller;      /* Controlling IOP */
6380 +       struct i2o_device *next;        /* Chain */
6381 +       struct i2o_device *prev;
6382 +       char dev_name[8];               /* linux /dev name if available */
6383 +};
6384 +
6385 +/*
6386 + *     Resource data for each PCI I2O controller
6387 + */            
6388 +struct i2o_pci
6389 +{
6390 +       int irq;
6391 +#ifdef CONFIG_MTRR
6392 +       int mtrr_reg0;
6393 +       int mtrr_reg1;
6394 +#endif
6395 +};
6396 +
6397 +
6398 +/*
6399 + *     Each I2O controller has one of these objects
6400 + */
6401
6402 +struct i2o_controller
6403 +{
6404 +       char name[16];
6405 +       int unit;
6406 +       int type;
6407 +       int enabled;
6408 +
6409 +#define I2O_TYPE_PCI           0x01            /* PCI I2O controller */        
6410 +
6411 +       struct notifier_block *event_notifer;   /* Events */
6412 +       atomic_t users;
6413 +       struct i2o_device *devices;             /* I2O device chain */
6414 +       struct i2o_controller *next;            /* Controller chain */
6415 +       volatile u32 *post_port;                /* Messaging ports */
6416 +       volatile u32 *reply_port;
6417 +       volatile u32 *irq_mask;                 /* Interrupt port */
6418 +
6419 +        /* Dynamic LCT related data */
6420 +        struct semaphore lct_sem;
6421 +        int lct_pid;
6422 +        int lct_running;
6423 +
6424 +       i2o_status_block *status_block;         /* IOP status block */
6425 +       i2o_lct *lct;                           /* Logical Config Table */
6426 +       i2o_lct *dlct;                          /* Temp LCT */
6427 +       i2o_hrt *hrt;
6428 +
6429 +       u32 mem_offset;                         /* MFA offset */
6430 +       u32 mem_phys;                           /* MFA physical */
6431 +
6432 +       u32 priv_mem;
6433 +       u32 priv_mem_size;
6434 +       u32 priv_io;
6435 +       u32 priv_io_size;
6436 +
6437 +       struct proc_dir_entry* proc_entry;      /* /proc dir */
6438 +
6439 +       union
6440 +       {                                       /* Bus information */
6441 +               struct i2o_pci pci;
6442 +       } bus;
6443 +       /* Bus specific destructor */
6444 +       void (*destructor)(struct i2o_controller *);            
6445 +       /* Bus specific attach/detach */
6446 +       int (*bind)(struct i2o_controller *, struct i2o_device *);      
6447 +       /* Bus specific initiator */
6448 +       int (*unbind)(struct i2o_controller *, struct i2o_device *);
6449 +       /* Bus specific enable/disable */
6450 +       void (*bus_enable)(struct i2o_controller *c);
6451 +       void (*bus_disable)(struct i2o_controller *c);
6452 +
6453 +       void *page_frame;               /* Message buffers */
6454 +       int inbound_size;               /* Inbound queue size */
6455 +};
6456 +
6457 +struct i2o_handler
6458 +{
6459 +        /* Message reply handler */
6460 +
6461 +       void (*reply)(struct i2o_handler *, struct i2o_controller *, struct i2o_message *);
6462 +
6463 +        /* New device notification handler */
6464 +        void (*new_dev_notify)(struct i2o_controller *, struct i2o_device *);
6465 +
6466 +        /* Device deltion handler */
6467 +        void (*dev_del_notify)(struct i2o_controller *, struct i2o_device *);
6468 +
6469 +        /* Reboot notification handler */
6470 +        void (*reboot_notify)(void);
6471 +
6472 +       char *name;
6473 +       int context;            /* Low 8 bits of the transaction info */
6474 +       u32 class;                      /* I2O classes that this driver handles */
6475 +       /* User data follows */
6476 +};
6477 +
6478 +#ifdef MODULE
6479 +/*
6480 + * Used by bus specific modules to communicate with the core
6481 + *
6482 + * This is needed because the bus modules cannot make direct
6483 + * calls to the core as this results in the i2o_bus_specific_module
6484 + * being dependent on the core, not the otherway around.
6485 + * In that case, a 'modprobe i2o_lan' loads i2o_core & i2o_lan,
6486 + * but _not_ i2o_pci...which makes the whole thing pretty useless :)
6487 + *
6488 + */
6489 +struct i2o_core_func_table
6490 +{
6491 +       int     (*install)(struct i2o_controller *);
6492 +       int     (*activate)(struct i2o_controller *);
6493 +       struct  i2o_controller* (*find)(int);
6494 +       void    (*unlock)(struct i2o_controller *);
6495 +       void    (*run_queue)(struct i2o_controller *c);
6496 +       int     (*delete)(struct i2o_controller *);
6497 +};
6498 +#endif
6499 +
6500 +/*
6501 + * I2O System table entry
6502 + */
6503 +struct i2o_sys_tbl_entry
6504 +{
6505 +       u16     org_id;
6506 +       u16     reserved1;
6507 +       u32     iop_id:12;
6508 +       u32     reserved2:20;
6509 +       u16     seg_num:12;
6510 +       u16     i2o_version:4;
6511 +       u8      iop_state;
6512 +       u8      msg_type;
6513 +       u16     frame_size;
6514 +       u16     reserved3;
6515 +       u32     last_changed;
6516 +       u32     iop_capabilities;
6517 +       u32     inbound_low;
6518 +       u32     inbound_high;
6519 +};
6520 +
6521 +struct i2o_sys_tbl
6522 +{
6523 +       u8      num_entries;
6524 +       u8      version;
6525 +       u16     reserved1;
6526 +       u32     change_ind;
6527 +       u32     reserved2;
6528 +       u32     reserved3;
6529 +       struct i2o_sys_tbl_entry iops[0];
6530 +};     
6531 +
6532 +/*
6533 + *     Messenger inlines
6534 + */
6535 +extern inline u32 I2O_POST_READ32(struct i2o_controller *c)
6536 +{
6537 +       return *c->post_port;
6538 +}
6539 +
6540 +extern inline void I2O_POST_WRITE32(struct i2o_controller *c, u32 Val)
6541 +{
6542 +       *c->post_port = Val;
6543 +}
6544 +
6545 +
6546 +extern inline u32 I2O_REPLY_READ32(struct i2o_controller *c)
6547 +{
6548 +       return *c->reply_port;
6549 +}
6550 +
6551 +extern inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 Val)
6552 +{
6553 +       *c->reply_port= Val;
6554 +}
6555
6556 +
6557 +extern inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
6558 +{
6559 +       return *c->irq_mask;
6560 +}
6561 +
6562 +extern inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 Val)
6563 +{
6564 +       *c->irq_mask = Val;
6565 +}
6566 +
6567 +
6568 +extern inline void i2o_post_message(struct i2o_controller *c, u32 m)
6569 +{
6570 +       /* The second line isnt spurious - thats forcing PCI posting */
6571 +       I2O_POST_WRITE32(c,m);
6572 +       (void) I2O_IRQ_READ32(c);
6573 +}
6574 +
6575 +extern inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
6576 +{
6577 +       I2O_REPLY_WRITE32(c,m);
6578 +}
6579 +
6580 +extern int i2o_install_controller(struct i2o_controller *);
6581 +extern int i2o_delete_controller(struct i2o_controller *);
6582 +extern void i2o_unlock_controller(struct i2o_controller *);
6583 +extern struct i2o_controller *i2o_find_controller(int);
6584 +extern int i2o_status_get(struct i2o_controller *);
6585 +extern int i2o_num_controllers;
6586 +
6587 +extern int i2o_install_handler(struct i2o_handler *);
6588 +extern int i2o_remove_handler(struct i2o_handler *);
6589 +
6590 +extern int i2o_claim_device(struct i2o_device *, struct i2o_handler *);
6591 +extern int i2o_release_device(struct i2o_device *, struct i2o_handler *);
6592 +extern int i2o_device_notify_on(struct i2o_device *, struct i2o_handler *);
6593 +extern int i2o_device_notify_off(struct i2o_device *, struct i2o_handler *);
6594 +
6595 +extern int i2o_post_this(struct i2o_controller *, u32 *, int);
6596 +extern int i2o_post_wait(struct i2o_controller *, u32 *, int, int);
6597 +extern int i2o_issue_params(int, struct i2o_controller *, int, void *,
6598 +                           int, void *, int); 
6599 +
6600 +extern int i2o_query_scalar(struct i2o_controller *, int, int, int, void *, int);
6601 +extern int i2o_set_scalar(struct i2o_controller *, int, int, int, void *, int);
6602 +
6603 +extern int i2o_query_table(int, struct i2o_controller *, int, int, int, void *,
6604 +                          int, void *, int);
6605 +extern int i2o_clear_table(struct i2o_controller *, int, int); 
6606 +extern int i2o_row_add_table(struct i2o_controller *, int, int, int, void *,
6607 +                            int);
6608 +extern int i2o_row_delete_table(struct i2o_controller *, int, int, int, void *,                        int);
6609 +
6610 +extern int i2o_event_register(struct i2o_controller *, u32, u32,u32, u32); 
6611 +extern int i2o_event_ack(struct i2o_controller *,  u32 *);
6612 +
6613 +extern void i2o_run_queue(struct i2o_controller *);
6614 +extern void i2o_report_status(const char *, const char *, u32 *);
6615 +extern void i2o_dump_message(u32 *);
6616 +
6617 +extern const char *i2o_get_class_name(int);
6618 +
6619 +
6620 +/*
6621 + *     I2O classes / subclasses
6622 + */
6623 +
6624 +/*  Class ID and Code Assignments
6625 + *  (LCT.ClassID.Version field)
6626 + */
6627 +#define    I2O_CLASS_VERSION_10                        0x00
6628 +#define    I2O_CLASS_VERSION_11                        0x01
6629 +
6630 +/*  Class code names
6631 + *  (from v1.5 Table 6-1 Class Code Assignments.)
6632 + */
6633
6634 +#define    I2O_CLASS_EXECUTIVE                         0x000
6635 +#define    I2O_CLASS_DDM                               0x001
6636 +#define    I2O_CLASS_RANDOM_BLOCK_STORAGE              0x010
6637 +#define    I2O_CLASS_SEQUENTIAL_STORAGE                0x011
6638 +#define    I2O_CLASS_LAN                               0x020
6639 +#define    I2O_CLASS_WAN                               0x030
6640 +#define    I2O_CLASS_FIBRE_CHANNEL_PORT                0x040
6641 +#define    I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL          0x041
6642 +#define    I2O_CLASS_SCSI_PERIPHERAL                   0x051
6643 +#define    I2O_CLASS_ATE_PORT                          0x060
6644 +#define    I2O_CLASS_ATE_PERIPHERAL                    0x061
6645 +#define    I2O_CLASS_FLOPPY_CONTROLLER                 0x070
6646 +#define    I2O_CLASS_FLOPPY_DEVICE                     0x071
6647 +#define    I2O_CLASS_BUS_ADAPTER_PORT                  0x080
6648 +#define    I2O_CLASS_PEER_TRANSPORT_AGENT              0x090
6649 +#define    I2O_CLASS_PEER_TRANSPORT                    0x091
6650 +
6651 +/*  Rest of 0x092 - 0x09f reserved for peer-to-peer classes
6652 + */
6653
6654 +#define    I2O_CLASS_MATCH_ANYCLASS                    0xffffffff
6655 +
6656 +/*  Subclasses
6657 + */
6658 +
6659 +#define    I2O_SUBCLASS_i960                           0x001
6660 +#define    I2O_SUBCLASS_HDM                            0x020
6661 +#define    I2O_SUBCLASS_ISM                            0x021
6662
6663 +/* Operation functions */
6664 +
6665 +#define I2O_PARAMS_FIELD_GET   0x0001
6666 +#define I2O_PARAMS_LIST_GET    0x0002
6667 +#define I2O_PARAMS_MORE_GET    0x0003
6668 +#define I2O_PARAMS_SIZE_GET    0x0004
6669 +#define I2O_PARAMS_TABLE_GET   0x0005
6670 +#define I2O_PARAMS_FIELD_SET   0x0006
6671 +#define I2O_PARAMS_LIST_SET    0x0007
6672 +#define I2O_PARAMS_ROW_ADD     0x0008
6673 +#define I2O_PARAMS_ROW_DELETE  0x0009
6674 +#define I2O_PARAMS_TABLE_CLEAR 0x000A
6675 +
6676 +/*
6677 + *     I2O serial number conventions / formats
6678 + *     (circa v1.5)
6679 + */
6680 +
6681 +#define    I2O_SNFORMAT_UNKNOWN                        0
6682 +#define    I2O_SNFORMAT_BINARY                         1
6683 +#define    I2O_SNFORMAT_ASCII                          2
6684 +#define    I2O_SNFORMAT_UNICODE                        3
6685 +#define    I2O_SNFORMAT_LAN48_MAC                      4
6686 +#define    I2O_SNFORMAT_WAN                            5
6687 +
6688 +/* Plus new in v2.0 (Yellowstone pdf doc)
6689 + */
6690 +
6691 +#define    I2O_SNFORMAT_LAN64_MAC                      6
6692 +#define    I2O_SNFORMAT_DDM                            7
6693 +#define    I2O_SNFORMAT_IEEE_REG64                     8
6694 +#define    I2O_SNFORMAT_IEEE_REG128                    9
6695 +#define    I2O_SNFORMAT_UNKNOWN2                       0xff
6696 +
6697 +/* Transaction Reply Lists (TRL) Control Word structure */
6698 +
6699 +#define TRL_SINGLE_FIXED_LENGTH                0x00
6700 +#define TRL_SINGLE_VARIABLE_LENGTH     0x40
6701 +#define TRL_MULTIPLE_FIXED_LENGTH      0x80
6702 +
6703 +/*
6704 + *     Messaging API values
6705 + */
6706
6707 +#define        I2O_CMD_ADAPTER_ASSIGN          0xB3
6708 +#define        I2O_CMD_ADAPTER_READ            0xB2
6709 +#define        I2O_CMD_ADAPTER_RELEASE         0xB5
6710 +#define        I2O_CMD_BIOS_INFO_SET           0xA5
6711 +#define        I2O_CMD_BOOT_DEVICE_SET         0xA7
6712 +#define        I2O_CMD_CONFIG_VALIDATE         0xBB
6713 +#define        I2O_CMD_CONN_SETUP              0xCA
6714 +#define        I2O_CMD_DDM_DESTROY             0xB1
6715 +#define        I2O_CMD_DDM_ENABLE              0xD5
6716 +#define        I2O_CMD_DDM_QUIESCE             0xC7
6717 +#define        I2O_CMD_DDM_RESET               0xD9
6718 +#define        I2O_CMD_DDM_SUSPEND             0xAF
6719 +#define        I2O_CMD_DEVICE_ASSIGN           0xB7
6720 +#define        I2O_CMD_DEVICE_RELEASE          0xB9
6721 +#define        I2O_CMD_HRT_GET                 0xA8
6722 +#define        I2O_CMD_ADAPTER_CLEAR           0xBE
6723 +#define        I2O_CMD_ADAPTER_CONNECT         0xC9
6724 +#define        I2O_CMD_ADAPTER_RESET           0xBD
6725 +#define        I2O_CMD_LCT_NOTIFY              0xA2
6726 +#define        I2O_CMD_OUTBOUND_INIT           0xA1
6727 +#define        I2O_CMD_PATH_ENABLE             0xD3
6728 +#define        I2O_CMD_PATH_QUIESCE            0xC5
6729 +#define        I2O_CMD_PATH_RESET              0xD7
6730 +#define        I2O_CMD_STATIC_MF_CREATE        0xDD
6731 +#define        I2O_CMD_STATIC_MF_RELEASE       0xDF
6732 +#define        I2O_CMD_STATUS_GET              0xA0
6733 +#define        I2O_CMD_SW_DOWNLOAD             0xA9
6734 +#define        I2O_CMD_SW_UPLOAD               0xAB
6735 +#define        I2O_CMD_SW_REMOVE               0xAD
6736 +#define        I2O_CMD_SYS_ENABLE              0xD1
6737 +#define        I2O_CMD_SYS_MODIFY              0xC1
6738 +#define        I2O_CMD_SYS_QUIESCE             0xC3
6739 +#define        I2O_CMD_SYS_TAB_SET             0xA3
6740 +
6741 +#define I2O_CMD_UTIL_NOP               0x00
6742 +#define I2O_CMD_UTIL_ABORT             0x01
6743 +#define I2O_CMD_UTIL_CLAIM             0x09
6744 +#define I2O_CMD_UTIL_RELEASE           0x0B
6745 +#define I2O_CMD_UTIL_PARAMS_GET                0x06
6746 +#define I2O_CMD_UTIL_PARAMS_SET                0x05
6747 +#define I2O_CMD_UTIL_EVT_REGISTER      0x13
6748 +#define I2O_CMD_UTIL_EVT_ACK           0x14
6749 +#define I2O_CMD_UTIL_CONFIG_DIALOG     0x10
6750 +#define I2O_CMD_UTIL_DEVICE_RESERVE    0x0D
6751 +#define I2O_CMD_UTIL_DEVICE_RELEASE    0x0F
6752 +#define I2O_CMD_UTIL_LOCK              0x17
6753 +#define I2O_CMD_UTIL_LOCK_RELEASE      0x19
6754 +#define I2O_CMD_UTIL_REPLY_FAULT_NOTIFY        0x15
6755 +
6756 +#define I2O_CMD_SCSI_EXEC              0x81
6757 +#define I2O_CMD_SCSI_ABORT             0x83
6758 +#define I2O_CMD_SCSI_BUSRESET          0x27
6759 +
6760 +#define I2O_CMD_BLOCK_READ             0x30
6761 +#define I2O_CMD_BLOCK_WRITE            0x31
6762 +#define I2O_CMD_BLOCK_CFLUSH           0x37
6763 +#define I2O_CMD_BLOCK_MLOCK            0x49
6764 +#define I2O_CMD_BLOCK_MUNLOCK          0x4B
6765 +#define I2O_CMD_BLOCK_MMOUNT           0x41
6766 +#define I2O_CMD_BLOCK_MEJECT           0x43
6767 +
6768 +#define I2O_PRIVATE_MSG                        0xFF
6769 +
6770 +/*
6771 + *     Init Outbound Q status 
6772 + */
6773
6774 +#define I2O_CMD_OUTBOUND_INIT_IN_PROGRESS      0x01
6775 +#define I2O_CMD_OUTBOUND_INIT_REJECTED         0x02
6776 +#define I2O_CMD_OUTBOUND_INIT_FAILED           0x03
6777 +#define I2O_CMD_OUTBOUND_INIT_COMPLETE         0x04
6778 +
6779 +/*
6780 + *     I2O Get Status State values 
6781 + */
6782 +
6783 +#define        ADAPTER_STATE_INITIALIZING              0x01
6784 +#define        ADAPTER_STATE_RESET                     0x02
6785 +#define        ADAPTER_STATE_HOLD                      0x04
6786 +#define ADAPTER_STATE_READY                    0x05
6787 +#define        ADAPTER_STATE_OPERATIONAL               0x08
6788 +#define        ADAPTER_STATE_FAILED                    0x10
6789 +#define        ADAPTER_STATE_FAULTED                   0x11
6790 +       
6791 +/* I2O API function return values */
6792 +
6793 +#define I2O_RTN_NO_ERROR                       0
6794 +#define I2O_RTN_NOT_INIT                       1
6795 +#define I2O_RTN_FREE_Q_EMPTY                   2
6796 +#define I2O_RTN_TCB_ERROR                      3
6797 +#define I2O_RTN_TRANSACTION_ERROR              4
6798 +#define I2O_RTN_ADAPTER_ALREADY_INIT           5
6799 +#define I2O_RTN_MALLOC_ERROR                   6
6800 +#define I2O_RTN_ADPTR_NOT_REGISTERED           7
6801 +#define I2O_RTN_MSG_REPLY_TIMEOUT              8
6802 +#define I2O_RTN_NO_STATUS                      9
6803 +#define I2O_RTN_NO_FIRM_VER                    10
6804 +#define        I2O_RTN_NO_LINK_SPEED                   11
6805 +
6806 +/* Reply message status defines for all messages */
6807 +
6808 +#define I2O_REPLY_STATUS_SUCCESS                       0x00
6809 +#define I2O_REPLY_STATUS_ABORT_DIRTY                   0x01
6810 +#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER        0x02
6811 +#define        I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER         0x03
6812 +#define        I2O_REPLY_STATUS_ERROR_DIRTY                    0x04
6813 +#define        I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER         0x05
6814 +#define        I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER         0x06
6815 +#define        I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY            0x08
6816 +#define        I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09
6817 +#define        I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A
6818 +#define        I2O_REPLY_STATUS_TRANSACTION_ERROR              0x0B
6819 +#define        I2O_REPLY_STATUS_PROGRESS_REPORT                0x80
6820 +
6821 +/* Status codes and Error Information for Parameter functions */
6822 +
6823 +#define I2O_PARAMS_STATUS_SUCCESS              0x00
6824 +#define I2O_PARAMS_STATUS_BAD_KEY_ABORT                0x01
6825 +#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE     0x02
6826 +#define I2O_PARAMS_STATUS_BUFFER_FULL          0x03
6827 +#define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL     0x04
6828 +#define I2O_PARAMS_STATUS_FIELD_UNREADABLE     0x05
6829 +#define I2O_PARAMS_STATUS_FIELD_UNWRITEABLE    0x06
6830 +#define I2O_PARAMS_STATUS_INSUFFICIENT_FIELDS  0x07
6831 +#define I2O_PARAMS_STATUS_INVALID_GROUP_ID     0x08
6832 +#define I2O_PARAMS_STATUS_INVALID_OPERATION    0x09
6833 +#define I2O_PARAMS_STATUS_NO_KEY_FIELD         0x0A
6834 +#define I2O_PARAMS_STATUS_NO_SUCH_FIELD                0x0B
6835 +#define I2O_PARAMS_STATUS_NON_DYNAMIC_GROUP    0x0C
6836 +#define I2O_PARAMS_STATUS_OPERATION_ERROR      0x0D
6837 +#define I2O_PARAMS_STATUS_SCALAR_ERROR         0x0E
6838 +#define I2O_PARAMS_STATUS_TABLE_ERROR          0x0F
6839 +#define I2O_PARAMS_STATUS_WRONG_GROUP_TYPE     0x10
6840 +
6841 +/* DetailedStatusCode defines for Executive, DDM, Util and Transaction error
6842 + * messages: Table 3-2 Detailed Status Codes.*/
6843 +
6844 +#define I2O_DSC_SUCCESS                        0x0000
6845 +#define I2O_DSC_BAD_KEY                        0x0002
6846 +#define I2O_DSC_TCL_ERROR                      0x0003
6847 +#define I2O_DSC_REPLY_BUFFER_FULL              0x0004
6848 +#define I2O_DSC_NO_SUCH_PAGE                   0x0005
6849 +#define I2O_DSC_INSUFFICIENT_RESOURCE_SOFT     0x0006
6850 +#define I2O_DSC_INSUFFICIENT_RESOURCE_HARD     0x0007
6851 +#define I2O_DSC_CHAIN_BUFFER_TOO_LARGE         0x0009
6852 +#define I2O_DSC_UNSUPPORTED_FUNCTION           0x000A
6853 +#define I2O_DSC_DEVICE_LOCKED                  0x000B
6854 +#define I2O_DSC_DEVICE_RESET                   0x000C
6855 +#define I2O_DSC_INAPPROPRIATE_FUNCTION         0x000D
6856 +#define I2O_DSC_INVALID_INITIATOR_ADDRESS      0x000E
6857 +#define I2O_DSC_INVALID_MESSAGE_FLAGS          0x000F
6858 +#define I2O_DSC_INVALID_OFFSET                 0x0010
6859 +#define I2O_DSC_INVALID_PARAMETER              0x0011
6860 +#define I2O_DSC_INVALID_REQUEST                0x0012
6861 +#define I2O_DSC_INVALID_TARGET_ADDRESS         0x0013
6862 +#define I2O_DSC_MESSAGE_TOO_LARGE              0x0014
6863 +#define I2O_DSC_MESSAGE_TOO_SMALL              0x0015
6864 +#define I2O_DSC_MISSING_PARAMETER              0x0016
6865 +#define I2O_DSC_TIMEOUT                        0x0017
6866 +#define I2O_DSC_UNKNOWN_ERROR                  0x0018
6867 +#define I2O_DSC_UNKNOWN_FUNCTION               0x0019
6868 +#define I2O_DSC_UNSUPPORTED_VERSION            0x001A
6869 +#define I2O_DSC_DEVICE_BUSY                    0x001B
6870 +#define I2O_DSC_DEVICE_NOT_AVAILABLE           0x001C
6871 +
6872 +/* Device Claim Types */
6873 +#define        I2O_CLAIM_PRIMARY                                       0x01000000
6874 +#define        I2O_CLAIM_MANAGEMENT                                    0x02000000
6875 +#define        I2O_CLAIM_AUTHORIZED                                    0x03000000
6876 +#define        I2O_CLAIM_SECONDARY                                     0x04000000
6877
6878 +/* Message header defines for VersionOffset */
6879 +#define I2OVER15       0x0001
6880 +#define I2OVER20       0x0002
6881 +/* Default is 1.5, FIXME: Need support for both 1.5 and 2.0 */
6882 +#define I2OVERSION     I2OVER15
6883 +#define SGL_OFFSET_0    I2OVERSION
6884 +#define SGL_OFFSET_4    (0x0040 | I2OVERSION)
6885 +#define SGL_OFFSET_5    (0x0050 | I2OVERSION)
6886 +#define SGL_OFFSET_6    (0x0060 | I2OVERSION)
6887 +#define SGL_OFFSET_7    (0x0070 | I2OVERSION)
6888 +#define SGL_OFFSET_8    (0x0080 | I2OVERSION)
6889 +#define SGL_OFFSET_9    (0x0090 | I2OVERSION)
6890 +#define SGL_OFFSET_10   (0x00A0 | I2OVERSION)
6891 +#define SGL_OFFSET_12   (0x00C0 | I2OVERSION)
6892 +
6893 +#define TRL_OFFSET_5    (0x0050 | I2OVERSION)
6894 +#define TRL_OFFSET_6    (0x0060 | I2OVERSION)
6895 +
6896 + /* msg header defines for MsgFlags */
6897 +#define MSG_STATIC     0x0100
6898 +#define MSG_64BIT_CNTXT        0x0200
6899 +#define MSG_MULTI_TRANS        0x1000
6900 +#define MSG_FAIL       0x2000
6901 +#define MSG_LAST       0x4000
6902 +#define MSG_REPLY      0x8000
6903 +
6904 + /* minimum size msg */
6905 +#define THREE_WORD_MSG_SIZE    0x00030000
6906 +#define FOUR_WORD_MSG_SIZE     0x00040000
6907 +#define FIVE_WORD_MSG_SIZE     0x00050000
6908 +#define SIX_WORD_MSG_SIZE      0x00060000
6909 +#define SEVEN_WORD_MSG_SIZE    0x00070000
6910 +#define EIGHT_WORD_MSG_SIZE    0x00080000
6911 +#define NINE_WORD_MSG_SIZE     0x00090000
6912 +#define TEN_WORD_MSG_SIZE      0x000A0000
6913 +#define I2O_MESSAGE_SIZE(x)    ((x)<<16)
6914 +
6915 +
6916 +/* Special TID Assignments */
6917 +
6918 +#define ADAPTER_TID            0
6919 +#define HOST_TID               1
6920 +
6921 +#define MSG_FRAME_SIZE         128
6922 +#define NMBR_MSG_FRAMES                128
6923 +
6924 +#define MSG_POOL_SIZE          16384
6925 +
6926 +#define I2O_POST_WAIT_OK       0
6927 +#define I2O_POST_WAIT_TIMEOUT  -ETIMEDOUT
6928 +
6929 +
6930 +#endif /* __KERNEL__ */
6931 +
6932 +#endif /* _I2O_H */
6933 --- /usr/src/linux-orig/drivers/scsi/Makefile   Sun Mar 25 11:37:35 2001
6934 +++ linux/drivers/scsi/Makefile Fri May  4 12:08:56 2001
6935 @@ -407,6 +407,14 @@
6936    endif
6937  endif
6938  
6939 +ifeq ($(CONFIG_SCSI_DPT_I2O),y)
6940 +L_OBJS += dpt_i2o.o
6941 +else
6942 +  ifeq ($(CONFIG_SCSI_DPT_I2O),m)
6943 +  M_OBJS += dpt_i2o.o
6944 +  endif
6945 +endif
6946 +
6947  ifeq ($(CONFIG_SCSI_EATA_DMA),y)
6948  L_OBJS += eata_dma.o
6949  else
6950 @@ -748,4 +756,7 @@
6951  
6952  sd_mod.o: sd.o sd_ioctl.o
6953         $(LD) $(LD_RFLAG) -r -o $@ sd.o sd_ioctl.o
6954 +
6955 +dpt_i2o.o: dpti.c
6956 +       $(CC) $(CFLAGS) -c dpti.c -o dpt_i2o.o
6957  
6958 --- /usr/src/linux-orig/drivers/scsi/Config.in  Sun Mar 25 11:37:35 2001
6959 +++ linux/drivers/scsi/Config.in        Fri May  4 12:09:23 2001
6960 @@ -33,6 +33,7 @@
6961      int  '   Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 24
6962      bool '   Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS
6963  fi
6964 +dep_tristate 'Adaptec I2O RAID support ' CONFIG_SCSI_DPT_I2O $CONFIG_SCSI
6965  dep_tristate 'IBM ServeRAID support' CONFIG_SCSI_IPS $CONFIG_SCSI
6966  dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
6967  dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI
6968 --- /usr/src/linux-orig/drivers/scsi/hosts.c    Sun Mar 25 11:37:36 2001
6969 +++ linux/drivers/scsi/hosts.c  Fri May  4 12:10:24 2001
6970 @@ -147,6 +147,10 @@
6971  #include "BusLogic.h"
6972  #endif
6973  
6974 +#ifdef CONFIG_SCSI_DPT_I2O
6975 +#include "dpti.h"
6976 +#endif
6977 +
6978  #ifdef CONFIG_SCSI_EATA_DMA
6979  #include "eata_dma.h"
6980  #endif
6981 @@ -549,6 +553,9 @@
6982  #endif
6983  #ifdef CONFIG_SCSI_NCR53C8XX
6984      NCR53C8XX,
6985 +#endif
6986 +#ifdef CONFIG_SCSI_DPT_I2O
6987 +    DPT_I2O,
6988  #endif
6989  #ifdef CONFIG_SCSI_EATA_DMA
6990      EATA_DMA,
This page took 0.513987 seconds and 3 git commands to generate.