1 --- /dev/null Sat Apr 14 07:06:21 2001
2 +++ linux/drivers/scsi/dpti.c Wed Jul 18 14:31:28 2001
4 +/***************************************************************************
7 + begin : Thu Sep 7 2001
8 + copyright : (C) 2000 by Adaptec
9 + email : deanna_bonds@adaptec.com
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.
19 + See README.dpti for history, notes, license info, and credits
20 + ***************************************************************************/
22 +/***************************************************************************
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. *
29 + ***************************************************************************/
32 +//#define UARTDELAY 1
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
40 +//#define ADDR32 GFP_DMA
42 +#include <linux/autoconf.h>
43 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
47 +#if defined MODVERSIONS && defined MODULE
48 +# include <linux/modversions.h>
51 +#include <linux/version.h>
54 +#include <linux/module.h>
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;
62 +////////////////////////////////////////////////////////////////
64 +#include <linux/ioctl.h> /* For SCSI-Passthrough */
65 +#include <asm/uaccess.h>
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>
81 +#include <linux/timer.h>
82 +#include <linux/string.h>
83 +#include <linux/ioport.h>
84 +#include <linux/stat.h>
86 +#include <asm/processor.h> /* for boot_cpu_data */
87 +#include <asm/pgtable.h>
88 +#include <asm/io.h> /* for virt_to_bus, etc. */
97 +/* Create a binary signature */
98 +static dpt_sig_S DPTI_sig = {
99 + {'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
101 + PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
102 +#elif defined __ia64__
103 + PROC_INTEL, PROC_IA64,
104 +#elif define __sparc__
106 +#elif defined(__alpha__)
109 +#error This has not been ported to your architecture
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"
116 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
117 +static struct semaphore adpt_configuration_lock = MUTEX;
119 +DECLARE_MUTEX(adpt_configuration_lock);
121 +static struct i2o_sys_tbl *sys_tbl = NULL;
122 +static int sys_tbl_ind = 0;
123 +static int sys_tbl_len = 0;
125 + * The method for determining if PCI is present was changed in the 2.1.xx tree.
127 +#define NEWPCI_VERSION KERNEL_VERSION(2,1,92)
129 +static adpt_hba* hbas[DPTI_MAX_HBA];
130 +static adpt_hba* hba_chain = NULL;
131 +static int hba_count = 0;
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;
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
148 +static struct file_operations adpt_fops = {
151 + release: adpt_close
154 +#ifdef REBOOT_NOTIFIER
155 +static struct notifier_block adpt_reboot_notifier =
163 +inline u32 adpt_getBlinkLED(adpt_hba* host)
165 + return (host->FwDebugBLEDflag_P && (volatile u32)(*(host->FwDebugBLEDflag_P)) == 0xbc) ?
166 + host->FwDebugBLEDvalue_P[0] : 0;
169 +inline struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
172 + struct adpt_device* d;
174 + if( pHba->channel[chan].device == NULL){
175 + printk(KERN_ERR"Adaptec I2O RAID: Trying to find device before they are allocated\n");
179 + d = pHba->channel[chan].device[id];
180 + if(!d || d->tid == 0) {
184 + if(d->scsi_lun == lun){
188 + for(d=d->next_lun ; d ; d = d->next_lun){
189 + if(d->scsi_lun == lun){
197 +///////////////////////////////////////////////////////////////////////
198 +///////////////////////////////////////////////////////////////////////
200 +///////////////////////////////////////////////////////////////////////
201 +///////////////////////////////////////////////////////////////////////
203 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
205 +Scsi_Host_Template driver_template = DPT_I2O;
206 +#include "scsi_module.c"
211 +Scsi_Host_Template driver_template = DPT_I2O;
212 +#include "scsi_module.c"
218 +static int adpt_i2o_systab_send(adpt_hba* pHba)
223 + msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
224 + msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
227 + msg[4] = (0<<16) | ((pHba->unit+2) << 12); /* Host 0 IOP ID (unit + 2) */
228 + msg[5] = 0; /* Segment 0 */
231 + * Provide three SGL-elements:
232 + * System table (SysTab), Private memory space declaration and
233 + * Private i/o space declaration
235 + msg[6] = 0x54000000 | sys_tbl_len;
236 + msg[7] = virt_to_phys(sys_tbl);
237 + msg[8] = 0x54000000 | 0;
239 + msg[10] = 0xD4000000 | 0;
242 + if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 120))) {
243 + printk(KERN_INFO "%s: Unable to set SysTab (status=%#10x).\n",
248 + PINFO("%s: SysTab set.\n", pHba->name);
256 +void adpt_i2o_sys_shutdown(void)
258 + adpt_hba *pHba, *pNext;
260 + printk(KERN_INFO "Shutting down Adaptec I2O controllers.\n");
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);
269 + printk(KERN_INFO "Adaptec I2O controllers down.\n");
273 + * reboot/shutdown notification.
275 + * - Quiesce each IOP in the system
279 +#ifdef REBOOT_NOTIFIER
280 +int adpt_reboot_event(struct notifier_block *n, unsigned long code, void *p)
283 + if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
284 + return NOTIFY_DONE;
286 + adpt_i2o_sys_shutdown();
288 + return NOTIFY_DONE;
293 +int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev)
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;
305 + int raptorFlag = FALSE;
308 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
309 + if(pci_enable_device(pDev)) {
312 + pci_set_master(pDev);
314 + base_addr0_phys = (caddr_t)pci_resource_start(pDev,0);
315 + hba_map0_area_size = pci_resource_len(pDev,0);
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;
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);
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);
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);
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;
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
369 + pci_read_config_word (pDev, PCI_SUBSYSTEM_ID, &subdevice);
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;
376 + if(hba_map0_area_size > 0x100000) { // Only give 'em 1M
377 + hba_map0_area_size = 0x100000;
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);
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;
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");
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");
409 + msg_addr_virt = base_addr_virt;
412 + // Allocate and zero the data structure
413 + if( (pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL)) == NULL) {
414 + iounmap(base_addr_virt);
417 + memset(pHba, 0, sizeof(adpt_hba));
419 + down(&adpt_configuration_lock);
420 + for(i=0;i<DPTI_MAX_HBA;i++) {
421 + if(hbas[i]==NULL) {
427 + if(hba_chain != NULL){
428 + for(p = hba_chain; p->next; p = p->next);
434 +// pHba->next=hba_chain;
436 + pHba->unit = hba_count;
437 + sprintf(pHba->name, "dpti%d", i);
440 + up(&adpt_configuration_lock);
443 + pHba->base_addr_phys = base_addr0_phys;
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);
454 + pHba->lct_size = 0;
455 + pHba->status_block = NULL;
456 + pHba->post_count = 0;
457 + pHba->state = DPTI_STATE_RESET;
459 + pHba->devices = NULL;
461 + // Initializing the spinlocks
462 + spin_lock_init(&pHba->state_lock);
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);
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);
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);
484 +void adpt_i2o_delete_hba(adpt_hba* pHba)
488 + struct i2o_device* d;
489 + struct i2o_device* next;
492 + struct adpt_device* pDev;
493 + struct adpt_device* pNext;
496 + down(&adpt_configuration_lock);
497 + // scsi_unregister calls our adpt_release which
500 + free_irq(pHba->host->irq, pHba);
502 + for(i=0;i<DPTI_MAX_HBA;i++) {
503 + if(hbas[i]==pHba) {
508 + for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
511 + p2->next = p1->next;
513 + hba_chain = p1->next;
520 + up(&adpt_configuration_lock);
522 + iounmap(pHba->base_addr_virt);
523 + if(pHba->msg_addr_virt != pHba->base_addr_virt){
524 + iounmap(pHba->msg_addr_virt);
532 + if(pHba->status_block) {
533 + kfree(pHba->status_block);
535 + if(pHba->reply_pool){
536 + kfree(pHba->reply_pool);
539 + for(d = pHba->devices; d ; d = next){
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;
556 + if(hba_count <= 0){
557 + unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);
564 + * Enable IOP. Allows the IOP to resume external operations.
566 +int adpt_i2o_enable_hba(adpt_hba* pHba)
571 + adpt_i2o_status_get(pHba);
572 + if(!pHba->status_block){
575 + /* Enable only allowed on READY state */
576 + if(pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
579 + if(pHba->status_block->iop_state != ADAPTER_STATE_READY)
582 + msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
583 + msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
587 + /* How long of a timeout do we need? */
589 + if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
590 + printk(KERN_ERR "%s: Could not enable (status=%#10x).\n",
593 + printk(KERN_INFO "%s: Enabled.\n", pHba->name);
596 + adpt_i2o_status_get(pHba);
602 + * Bring a controller online into OPERATIONAL state.
605 +int adpt_i2o_online_hba(adpt_hba* pHba)
607 + if (adpt_i2o_systab_send(pHba) < 0) {
608 + adpt_i2o_delete_hba(pHba);
611 + /* In READY state */
613 + if (adpt_i2o_enable_hba(pHba) < 0) {
614 + adpt_i2o_delete_hba(pHba);
618 + /* In OPERATIONAL state */
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.
630 +int adpt_detect(Scsi_Host_Template* sht)
632 + struct pci_dev *pDev = NULL;
636 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
637 + sht->proc_dir = &proc_scsi_dptI2O;
639 + sht->use_new_eh_code = 1;
641 + PINFO("Detecting Adaptec I2O RAID controllers...\n");
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;
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;
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);
677 + /* Active IOPs in HOLD state */
680 + if (hba_chain == NULL)
684 + * If build_sys_table fails, we kill everything and bail
685 + * as we can't init the IOPs w/o a system table
687 + if (adpt_i2o_build_sys_table() < 0) {
688 + adpt_i2o_sys_shutdown();
692 + PDEBUG("HBA's in HOLD state\n");
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;
702 + /* Active IOPs now in OPERATIONAL state */
703 + PDEBUG("HBA's in OPERATIONAL state\n");
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);
713 + if (adpt_i2o_parse_lct(pHba) < 0){
714 + adpt_i2o_delete_hba(pHba);
717 + adpt_inquiry(pHba);
720 + for (pHba = hba_chain; pHba; pHba = pHba->next) {
721 + if( adpt_scsi_register(pHba,sht) < 0){
722 + adpt_i2o_delete_hba(pHba);
725 + pHba->initialized = TRUE;
726 + pHba->state &= ~DPTI_STATE_RESET;
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();
744 + printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
745 + for (i = 0; i < DPTI_MAX_HBA; i++) {
748 +#ifdef REBOOT_NOTIFIER
749 + register_reboot_notifier(&adpt_reboot_notifier);
755 +/* Structures and definitions for synchronous message posting.
756 + * See adpt_i2o_post_wait() for description
758 +struct adpt_i2o_post_wait_data
762 + adpt_wait_queue_head_t *wq;
763 + struct adpt_i2o_post_wait_data *next;
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);
771 +int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
773 + ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
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;
785 + * The spin locking is needed to keep anyone from playing
786 + * with the queue pointers and id while we do the same
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);
797 + wait_data->wq = &adpt_wq_i2o_post;
798 + wait_data->status = -ETIMEDOUT;
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);
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);
813 + msg[2] |= 0x80000000 | ((u32)wait_data->id);
815 + if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
817 + current->state = TASK_INTERRUPTIBLE;
818 + spin_unlock_irq(&io_request_lock);
820 + spin_lock_irq(&io_request_lock);
822 + current->state = TASK_INTERRUPTIBLE;
823 + spin_unlock_irq(&io_request_lock);
824 + schedule_timeout(timeout*HZ);
825 + spin_lock_irq(&io_request_lock);
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);
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);
838 + if(status == -ETIMEDOUT)
839 + printk("dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
841 + /* Remove the entry from the queue. */
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) {
847 + p2->next = p1->next;
849 + adpt_post_wait_queue = p1->next;
853 + spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
859 +s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
862 + u32 m = EMPTY_QUEUE;
864 + u32 timeout = jiffies + 30*HZ;
867 + m = readl(pHba->post_port);
868 + if (m != EMPTY_QUEUE) {
871 + if(time_after(jiffies,timeout)){
873 + "dpti%d: Timeout waiting for message frame!\n",
877 + } while(m == EMPTY_QUEUE);
879 + msg = (u32*) (pHba->msg_addr_virt + m);
880 + memcpy_toio(msg, data, len);
884 + writel(m, pHba->post_port);
891 +static void adpt_i2o_post_wait_complete(u32 context, int status)
893 + struct adpt_i2o_post_wait_data *p1 = NULL;
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
903 + * Lock needed to keep anyone from moving queue pointers
904 + * around while we're looking through them.
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);
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);
929 + * Bring an I2O controller into HOLD state. See the spec.
931 +int adpt_i2o_activate_hba(adpt_hba* pHba)
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);
941 + if (adpt_i2o_status_get(pHba) < 0) {
942 + printk(KERN_INFO "HBA not responding.\n");
947 + if(pHba->status_block->iop_state == ADAPTER_STATE_FAULTED) {
948 + printk(KERN_CRIT "%s: hardware fault\n", pHba->name);
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);
963 + if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
964 + printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
970 + if (adpt_i2o_init_outbound_q(pHba) < 0) {
974 + /* In HOLD state */
976 + if (adpt_i2o_hrt_get(pHba) < 0) {
984 +s32 adpt_i2o_reset_hba(adpt_hba* pHba)
988 + u32 m = EMPTY_QUEUE ;
989 + u32 timeout = jiffies + (TMOUT_IOPRESET*HZ);
991 + if(pHba->initialized == FALSE) { // First time reset should be quick
992 + timeout = jiffies + (25*HZ);
994 + adpt_i2o_quiesce_hba(pHba);
999 + m = readl(pHba->post_port);
1000 + if (m != EMPTY_QUEUE) {
1003 + if(time_after(jiffies,timeout)){
1004 + printk(KERN_ERR "Timeout waiting for message!\n");
1005 + return -ETIMEDOUT;
1007 + } while (m == EMPTY_QUEUE);
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");
1015 + memset(status,0,4);
1017 + msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
1018 + msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
1023 + msg[6]=virt_to_bus(status);
1026 + memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
1028 + writel(m, pHba->post_port);
1031 + while((volatile u8)*status == 0){
1032 + if(time_after(jiffies,timeout)){
1033 + printk(KERN_ERR"%s: IOP Reset Timeout\n",pHba->name);
1035 + return -ETIMEDOUT;
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
1046 + m = readl(pHba->post_port);
1047 + if (m != EMPTY_QUEUE) {
1050 + if(time_after(jiffies,timeout)){
1051 + printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
1052 + return -ETIMEDOUT;
1054 + } while (m == EMPTY_QUEUE);
1055 + // Flush the offset
1056 + adpt_send_nop(pHba, m);
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",
1064 + printk(KERN_INFO"%s: Reset completed.\n",
1070 + adpt_delay(20000);
1075 +s32 adpt_i2o_quiesce_hba(adpt_hba* pHba)
1080 + adpt_i2o_status_get(pHba);
1082 + /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
1084 + if((pHba->status_block->iop_state != ADAPTER_STATE_READY) &&
1085 + (pHba->status_block->iop_state != ADAPTER_STATE_OPERATIONAL)){
1089 + msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
1090 + msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
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);
1098 + printk("dpti%d: Quiesced.\n",pHba->unit);
1101 + adpt_i2o_status_get(pHba);
1105 +s32 adpt_i2o_status_get(adpt_hba* pHba)
1109 + volatile u32 *msg;
1110 + volatile u8 *status_block=NULL;
1111 + caddr_t status_block_bus;
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) {
1118 + "dpti%d: Get Status Block failed; Out of memory. \n",
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;
1129 + m = readl(pHba->post_port);
1130 + if (m != EMPTY_QUEUE) {
1133 + if(time_after(jiffies,timeout)){
1134 + printk(KERN_ERR "%s: Timeout waiting for message !\n",
1136 + return -ETIMEDOUT;
1138 + } while(m==EMPTY_QUEUE);
1141 + msg=(u32*)(pHba->msg_addr_virt+m);
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
1154 + writel(m, pHba->post_port);
1157 + while(status_block[87]!=0xff){
1158 + if(time_after(jiffies,timeout)){
1159 + printk(KERN_ERR"dpti%d: Get status timeout.\n",
1161 + return -ETIMEDOUT;
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;
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;
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;
1185 + printk("dpti%d: State = ",pHba->unit);
1186 + switch(pHba->status_block->iop_state) {
1191 + printk("RESET\n");
1197 + printk("READY\n");
1200 + printk("OPERATIONAL\n");
1203 + printk("FAILED\n");
1206 + printk("FAULTED\n");
1209 + printk("%x (unknown!!)\n",pHba->status_block->iop_state);
1216 +s32 adpt_i2o_hrt_get(adpt_hba* pHba)
1219 + int ret, size = sizeof(i2o_hrt);
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);
1230 + msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
1231 + msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
1234 + msg[4]= (0xD0000000 | size); /* Simple transaction */
1235 + msg[5]= virt_to_bus(pHba->hrt); /* Dump it here */
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);
1242 + if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
1243 + size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
1247 + } while(pHba->hrt == NULL);
1252 + * Query one scalar group value or a whole scalar group.
1254 +int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
1255 + int group, int field, void *buf, int buflen)
1257 + u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
1258 + u8 resblk[8+buflen]; /* 8 bytes for header */
1261 + if (field == -1) /* whole group */
1264 + size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid,
1265 + opblk, sizeof(opblk), resblk, sizeof(resblk));
1270 + memcpy(buf, resblk+8, buflen); /* cut off header */
1275 +/* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
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.
1283 +int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid,
1284 + void *opblk, int oplen, void *resblk, int reslen)
1287 + u32 *res = (u32 *)resblk;
1290 + msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
1291 + msg[1] = cmd << 24 | HOST_TID << 12 | tid;
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);
1300 + if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
1301 + return wait_status; /* -DetailedStatus */
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",
1308 + (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
1310 + res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF);
1311 + return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
1314 + return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */
1318 + * Get the IOP's Logical Configuration Table
1320 +int adpt_i2o_lct_get(adpt_hba* pHba)
1326 + if ((pHba->lct_size == 0) || (pHba->lct == NULL)){
1327 + pHba->lct_size = pHba->status_block->expected_lct_size;
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",
1338 + memset(pHba->lct, 0, pHba->lct_size);
1340 + msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
1341 + msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
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);
1349 + if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
1350 + printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n",
1352 + printk("Adaptec: Error Reading Hardware.\n");
1356 + if ((pHba->lct->table_size << 2) > pHba->lct_size) {
1357 + pHba->lct_size = pHba->lct->table_size << 2;
1361 + } while (pHba->lct == NULL);
1363 + PDEBUG("%s: Hardware resource table read.\n", pHba->name);
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;
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.
1386 +int adpt_i2o_parse_lct(adpt_hba* pHba)
1391 + struct i2o_device *d;
1392 + i2o_lct *lct = pHba->lct;
1396 + u32 buf[10]; // larger than 7, or 8 ...
1397 + struct adpt_device* pDev;
1399 + if (lct == NULL) {
1400 + printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
1404 + max = lct->table_size;
1408 + if(lct->iop_flags&(1<<0))
1409 + printk(KERN_WARNING "%s: Configuration dialog desired.\n", pHba->name);
1411 + for(i=0;i<max;i++) {
1412 + if( lct->lct_entry[i].user_tid != 0xfff){
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).
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 ){
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) {
1430 + bus_no = buf[0]>>16;
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);
1437 + if(scsi_id > MAX_ID){
1438 + printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
1441 + if(bus_no > pHba->top_scsi_channel){
1442 + pHba->top_scsi_channel = bus_no;
1444 + if(scsi_id > pHba->top_scsi_id){
1445 + pHba->top_scsi_id = scsi_id;
1447 + if(scsi_lun > pHba->top_scsi_lun){
1448 + pHba->top_scsi_lun = scsi_lun;
1452 + d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
1455 + printk(KERN_CRIT "%s: Out of memory for I2O device data.\n",pHba->name);
1459 + d->controller = (void*)pHba;
1462 + memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
1465 + tid = d->lct_data.tid;
1466 + adpt_i2o_report_hba_unit(pHba, d);
1467 + adpt_i2o_install_device(pHba, d);
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
1476 + if(bus_no > pHba->top_scsi_channel){
1477 + pHba->top_scsi_channel = bus_no;
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)
1483 + pHba->channel[bus_no].scsi_id = buf[1];
1484 + printk(KERN_INFO "Bus %d - SCSI ID %d.\n", bus_no, buf[1]);
1486 + // TODO remove - this is just until we get from hrt
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);
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 ){
1501 + tid = d->lct_data.tid;
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;
1507 + scsi_lun = (buf[2]>>8 )&0xff;
1508 + if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
1511 + if(scsi_id > MAX_ID){
1514 + if( pHba->channel[bus_no].device[scsi_id] == NULL){
1515 + pDev = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
1516 + if(pDev == NULL) {
1519 + pHba->channel[bus_no].device[scsi_id] = pDev;
1520 + memset(pDev,0,sizeof(struct adpt_device));
1522 + for( pDev = pHba->channel[bus_no].device[scsi_id];
1523 + pDev->next_lun; pDev = pDev->next_lun){
1525 + pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
1526 + if(pDev == NULL) {
1529 + memset(pDev->next_lun,0,sizeof(struct adpt_device));
1530 + pDev = pDev->next_lun;
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;
1543 + if(scsi_lun > pHba->top_scsi_lun){
1544 + pHba->top_scsi_lun = scsi_lun;
1547 + if(scsi_id == -1){
1548 + printk(KERN_WARNING"Could not find SCSI ID for %s\n",
1549 + d->lct_data.identity_tag);
1558 + * Each I2O controller has a chain of devices on it - these match
1559 + * the useful parts of the LCT of the board.
1562 +int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
1564 + down(&adpt_configuration_lock);
1565 + d->controller=(struct i2o_controller*)pHba;
1567 + d->next=pHba->devices;
1569 + if (pHba->devices != NULL){
1570 + pHba->devices->prev=d;
1575 + up(&adpt_configuration_lock);
1581 + * Dump the information block associated with a given unit (TID)
1584 +void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d)
1587 + int unit = d->lct_data.tid;
1589 + printk(KERN_INFO "Target ID %d.\n", unit);
1591 + if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 3, buf, 16)>=0)
1594 + printk(KERN_INFO" Vendor: %s", buf);
1596 + if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 4, buf, 16)>=0)
1599 + printk(" Device: %s", buf);
1602 + if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 5, buf, 16)>=0)
1605 + printk(KERN_INFO "Description: %s", buf);
1608 + if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 6, buf, 8)>=0)
1611 + printk(" Rev: %s\n", buf);
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: ");
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!
1631 + * Do i2o class name lookup
1633 +const char *adpt_i2o_get_class_name(int class)
1636 + static char *i2o_class_name[] = {
1638 + "Device Driver Module",
1643 + "Fibre Channel Port",
1644 + "Fibre Channel Device",
1648 + "Floppy Controller",
1650 + "Secondary Bus Port",
1651 + "Peer Transport Agent",
1656 + switch(class&0xFFF) {
1657 + case I2O_CLASS_EXECUTIVE:
1659 + case I2O_CLASS_DDM:
1661 + case I2O_CLASS_RANDOM_BLOCK_STORAGE:
1663 + case I2O_CLASS_SEQUENTIAL_STORAGE:
1665 + case I2O_CLASS_LAN:
1667 + case I2O_CLASS_WAN:
1669 + case I2O_CLASS_FIBRE_CHANNEL_PORT:
1671 + case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
1673 + case I2O_CLASS_SCSI_PERIPHERAL:
1675 + case I2O_CLASS_ATE_PORT:
1677 + case I2O_CLASS_ATE_PERIPHERAL:
1679 + case I2O_CLASS_FLOPPY_CONTROLLER:
1681 + case I2O_CLASS_FLOPPY_DEVICE:
1683 + case I2O_CLASS_BUS_ADAPTER_PORT:
1685 + case I2O_CLASS_PEER_TRANSPORT_AGENT:
1687 + case I2O_CLASS_PEER_TRANSPORT:
1690 + return i2o_class_name[idx];
1694 +int adpt_open(struct inode *inode, struct file *file)
1699 + //TODO check for root access
1701 + minor = MINOR(inode->i_rdev);
1702 + if (minor >= hba_count) {
1705 + down(&adpt_configuration_lock);
1706 + for (pHba = hba_chain; pHba; pHba = pHba->next) {
1707 + if (pHba->unit == minor) {
1708 + break; /* found adapter */
1711 + if (pHba == NULL) {
1712 + up(&adpt_configuration_lock);
1716 +// if(pHba->in_use){
1717 + // up(&adpt_configuration_lock);
1722 + up(&adpt_configuration_lock);
1727 +int adpt_close(struct inode *inode, struct file *file)
1732 + minor = MINOR(inode->i_rdev);
1733 + if (minor >= hba_count) {
1736 + down(&adpt_configuration_lock);
1737 + for (pHba = hba_chain; pHba; pHba = pHba->next) {
1738 + if (pHba->unit == minor) {
1739 + break; /* found adapter */
1742 + up(&adpt_configuration_lock);
1743 + if (pHba == NULL) {
1753 +int adpt_i2o_passthru(adpt_hba* pHba, u32* arg)
1755 + u32 msg[MAX_MESSAGE_SIZE/4];
1756 + u32* reply = NULL;
1758 + u32 reply_size = 0;
1759 + u32* user_msg = (u32*)arg;
1760 + u32* user_reply = NULL;
1761 + u32 sg_offset = 0;
1766 + caddr_t sg_list[pHba->sg_tablesize];
1769 + memset(&msg, 0, MAX_MESSAGE_SIZE);
1770 + // get user msg size in u32s
1771 + get_user(size, &user_msg[0]);
1774 + user_reply = &user_msg[size];
1775 + size *= 4; // Convert to bytes
1776 + if(size > MAX_MESSAGE_SIZE){
1780 + /* Copy in the user's I2O command */
1781 + if (copy_from_user ((void*)msg, (void*)user_msg, size)) {
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;
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);
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);
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);
1809 + for (i = 0; i < sg_count; i++) {
1813 + int residual, length, sub_length;
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);
1822 + sg_size = sg[i].flag_count & 0xffffff;
1823 + /* Allocate memory for the transfer */
1824 + p = (caddr_t)kmalloc(sg_size, GFP_KERNEL|ADDR32);
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);
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);
1840 + sg[i].addr_bus = (u32)virt_to_bus(p);
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;
1846 + residual = sg[i].flag_count&0xffffff;
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)) {
1856 + if (++sg_count > pHba->sg_tablesize){
1857 + printk(KERN_WARNING"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
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);
1866 + // fixup message and scatter gather list.
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;) {
1874 + // length &= 0xffffff;
1875 + sg[i].flag_count |= length;
1877 + sg[++i].addr_bus = physical = (u32)virt_to_bus(virtual);
1878 + // residual &= 0xffffff;
1879 + sg[i].flag_count |= residual;
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);
1898 + if(!rcode && sg_offset) {
1899 + /* Copy back the Scatter Gather buffers back to user space */
1901 + struct sg_simple_element* sg;
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])){
1913 + /* Copy in the user's I2O command */
1914 + if (copy_from_user ((void*)msg, (void*)user_msg, size)) {
1918 + sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
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);
1934 + /* Copy back the reply to user space */
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);
1941 + if (copy_to_user(user_reply, reply, reply_size)) {
1942 + printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
1951 + if(sg_list[--sg_index]) {
1952 + kfree(sg_list[sg_index]);
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.
1964 +/* Get all the info we can not get from kernel services */
1965 +int adpt_system_info(void *buffer)
1969 + memset(&si, 0, sizeof(si));
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;
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);
1987 + si.processorType = 0xff ;
1989 + if(copy_to_user(buffer, &si, sizeof(si))){
1990 + printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
1997 +#if defined __ia64__
1998 +void adpt_ia64_info(sysInfo_S* si)
2000 + // This is all the info we need for now
2001 + si->processorType = PROC_IA64;
2006 +#if defined __sparc__
2007 +void adpt_sparc_info(sysInfo_S* si)
2009 + // This is all the info we need for now
2010 + si->processorType = PROC_ULTRASPARC;
2014 +#if defined __alpha__
2015 +void adpt_sparc_info(sysInfo_S* si)
2017 + // This is all the info we need for now
2018 + si->processorType = PROC_ALPHA;
2022 +#if defined __i386__
2024 +#include <linux/mc146818rtc.h>
2027 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2029 +void adpt_i386_info(sysInfo_S* si)
2035 + switch (boot_cpu_data.x86) {
2037 + si->processorType = PROC_386;
2040 + si->processorType = PROC_486;
2043 + si->processorType = PROC_PENTIUM;
2045 + default: // Just in case
2046 + si->processorType = PROC_PENTIUM;
2050 + spin_lock_irqsave(&rtc_lock, flags);
2052 + /* Get drive type for 1st drive*/
2053 + i = CMOS_READ(0x12) >> 4;
2056 + j = CMOS_READ(0x19);
2058 + si->drive0CMOS = j;
2060 + /* Get driver type for 2nd drive*/
2063 + j = CMOS_READ(0x1a);
2065 + spin_unlock_irqrestore(&rtc_lock, flags);
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;
2073 + /* Go Out And Look For SmartROM revision */
2074 + for (i = 0; i < 3; ++i) {
2078 + /* Decide which bank */
2081 + } else if(i == 1) {
2087 + /* Looking for our bios signature */
2088 + if(isa_readw(addr) != 0xAA55) {
2091 + if(isa_readl( addr+6) != 0x202053) {
2094 + if(isa_readl(addr+10) != 0x545044) {
2100 + /* scan for " v" */
2101 + for (k = 0; k < 64; ++k) {
2102 + if(isa_readb(addr++) == ' ' && isa_readb(addr) == 'v' ) {
2107 + /* Found it - get version */
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;
2118 + /* if didn't find it - no smart ROM */
2119 + si->flags |= SI_NO_SmartROM;
2122 + if(si->numDrives > 0) {
2124 + /* Get The Pointer From Int 41 For The First
2125 + * Drive Parameters
2127 + addr = (((u32)isa_readw(0x104+2)) << 4) + (u16)isa_readw(0x104);
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 (!?)
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);
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;
2146 + if(si->numDrives > 1) {
2148 + * Get Pointer From Int 46 For The 2nd Drive Parameters
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);
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;
2168 +void adpt_i386_info(sysInfo_S* si)
2175 + switch (boot_cpu_data.x86) {
2177 + si->processorType = PROC_386;
2180 + si->processorType = PROC_486;
2183 + si->processorType = PROC_PENTIUM;
2185 + default: // Just in case
2186 + si->processorType = PROC_PENTIUM;
2190 +// spin_lock_irqsave(&rtc_lock, flags);
2192 + /* Get drive type for 1st drive*/
2193 + i = CMOS_READ(0x12) >> 4;
2196 + j = CMOS_READ(0x19);
2198 + si->drive0CMOS = j;
2200 + /* Get driver type for 2nd drive*/
2203 + j = CMOS_READ(0x1a);
2205 +// spin_unlock_irqrestore(&rtc_lock, flags);
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;
2213 + /* Go Out And Look For SmartROM revision */
2214 + for (i = 0; i < 3; ++i) {
2217 + /* Decide which bank */
2220 + } else if(i == 1) {
2225 + c_addr = phys_to_virt(j);
2227 + /* Looking for our bios signature */
2228 + if (*((unsigned short *) c_addr) != 0xAA55) {
2231 + if (*((unsigned long *) (c_addr + 6)) != 0x202053) {
2234 + if (*((unsigned long *) (c_addr + 10)) != 0x545044) {
2240 + /* scan for " v" */
2241 + for (k = 0; k < 64; ++k) {
2242 + if ((*((unsigned char *) (c_addr++)) == ' ') &&
2243 + (*((unsigned char *) (c_addr)) == 'v')) {
2248 + /* Found it - get version */
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;
2259 + /* if didn't find it - no smart ROM */
2260 + si->flags |= SI_NO_SmartROM;
2263 + if(si->numDrives > 0) {
2265 + * Get The Pointer From Int 41 For The First
2266 + * Drive Parameters
2268 + j = ((unsigned)(*((unsigned short *)phys_to_virt(0x104 + 2))) << 4)
2269 + + (unsigned)(*((unsigned short *)phys_to_virt(0x104 + 0)));
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 (!?)
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));
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;
2288 + if(si->numDrives > 1) {
2290 + * Get Pointer From Int 46 For The 2nd Drive Parameters
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));
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;
2313 +int adpt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
2314 + unsigned long arg)
2320 + minor = MINOR(inode->i_rdev);
2321 + if (minor >= DPTI_MAX_HBA){
2324 + down(&adpt_configuration_lock);
2325 + for (pHba = hba_chain; pHba; pHba = pHba->next) {
2326 + if (pHba->unit == minor) {
2327 + break; /* found adapter */
2330 + up(&adpt_configuration_lock);
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);
2339 + current->state = TASK_UNINTERRUPTIBLE;
2341 + schedule_timeout(2);
2346 + // TODO: handle 3 cases
2347 + case DPT_SIGNATURE:
2348 + if (copy_to_user((char*)arg, &DPTI_sig, sizeof(DPTI_sig))) {
2353 + return adpt_i2o_passthru(pHba,(u32*)arg);
2356 + case DPT_CTRLINFO:{
2357 + drvrHBAinfo_S HbaInfo;
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);
2377 + return adpt_system_info((void*)arg);
2379 + case DPT_BLINKLED:{
2381 + value = adpt_getBlinkLED(pHba);
2382 + if (copy_to_user((char*)arg, &value, sizeof(value))) {
2388 + adpt_hba_reset(pHba);
2390 + case I2ORESCANCMD:
2391 + adpt_rescan(pHba);
2393 + case DPT_TARGET_BUSY & 0xFFFF:
2394 + case DPT_TARGET_BUSY:
2396 + TARGET_BUSY_T busy;
2397 + struct adpt_device* d;
2399 + if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
2403 + d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
2407 + busy.isBusy = ((d->pScsi_dev) && (0 != d->pScsi_dev->access_count)) ? 1 : 0;
2408 + if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
2421 +const char *adpt_info(struct Scsi_Host *host)
2425 + pHba = (adpt_hba *) host->hostdata[0];
2426 + return (char *) (pHba->detail);
2429 +int adpt_proc_info(char *buffer, char **start, off_t offset,
2430 + int length, int hostno, int inout)
2432 + struct adpt_device* d;
2439 + struct Scsi_Host *host;
2442 + if (inout == TRUE) {
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
2448 + * Read data from buffer (writing to us) - NOT SUPPORTED
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
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.
2463 + *start = buffer + offset;
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 */
2472 + up(&adpt_configuration_lock);
2473 + if (pHba == NULL) {
2476 + host = pHba->host;
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);
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];
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;
2500 + if (pos < offset) {
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.
2509 + if (pos > offset + length) {
2511 + * We have written past the end of the buffer
2512 + * (proc_read/writescsi gives us 1K slop
2514 + * stop the output and calculate the correct length
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
2526 + *(buffer + len) = '\0';
2528 + len -= (offset - begin);
2529 + if (len > length) {
2537 + * I2O System Table. Contains information about
2538 + * all the IOPs in the system. Used to inform IOPs
2539 + * about each other's existence.
2541 + * sys_tbl_ver is the CurrentChangeIndicator that is
2542 + * used by IOPs to track changes.
2546 +int adpt_i2o_build_sys_table(void)
2548 + adpt_hba* pHba = NULL;
2551 + sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs
2552 + (hba_count) * sizeof(struct i2o_sys_tbl_entry);
2557 + sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
2559 + printk(KERN_ERR "SysTab Set failed. Out of memory.\n");
2562 + memset(sys_tbl, 0, sys_tbl_len);
2564 + sys_tbl->num_entries = hba_count;
2565 + sys_tbl->version = I2OVERSION;
2566 + sys_tbl->change_ind = sys_tbl_ind++;
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
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);
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]);
2605 +s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
2611 + u32 timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
2613 + u32 outbound_frame;
2617 + m = readl(pHba->post_port);
2618 + if (m != EMPTY_QUEUE) {
2622 + if(time_after(jiffies,timeout)){
2623 + printk("%s: Timeout waiting for message frame\n",pHba->name);
2624 + return -ETIMEDOUT;
2626 + } while(m == EMPTY_QUEUE);
2628 + msg=(u32 *)(pHba->msg_addr_virt+m);
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",
2637 + memset(status, 0, 4);
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]);
2648 + writel(m, pHba->post_port);
2651 + // Wait for the reply status to come back
2653 + if ((volatile u32)*status) {
2654 + if ((volatile u32)*status != 0x01 /*I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS*/) {
2659 + if(time_after(jiffies,timeout)){
2660 + printk("%s: Timeout Initializing\n",pHba->name);
2661 + kfree((void*)status);
2662 + return -ETIMEDOUT;
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);
2672 + kfree((void*)status);
2674 + if(pHba->reply_pool != NULL){
2675 + kfree(pHba->reply_pool);
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);
2683 + memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
2685 + ptr = pHba->reply_pool;
2686 + // TODO remove this code
2688 + for(i = 0; i < pHba->reply_fifo_size; i++) {
2689 + outbound_frame = (u32)virt_to_bus(ptr);
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);
2694 + writel(m, pHba->reply_port);
2698 + m = outbound_frame;
2699 + ptr += REPLY_FRAME_SIZE;
2701 + // the last frame represented in m & outbound_frame is necessarily lost by the above algorithm.
2702 + adpt_i2o_status_get(pHba);
2707 +void adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
2710 + adpt_hba* pHba=NULL;
2718 + if (pHba == NULL ){
2719 + printk("adpt_isr: NULL dev_id\n");
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
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);
2736 + reply = (ulong)bus_to_virt(m);
2738 + if (readl(reply) & MSG_FAIL) {
2739 + u32 old_m = readl(reply+28);
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);
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);
2754 + context = readl(reply+8);
2755 + if(context & 0x40000000){ // IOCTL
2756 + caddr_t p = (caddr_t)(readl(reply+12));
2758 + memcpy(p, (caddr_t)reply, REPLY_FRAME_SIZE * 4);
2760 + // All IOCTLs will also be post wait
2762 + if(context & 0x80000000){ // Post wait message
2763 + status = readl(reply+16);
2765 + status = -( status & 0xffff);
2767 + status = I2O_POST_WAIT_OK;
2769 + if(!(context & 0x40000000)) {
2770 + cmd = (Scsi_Cmnd*) readl(reply+12);
2772 + printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
2775 + adpt_i2o_post_wait_complete(context, status);
2776 + } else { // SCSI message
2777 + cmd = (Scsi_Cmnd*) readl(reply+12);
2779 + if(cmd->serial_number != 0) { // If not timedout
2780 + adpt_i2o_to_scsi(reply, cmd);
2784 + writel(m, pHba->reply_port);
2788 + spin_unlock_irqrestore(&io_request_lock, flags);
2793 +s32 adpt_send_nop(adpt_hba*pHba,u32 m)
2796 + u32 timeout = jiffies + 5*HZ;
2798 + while(m == EMPTY_QUEUE){
2800 + m = readl(pHba->post_port);
2801 + if(m != EMPTY_QUEUE){
2804 + if(time_after(jiffies,timeout)){
2805 + printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
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]);
2815 + writel(m, pHba->post_port);
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.
2826 +#include "dpti2oscsi2.c"
2829 +s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
2832 + u32 msg[MAX_MESSAGE_SIZE/4];
2841 + memset(msg, 0 , sizeof(msg));
2842 + len = cmd->request_bufflen;
2843 + direction = 0x00000000;
2845 + scsidir = 0x00000000; // DATA NO XFER
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
2853 + if (cmd->cmnd[0] < DISKXFERTBLSIZE) {
2854 + switch (i2oscsi2diskxfer[cmd->cmnd[0]]) {
2856 + scsidir =0x40000000; // DATA IN (iop<--dev)
2859 + direction=0x04000000; // SGL OUT
2860 + scsidir =0x80000000; // DATA OUT (iop-->dev)
2865 + scsidir =0x40000000; // DATA IN (iop<--dev)
2866 + // Assume In - and continue;
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);
2876 + printk("%s: cmd->cmnd[0] = %d is greater than table size, which is %d\n",
2877 + pHba->name, cmd->cmnd[0], DISKXFERTBLSIZE);
2880 + // msg[0] is set later
2881 + // I2O_CMD_SCSI_EXEC
2882 + msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
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);
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;
2897 + // Write SCSI command into the message - always 16 byte block
2898 + memset(mptr, 0, 16);
2899 + memcpy(mptr, cmd->cmnd, cmd->cmd_len);
2901 + lenptr=mptr++; /* Remember me - fill in when we know */
2902 + reqlen = 14; // SINGLE SGE
2903 + /* Now fill in the SGList and command */
2905 + struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
2907 + for(i = 0 ; i < cmd->use_sg; i++) {
2908 + *mptr++ = direction|0x10000000|sg->length;
2910 + *mptr++ = virt_to_bus(sg->address);
2913 + /* Make this an end of list */
2914 + mptr[-2] = direction|0xD0000000|(sg-1)->length;
2915 + reqlen = mptr - msg;
2918 + if(cmd->underflow && len != cmd->underflow){
2919 + printk("Cmd len %08X Cmd underflow %08X\n",
2920 + len, cmd->underflow);
2923 + *lenptr = len = cmd->request_bufflen;
2927 + *mptr++ = 0xD0000000|direction|cmd->request_bufflen;
2928 + *mptr++ = virt_to_bus(cmd->request_buffer);
2932 + /* Stick the headers on */
2933 + msg[0] = reqlen<<16 | ((reqlen > 12) ? SGL_OFFSET_12 : SGL_OFFSET_0);
2935 + // Send it on it's way
2936 + rcode = adpt_i2o_post_this(pHba, msg, reqlen<<2);
2944 +int adpt_abort(Scsi_Cmnd * cmd)
2946 + adpt_hba* pHba = NULL; /* host bus adapter structure */
2947 + struct adpt_device* dptdevice; /* dpt per device information */
2950 + printk(KERN_INFO"%s: Aborting cmd=%p\n",pHba->name, cmd);
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;
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;
2963 + msg[4] = (u32)cmd;
2964 + if(adpt_i2o_post_wait(pHba, msg, sizeof(msg), 60) != 0){
2965 + return FAILED; // Timedout
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
2976 + * scsi_unregister will be called AFTER we return.
2978 +int adpt_release(struct Scsi_Host *host)
2980 + adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
2981 +// adpt_i2o_quiesce_hba(pHba);
2982 + adpt_i2o_delete_hba(pHba);
2987 +void adpt_inquiry(adpt_hba* pHba)
3000 + memset(msg, 0, sizeof(msg));
3001 + buf = (u8*)kmalloc(36,GFP_KERNEL|ADDR32);
3003 + printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
3006 + memset((void*)buf, 0, 36);
3009 + direction = 0x00000000;
3010 + scsidir =0x40000000; // DATA IN (iop<--dev)
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);
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*/;
3029 + memset(scb, 0, sizeof(scb));
3030 + // Write SCSI command into the message - always 16 byte block
3037 + // Don't care about the rest of scb
3039 + memcpy(mptr, scb, sizeof(scb));
3041 + lenptr=mptr++; /* Remember me - fill in when we know */
3043 + /* Now fill in the SGList and command */
3045 + *mptr++ = 0xD0000000|direction|len;
3046 + *mptr++ = virt_to_bus(buf);
3048 + // Send it on it's way
3049 + rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
3051 + sprintf(pHba->detail, "Adaptec I2O RAID");
3052 + printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
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 */
3063 + adpt_i2o_status_get(pHba);
3068 +// This version of reset is called by the eh_error_handler
3069 +int adpt_reset(Scsi_Cmnd* cmd)
3072 + pHba = (adpt_hba*)cmd->host->hostdata;
3073 + return adpt_hba_reset(pHba);
3077 +int adpt_hba_reset(adpt_hba* pHba)
3082 + pHba->state |= DPTI_STATE_RESET;
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);
3093 + if ((rcode=adpt_i2o_build_sys_table()) < 0) {
3094 + spin_unlock_irqrestore(&io_request_lock, flags);
3095 + adpt_i2o_delete_hba(pHba);
3098 + PDEBUG("%s: in HOLD state\n",pHba->name);
3100 + if ((rcode=adpt_i2o_online_hba(pHba)) < 0) {
3101 + spin_unlock_irqrestore(&io_request_lock, flags);
3102 + adpt_i2o_delete_hba(pHba);
3105 + PDEBUG("%s: in OPERATIONAL state\n",pHba->name);
3107 + if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
3108 + spin_unlock_irqrestore(&io_request_lock, flags);
3109 + adpt_i2o_delete_hba(pHba);
3113 + if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
3114 + spin_unlock_irqrestore(&io_request_lock, flags);
3115 + adpt_i2o_delete_hba(pHba);
3118 + pHba->state &= ~DPTI_STATE_RESET;
3120 + adpt_fail_posted_scbs(pHba);
3121 + spin_unlock_irqrestore(&io_request_lock, flags);
3122 + return 0; /* return success */
3126 +// This version of bus reset is called by the eh_error handler
3127 +int adpt_bus_reset(Scsi_Cmnd* cmd)
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);
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);
3144 + cmd->result = (DID_OK<<16);
3145 + cmd->scsi_done(cmd);
3150 +// This is not currently supported by our adapter but we issue it anyway
3151 +int adpt_device_reset(Scsi_Cmnd* cmd)
3155 + struct adpt_device* d = (void*) cmd->device->hostdata;
3157 + pHba = (void*) cmd->host->hostdata;
3159 + printk("%s: Reset Device: Device Not found\n",pHba->name);
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);
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);
3176 + cmd->result = (DID_OK<<16);
3177 + cmd->scsi_done(cmd);
3182 +void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist)
3184 + Scsi_Device *device; /* scsi layer per device information */
3187 + pHba = (adpt_hba *) host->hostdata[0];
3189 + for (device = devicelist; device != NULL; device = device->next) {
3190 + if (device->host != host) {
3193 + // TODO find better number for this
3194 + if (host->can_queue) {
3195 + device->queue_depth = host->can_queue - 1;
3197 + device->queue_depth = 1;
3202 +int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
3204 + adpt_hba* pHba = NULL;
3205 + struct adpt_device* pDev = NULL; /* dpt per device information */
3206 + u32 timeout = jiffies + (TMOUT_SCSI*HZ);
3208 + cmd->scsi_done = done;
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
3216 + if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
3217 + cmd->result = (DID_OK << 16);
3218 + cmd->scsi_done(cmd);
3222 + pHba = (adpt_hba*)cmd->host->hostdata[0];
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;
3233 + mod_timer(&cmd->eh_timeout, timeout);
3235 + if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
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.
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);
3246 + (struct adpt_device*)(cmd->device->hostdata) = pDev;
3248 + pDev->pScsi_dev = cmd->device;
3251 + * Let the rescan handler notify the sd layer to rescan the devices
3253 + if (pDev->state & DPTI_DEV_OFFLINE) {
3254 + if (cmd->device != NULL) {
3255 + cmd->device->online = FALSE;
3257 + cmd->result = (DID_NO_CONNECT << 16);
3258 + cmd->scsi_done(cmd);
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
3272 + if (pDev->state & DPTI_DEV_RESET /* || pDev->state & DPTI_DEV_UNSCANNED */) {
3275 + return adpt_scsi_to_i2o(pHba, cmd, pDev);
3279 +s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
3281 + struct Scsi_Host *host = NULL;
3283 + host = scsi_register(sht, sizeof(adpt_hba*));
3284 + if (host == NULL) {
3285 + printk ("%s: scsi_register returned NULL\n",pHba->name);
3288 + (adpt_hba*)(host->hostdata[0]) = pHba;
3289 + pHba->host = host;
3291 + host->irq = pHba->pDev->irq;;
3292 + /* no IO ports, so don't have to set host->io_port and
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;
3311 +int adpt_bios_param(Disk* disk, kdev_t dev, int geom[])
3317 + // *** First lets set the default geometry ****
3319 + // If the capacity is less than ox2000
3320 + if (disk->capacity < 0x2000 ) { // floppy
3324 + // else if between 0x2000 and 0x20000
3325 + else if (disk->capacity < 0x20000) {
3329 + // else if between 0x20000 and 0x40000
3330 + else if (disk->capacity < 0x40000) {
3334 + // else if between 0x4000 and 0x80000
3335 + else if (disk->capacity < 0x80000) {
3339 + // else if greater than 0x80000
3344 + cylinders = disk->capacity / (heads * sectors);
3346 + // Special case if CDROM
3347 + if(disk->device->type == 5) { // CDROM
3352 + // *** Now lets read the partition table to see what it thinks ****
3354 + // TODO(defer) dmb - use marks algorythm
3355 + if( disk->has_part_table == 1){
3364 + geom[1] = sectors;
3365 + geom[2] = cylinders;
3369 + PDEBUG("adpt_bios_param: exit\n");
3376 +int adpt_read_capacity(adpt_hba* pHba, struct adpt_device* d)
3378 + u32 msg[MAX_MESSAGE_SIZE/4], *mptr;
3389 + memset(msg, 0, sizeof(msg));
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
3397 + /* Stick the headers on */
3398 + msg[0] = reqlen<<16 | SGL_OFFSET_12;
3399 + msg[1] = (0xff<<24|HOST_TID<<12|d->tid);
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*/;
3413 + memset(scb, 0, sizeof(scb));
3414 + // Write SCSI command into the message - always 16 byte block
3415 + scb[0] = READ_CAPACITY;
3425 + // Don't care about the rest of scb
3427 + memcpy(mptr, scb, 16);
3429 + lenptr=mptr++; /* Remember me - fill in when we know */
3431 + /* Now fill in the SGList and command */
3433 + *mptr++ = 0xD0000000|direction|len;
3434 + *mptr++ = virt_to_bus(buf);
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);
3440 + d->block_size = 0;
3443 + ptr = (u8*) &d->capacity;
3444 + for (i = 0; i < 4; ++i) {
3445 + ptr[i] = buf[3-i];
3447 + ptr = (u8*)&d->block_size;
3448 + for (i = 0; i < 4; ++i) {
3449 + ptr[i] = buf[7-i];
3459 +s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
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;
3469 + u32 reply_flags = readl(reply) & 0xff00; // Leave it shifted up 8 bits
3471 + dev_status = detailed_status & 0xff;
3472 + hba_status = detailed_status >> 8;
3473 + pHba = (adpt_hba*) cmd->host->hostdata[0];
3475 + if (!(reply_flags & MSG_FAIL)) {
3477 + switch (detailed_status & I2O_SCSI_DSC_MASK) {
3478 + case I2O_SCSI_DSC_SUCCESS:
3479 + cmd->result = (DID_OK << 16);
3481 + case I2O_SCSI_DSC_REQUEST_ABORTED:
3482 + cmd->result = (DID_ABORT << 16);
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);
3509 + case I2O_SCSI_DSC_ADAPTER_BUSY:
3510 + case I2O_SCSI_DSC_BUS_BUSY:
3511 + cmd->result = (DID_BUS_BUSY << 16);
3513 + case I2O_SCSI_DSC_REQUEST_INVALID:
3514 + cmd->result = (DID_ERROR << 16);
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;
3525 + case I2O_SCSI_DSC_SCSI_BUS_RESET:
3526 + case I2O_SCSI_DSC_BDR_MESSAGE_SENT:
3527 + cmd->result = (DID_RESET << 16);
3529 + case I2O_SCSI_DSC_PARITY_ERROR_FAILURE:
3530 + cmd->result = (DID_ERROR << 16);
3533 + cmd->result = (DID_NO_CONNECT << 16);
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);
3547 + cmd->result = (DID_OK << 16);
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.
3559 + cmd->result = (DID_TIME_OUT << 16);
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.
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]);
3572 + // TODO test the timeout lockup thingie
3573 + if (cmd->result == (DID_TIME_OUT <<16) ){
3574 + cmd->result = (DID_NO_CONNECT << 16);
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);
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);
3591 + cmd->result |= (dev_status);
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);
3599 + return cmd->result;
3603 +s32 adpt_rescan(adpt_hba* pHba)
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);
3615 + if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
3616 +// adpt_i2o_delete_hba(pHba);
3617 + spin_unlock_irqrestore(&io_request_lock, flags);
3620 + spin_unlock_irqrestore(&io_request_lock, flags);
3625 +s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
3630 + struct i2o_device *d;
3631 + i2o_lct *lct = pHba->lct;
3635 + u32 buf[10]; // at least 8 u32's
3636 + struct adpt_device* pDev = NULL;
3637 + struct i2o_device* pI2o_dev = NULL;
3639 + if (lct == NULL) {
3640 + printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
3644 + max = lct->table_size;
3648 + // Mark each drive as unscanned
3649 + for (d = pHba->devices; d; d = d->next) {
3650 + pDev =(struct adpt_device*) d->owner;
3654 + pDev->state |= DPTI_DEV_UNSCANNED;
3657 + printk(KERN_INFO "%s: LCT has %d entries.\n", pHba->name,max);
3659 + if(lct->iop_flags&(1<<0))
3660 + printk(KERN_WARNING "%s: Configuration dialog desired.\n", pHba->name);
3662 + for(i=0;i<max;i++) {
3663 + if( lct->lct_entry[i].user_tid != 0xfff){
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);
3675 + bus_no = buf[0]>>16;
3677 + scsi_lun = (buf[2]>>8 )&0xff;
3678 + pDev = pHba->channel[bus_no].device[scsi_id];
3681 + if(pDev->scsi_lun == scsi_lun) {
3684 + pDev = pDev->next_lun;
3686 + if(!pDev ) { // Something new add it
3687 + d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
3690 + printk(KERN_CRIT "Out of memory for I2O device data.\n");
3694 + d->controller = (void*)pHba;
3697 + memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
3700 + adpt_i2o_report_hba_unit(pHba, d);
3701 + adpt_i2o_install_device(pHba, d);
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);
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;
3712 + while (pDev->next_lun) {
3713 + pDev = pDev->next_lun;
3715 + pDev = pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
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;
3730 + if(scsi_lun > pHba->top_scsi_lun){
3731 + pHba->top_scsi_lun = scsi_lun;
3734 + } // end of new i2o device
3736 + // We found an old device - check it
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;
3745 + d = pDev->pI2o_dev;
3746 + if(d->lct_data.tid != tid) { // something changed
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;
3754 + // Found it - mark it scanned
3755 + pDev->state &= ~(DPTI_DEV_UNSCANNED|DPTI_DEV_OFFLINE);
3758 + pDev = pDev->next_lun;
3762 + for (pI2o_dev = pHba->devices; pI2o_dev; pI2o_dev = pI2o_dev->next) {
3763 + pDev =(struct adpt_device*) pI2o_dev->owner;
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));
3788 +void adpt_fail_posted_scbs(adpt_hba* pHba)
3790 + Scsi_Cmnd* cmd = NULL;
3791 + Scsi_Device* d = NULL;
3793 + if( pHba->host->host_queue != NULL ) {
3794 + d = pHba->host->host_queue;
3798 + while( d->next != NULL ){
3799 + for(cmd = d->device_queue; cmd ; cmd = cmd->next){
3800 + if(cmd->serial_number == 0){
3803 + cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
3804 + cmd->scsi_done(cmd);
3813 +static void adpt_delay(int millisec)
3816 + for (i = 0; i < millisec; i++) {
3817 + udelay(1000); /* delay for one millisecond */
3823 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
3825 +adpt_pci_find_device(unsigned int vendor, struct pci_dev *from)
3828 + from = pci_devices;
3830 + from = from->next;
3832 + while (from && from->vendor != vendor) {
3833 + from = from->next;
3839 --- /dev/null Sat Apr 14 07:06:21 2001
3840 +++ linux/drivers/scsi/dpti.h Wed Jul 18 14:31:28 2001
3842 +/***************************************************************************
3843 + dpti.h - description
3844 + -------------------
3845 + begin : Thu Sep 7 2000
3846 + copyright : (C) 2001 by Adaptec
3847 + email : deanna_bonds@adaptec.com
3849 + See README.dpti for history, notes, license info, and credits
3850 + ***************************************************************************/
3852 +/***************************************************************************
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. *
3859 + ***************************************************************************/
3864 +#define MAX_TO_IOP_MESSAGES (210)
3865 +#define MAX_FROM_IOP_MESSAGES (56)
3867 +#ifndef LINUX_VERSION_CODE
3868 +#include <linux/version.h>
3871 +#include "sys_info.h"
3874 + * Function Prototypes
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);
3885 +const char *adpt_info(struct Scsi_Host *pSHost);
3886 +int adpt_bios_param(Disk * disk, kdev_t dev, int geom[]);
3888 +int adpt_bus_reset(Scsi_Cmnd* cmd);
3889 +int adpt_device_reset(Scsi_Cmnd* cmd);
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.
3897 +#define DPT_DRIVER_NAME "Adaptec I2O RAID"
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 \
3920 +#else /* KERNEL_VERSION > 2.2.16 */
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" \
3946 +#include <linux/wait.h>
3947 +#include "dpti_i2o.h"
3948 +#include "dpti_ioctl.h"
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
3957 +#define DPT_YEAR (2001-1980)
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
3966 +#define REPLY_FRAME_SIZE (17)
3967 +#define SG_LIST_ELEMENTS (56)
3968 +#define MAX_MESSAGE_SIZE (512)
3970 +#define EMPTY_QUEUE 0xffffffff
3971 +#define I2O_INTERRUPT_PENDING_B (0x08)
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)
3977 +//#define REBOOT_NOTIFIER 1
3978 +/* Debugging macro from Linux Device Drivers - Rubini */
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)
3985 +# define PDEBUG(fmt, args...) /* not debugging: nothing */
3986 +# define PDEBUGV(fmt, args...) /* not debugging: nothing */
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)
3994 +#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
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)
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
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 */
4057 +// Device state flags
4058 +#define DPTI_DEV_UNSCANNED 0x01
4059 +#define DPTI_DEV_RESET 0x02
4060 +#define DPTI_DEV_OFFLINE 0x04
4063 +struct adpt_device {
4064 + struct adpt_device* next_lun;
4074 + struct i2o_device* pI2o_dev;
4075 + Scsi_Device *pScsi_dev;
4078 +struct adpt_channel {
4079 + struct adpt_device* device[MAX_ID]; /* used as an array of 128 scsi ids */
4084 + struct i2o_device* pI2o_dev;
4088 +#define DPTI_STATE_RESET (0x01)
4089 +#define DPTI_STATE_IOCTL (0x02)
4091 +typedef struct _adpt_hba {
4092 + struct _adpt_hba *next;
4093 + struct pci_dev *pDev;
4094 + struct Scsi_Host *host;
4096 + spinlock_t state_lock;
4098 + int host_no; /* SCSI host number */
4100 + u8 in_use; /* is the management node open*/
4105 + caddr_t base_addr_virt;
4106 + caddr_t msg_addr_virt;
4107 + caddr_t base_addr_phys;
4112 + u32 post_fifo_size;
4113 + u32 reply_fifo_size;
4115 + u32 sg_tablesize; // Scatter/Gather List Size.
4116 + u8 top_scsi_channel;
4120 + i2o_status_block* status_block;
4123 + unsigned lct_size;
4124 + struct i2o_device* devices;
4125 + struct adpt_channel channel[MAX_CHANNEL];
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
4136 +struct sg_simple_element {
4142 + * Function Prototypes
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);
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);
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);
4193 +void adpt_start_complete_queue(void);
4194 +void adpt_done_cmds_complete(void * data);
4195 +void adpt_queue_cmd_complete(Scsi_Cmnd *cmd);
4198 +static void adpt_delay(int millisec);
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);
4205 +#if defined __ia64__
4206 +void adpt_ia64_info(sysInfo_S* si);
4208 +#if defined __sparc__
4209 +void adpt_sparc_info(sysInfo_S* si);
4211 +#if defined __alpha__
4212 +void adpt_sparc_info(sysInfo_S* si);
4214 +#if defined __i386__
4215 +void adpt_i386_info(sysInfo_S* si);
4218 +#define PRINT_BUFFER_SIZE 512
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
4230 +#define FW_DEBUG_STR_LENGTH_OFFSET 0
4231 +#define FW_DEBUG_FLAGS_OFFSET 4
4232 +#define FW_DEBUG_BLED_OFFSET 8
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
4242 + * NOTE: You must include i2obscsi.h before including this file
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
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
4263 +unsigned char i2oscsi2diskxfer[] = {
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,
4276 +/* 0x09 */ NOSUPPORT,
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,
4301 +/* 0x1f */ NOSUPPORT,
4302 +/* 0x20 */ NOSUPPORT,
4303 +/* 0x21 */ NOSUPPORT,
4304 +/* 0x22 */ NOSUPPORT,
4305 +/* 0x23 */ NOSUPPORT,
4307 +/* SET_WINDOW 0x24 */ DATAOUT,
4308 +/* READ_CAPACITY 0x25 */ DATAIN,
4310 +/* 0x26 */ NOSUPPORT,
4311 +/* 0x27 */ NOSUPPORT,
4313 +/* READ_10 0x28 */ DATAIN,
4315 +/* 0x29 */ NOSUPPORT,
4317 +/* WRITE_10 0x2a */ DATAOUT,
4318 +/* SEEK_10 0x2b */ NODATA,
4320 +/* 0x2c */ NOSUPPORT,
4321 +/* 0x2d */ NOSUPPORT,
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,
4346 +/* READ_TOC 0x43 */ DATAIN,
4349 +/* 0x45 */ NOSUPPORT,
4350 +/* 0x46 */ NOSUPPORT,
4351 +/* 0x47 */ NOSUPPORT,
4352 +/* 0x48 */ NOSUPPORT,
4353 +/* 0x49 */ NOSUPPORT,
4354 +/* 0x4a */ NOSUPPORT,
4355 +/* 0x4b */ NOSUPPORT,
4357 +/* LOG_SELECT 0x4c */ DATAOUT,
4358 +/* LOG_SENSE 0x4d */ DATAIN,
4360 +/* 0x4e */ NOSUPPORT,
4361 +/* 0x4f */ NOSUPPORT,
4362 +/* 0x50 */ NOSUPPORT,
4365 +/* 0x53 */ DATAOUT,
4366 +/* 0x54 */ NOSUPPORT,
4368 +/* MODE_SELECT_10 0x55 */ DATAOUT,
4372 +/* 0x58 */ NOSUPPORT,
4373 +/* 0x59 */ NOSUPPORT,
4375 +/* MODE_SENSE_10 0x5a */ DATAIN,
4379 +/* 0x5d */ NOSUPPORT,
4380 +/* 0x5e */ NOSUPPORT,
4381 +/* 0x5f */ NOSUPPORT,
4383 +/* assign NOSUPPORT for 0x60 - 0x9f */
4385 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4386 + NOSUPPORT, NOSUPPORT,
4387 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4388 + NOSUPPORT, NOSUPPORT,
4390 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4391 + NOSUPPORT, NOSUPPORT,
4392 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4393 + NOSUPPORT, NOSUPPORT,
4395 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4396 + NOSUPPORT, NOSUPPORT,
4397 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4398 + NOSUPPORT, NOSUPPORT,
4400 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4401 + NOSUPPORT, NOSUPPORT,
4402 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4403 + NOSUPPORT, NOSUPPORT,
4405 +/* 0xa0 */ NOSUPPORT,
4406 +/* 0xa1 */ NOSUPPORT,
4407 +/* 0xa2 */ NOSUPPORT,
4408 +/* 0xa3 */ NOSUPPORT,
4409 +/* 0xa4 */ NOSUPPORT,
4411 +/* MOVE_MEDIUM 0xa5 */ NODATA,
4413 +/* 0xa6 */ NOSUPPORT,
4414 +/* 0xa7 */ NOSUPPORT,
4416 +/* READ_12 0xa8 */ DATAIN,
4418 +/* 0xa9 */ NOSUPPORT,
4420 +/* WRITE_12 0xaa */ DATAOUT,
4422 +/* 0xab */ NOSUPPORT,
4423 +/* 0xac */ NOSUPPORT,
4424 +/* 0xad */ NOSUPPORT,
4426 +/* WRITE_VERIFY_12 0xae */ DATAOUT,
4428 +/* 0xaf */ NOSUPPORT,
4430 +/* SEARCH_HIGH_12 0xb0 */ DATAOUT,
4431 +/* SEARCH_EQUAL_12 0xb1 */ DATAOUT,
4432 +/* SEARCH_LOW_12 0xb2 */ DATAOUT,
4434 +/* 0xb3 */ NOSUPPORT,
4435 +/* 0xb4 */ NOSUPPORT,
4436 +/* 0xb5 */ NOSUPPORT,
4438 +/* SEND_VOLUME_TAG 0xb6 */ DATAOUT,
4440 +/* 0xb7 */ NOSUPPORT,
4442 +/* READ_ELEMENT_STATUS 0xb8 */ DATAIN,
4444 +/* 0xb9 */ NOSUPPORT,
4445 +/* 0xba */ NOSUPPORT,
4446 +/* 0xbb */ DATAOUT,
4447 +/* 0xbc */ NOSUPPORT,
4449 +/* 0xbe */ NOSUPPORT,
4450 +/* 0xbf */ NOSUPPORT,
4452 +/* assign NOSUPPORT for 0xc0 - 0xdf */
4454 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4455 + NOSUPPORT, NOSUPPORT,
4456 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4457 + NOSUPPORT, NOSUPPORT,
4459 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4460 + NOSUPPORT, NOSUPPORT,
4461 + NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT, NOSUPPORT,
4462 + NOSUPPORT, NOSUPPORT,
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,
4475 +/* WRITE_LONG_2 0xea */ DATAOUT
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
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
4489 + See README.dpti for history, notes, license info, and credits
4490 + ***************************************************************************/
4492 +/***************************************************************************
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. *
4499 + ***************************************************************************/
4501 +/***************************************************************************
4502 + * This file is generated from osd_unix.h *
4503 + * *************************************************************************/
4505 +#ifndef _dpti_ioctl_h
4506 +#define _dpti_ioctl_h
4508 +// IOCTL interface commands
4511 +# define _IOWR(x,y,z) (((x)<<8)|y)
4514 +# define _IOW(x,y,z) (((x)<<8)|y)
4517 +# define _IOR(x,y,z) (((x)<<8)|y)
4520 +# define _IO(x,y) (((x)<<8)|y)
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)
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)
4563 + /* Structure Returned From Get Controller Info */
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) */
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))
4599 + ADAPTER_OBJECT *AdapterObject;
4600 + LARGE_INTEGER DmaLogicalAddress;
4601 + PVOID DmaVirtualAddress;
4602 + LARGE_INTEGER ReplyLogicalAddress;
4603 + PVOID ReplyVirtualAddress;
4605 + uLONG reserved1; // Reserved for future expansion
4606 + uLONG reserved2; // Reserved for future expansion
4607 + uLONG reserved3; // Reserved for future expansion
4611 +typedef struct TARGET_BUSY
4621 --- /dev/null Sat Apr 14 07:06:21 2001
4622 +++ linux/drivers/scsi/dptsig.h Wed Jul 18 14:31:28 2001
4624 +/* BSDI dptsig.h,v 1.7 1998/06/03 19:15:00 karels Exp */
4627 + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
4628 + * All rights reserved.
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.
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.
4648 +#ifndef __DPTSIG_H_
4649 +#define __DPTSIG_H_
4650 +#ifdef _SINIX_ADDON
4653 +/* DPT SIGNATURE SPEC AND HEADER FILE */
4654 +/* Signature Version 1 (sorry no 'A') */
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;
4662 +typedef unsigned long sigLONG;
4666 + * use sigWORDLittleEndian for:
4671 + * use sigLONGLittleEndian for:
4673 + * so that the sig can be standardised to Little Endian
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))
4683 +# define sigWORDLittleEndian(x) (x)
4684 +# define sigLONGLittleEndian(x) (x)
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. */
4695 +#if defined (_DPT_AIX)
4696 +#pragma options align=packed
4701 +/* For the Macintosh */
4702 +#if STRUCTALIGNMENTSUPPORTED
4703 +#pragma options align=mac68k
4707 +/* Current Signature Version - sigBYTE dsSigVersion; */
4708 +/* ------------------------------------------------------------------ */
4709 +#define SIG_VERSION 1
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 */
4723 +/* Specific Minimim Processor - sigBYTE dsProcessor; FLAG BITS */
4724 +/* ------------------------------------------------------------------ */
4725 +/* Different bit definitions dependent on processor_family */
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 */
4736 +#define PROC_960RX 0x01 /* Intel 80960RC/RD */
4737 +#define PROC_960HX 0x02 /* Intel 80960HA/HD/HT */
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 */
4747 +#define PROC_PPC601 0x01 /* PowerPC 601 */
4748 +#define PROC_PPC603 0x02 /* PowerPC 603 */
4749 +#define PROC_PPC604 0x04 /* PowerPC 604 */
4751 +/* PROC_MIPS4000: */
4752 +#define PROC_R4000 0x01 /* MIPS R4000 */
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 */
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 */
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 */
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 */
4829 +#define OS_OTHER 0x80000000 /* Other */
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 */
4844 +#define CAP_CACHEMODE 0x1000 /* dpt_force_cache is set in driver */
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 */
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 */
4876 + * Combinations of products
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
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 */
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 */
4911 + * You may adjust dsDescription_size with an override to a value less than
4912 + * 50 so that the structure allocates less real space.
4914 +#if (!defined(dsDescription_size))
4915 +# define dsDescription_size 50
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];
4941 +/* 32 bytes minimum - with no description. Put NULL at description[0] */
4942 +/* 81 bytes maximum - with 49 character description plus NULL. */
4944 +/* This line added at Roycroft's request */
4945 +/* Microsoft's NT compiler gets confused if you do a pack and don't */
4949 +#if defined (_DPT_AIX)
4950 +#pragma options align=reset
4951 +#elif defined (UNPACK_FOUR)
4957 +/* For the Macintosh */
4958 +#if STRUCTALIGNMENTSUPPORTED
4959 +#pragma options align=reset
4963 --- /dev/null Sat Apr 14 07:06:21 2001
4964 +++ linux/drivers/scsi/sys_info.h Wed Jul 18 14:31:28 2001
4966 +/* BSDI sys_info.h,v 1.6 1998/06/03 19:14:59 karels Exp */
4969 + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
4970 + * All rights reserved.
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.
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.
4990 +#ifndef __SYS_INFO_H
4991 +#define __SYS_INFO_H
4993 +/*File - SYS_INFO.H
4994 + ****************************************************************************
4998 + * This file contains structure definitions for the OS dependent
4999 + *layer system information buffers.
5001 + *Copyright Distributed Processing Technology, Corp.
5003 + * Maitland, Fl. 32751 USA
5004 + * Phone: (407) 830-5522 Fax: (407) 260-5366
5005 + * All Rights Reserved
5007 + *Author: Don Kemper
5015 + *****************************************************************************/
5018 +/*Include Files ------------------------------------------------------------- */
5020 +#include "osd_util.h"
5023 +#if defined (_DPT_AIX)
5024 +#pragma options align=packed
5028 +#endif // no unpack
5031 +/*struct - driveParam_S - start
5032 + *===========================================================================
5036 + * This structure defines the drive parameters seen during
5039 + *---------------------------------------------------------------------------*/
5042 + struct driveParam_S {
5047 + uSHORT cylinders; /* Upto 1024 */
5048 + uCHAR heads; /* Upto 255 */
5049 + uCHAR sectors; /* Upto 63 */
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 +//--------------------------------------------
5064 +/*driveParam_S - end */
5067 +/*struct - sysInfo_S - start
5068 + *===========================================================================
5072 + * This structure defines the command system information that
5073 + *should be returned by every OS dependent layer.
5075 + *---------------------------------------------------------------------------*/
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
5088 +#define SI_ALL_VALID 0x0FFF /* All Std SysInfo is valid */
5089 +#define SI_NO_SmartROM 0x8000
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
5098 + struct sysInfo_S {
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 */
5118 +#ifdef _SINIX_ADDON
5119 + uCHAR busType; /* See defininitions above */
5120 + uSHORT osSubRevision;
5121 + uCHAR pad[2]; /* For alignment */
5123 + uCHAR osSubRevision;
5124 + uCHAR busType; /* See defininitions above */
5125 + uCHAR pad[3]; /* For alignment */
5127 + driveParam_S drives[16]; /* SmartROM Logical Drives */
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 +//--------------------------------------------
5142 +/*sysInfo_S - end */
5145 +/*struct - DOS_Info_S - start
5146 + *===========================================================================
5150 + * This structure defines the system information specific to a
5153 + *---------------------------------------------------------------------------*/
5155 +/*flags - bit definitions */
5156 +#define DI_DOS_HIGH 0x01 /* DOS is loaded high */
5157 +#define DI_DPMI_VALID 0x02 /* DPMI version is valid */
5160 + struct DOS_Info_S {
5165 + uCHAR flags; /* See bit definitions above */
5166 + uSHORT driverLocation; /* SmartROM BIOS address */
5167 + uSHORT DOS_version;
5168 + uSHORT DPMI_version;
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 +//--------------------------------------------
5183 +/*DOS_Info_S - end */
5186 +/*struct - Netware_Info_S - start
5187 + *===========================================================================
5191 + * This structure defines the system information specific to a
5194 + *---------------------------------------------------------------------------*/
5197 + struct Netware_Info_S {
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;
5214 + uCHAR clibMajorVersion; /* The CLIB.NLM version */
5215 + uCHAR clibMinorVersion;
5216 + uCHAR clibRevision;
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 +//--------------------------------------------
5231 +/*Netware_Info_S - end */
5234 +/*struct - OS2_Info_S - start
5235 + *===========================================================================
5239 + * This structure defines the system information specific to an
5242 + *---------------------------------------------------------------------------*/
5245 + struct OS2_Info_S {
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 +//--------------------------------------------
5265 +/*OS2_Info_S - end */
5268 +/*struct - WinNT_Info_S - start
5269 + *===========================================================================
5273 + * This structure defines the system information specific to a
5274 + *Windows NT machine.
5276 + *---------------------------------------------------------------------------*/
5279 + struct WinNT_Info_S {
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 +//--------------------------------------------
5299 +/*WinNT_Info_S - end */
5302 +/*struct - SCO_Info_S - start
5303 + *===========================================================================
5307 + * This structure defines the system information specific to an
5308 + *SCO UNIX machine.
5310 + *---------------------------------------------------------------------------*/
5313 + struct SCO_Info_S {
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 +//--------------------------------------------
5333 +/*SCO_Info_S - end */
5336 +/*struct - USL_Info_S - start
5337 + *===========================================================================
5341 + * This structure defines the system information specific to a
5342 + *USL UNIX machine.
5344 + *---------------------------------------------------------------------------*/
5347 + struct USL_Info_S {
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 +//--------------------------------------------
5367 +/*USL_Info_S - end */
5370 + /* Restore default structure packing */
5372 +#if defined (_DPT_AIX)
5373 +#pragma options align=reset
5374 +#elif defined (UNPACK_FOUR)
5379 +#endif // no unpack
5381 +#endif // __SYS_INFO_H
5383 --- /dev/null Sat Apr 14 07:06:21 2001
5384 +++ linux/drivers/scsi/README.dpti Wed Jul 18 14:31:28 2001
5386 + /* TERMS AND CONDITIONS OF USE
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.
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.
5404 + ****************************************************************
5405 + * This driver supports the Adaptec I2O RAID and DPT SmartRAID V I2O boards.
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
5413 + * Thanks to Ricky Beam for supplying porting information to 2.3 kernel.
5415 + * 2.0 version of the driver by Deanna Bonds and Mark Salyzyn.
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.
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
5427 --- /dev/null Sat Apr 14 07:06:21 2001
5428 +++ linux/drivers/scsi/osd_util.h Wed Jul 18 14:31:28 2001
5430 +/* BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp */
5433 + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
5434 + * All rights reserved.
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.
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.
5454 +#ifndef __OSD_UTIL_H
5455 +#define __OSD_UTIL_H
5457 +/*File - OSD_UTIL.H
5458 + ****************************************************************************
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.
5466 + *Copyright Distributed Processing Technology, Corp.
5468 + * Maitland, Fl. 32751 USA
5469 + * Phone: (407) 830-5522 Fax: (407) 260-5366
5470 + * All Rights Reserved
5472 + *Author: Doug Anderson
5480 + *****************************************************************************/
5483 +/*Definitions - Defines & Constants ----------------------------------------- */
5485 +/*----------------------------- */
5486 +/* Operating system selections: */
5487 +/*----------------------------- */
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 */
5501 +/*-------------------------------- */
5502 +/* Include the OS specific defines */
5503 +/*-------------------------------- */
5505 +/*#define OS_SELECTION From Above List */
5506 +/*#define SEMAPHORE_T ??? */
5507 +/*#define DLL_HANDLE_T ??? */
5509 +#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
5510 +# include "i386/isa/dpt_osd_defs.h"
5512 +# include "osd_defs.h"
5515 +#ifndef DPT_UNALIGNED
5516 + #define DPT_UNALIGNED
5520 + #define DPT_EXPORT
5524 + #define DPT_IMPORT
5527 +#ifndef DPT_RUNTIME_IMPORT
5528 + #define DPT_RUNTIME_IMPORT DPT_IMPORT
5531 +/*--------------------- */
5532 +/* OS dependent defines */
5533 +/*--------------------- */
5535 +#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
5536 + #define _DPT_16_BIT
5538 + #define _DPT_32_BIT
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)
5545 +#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
5546 + || defined (_DPT_OS2)
5547 + #define _DPT_DLL_SUPPORT
5550 +#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
5551 + #define _DPT_PREEMPTIVE
5554 +#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
5555 + #define _DPT_MULTI_THREADED
5558 +#if !defined (_DPT_MSDOS)
5559 + #define _DPT_MULTI_TASKING
5562 + /* These exist for platforms that */
5563 + /* chunk when accessing mis-aligned */
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
5573 + /* Determine if in C or C++ mode */
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*". */
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. */
5591 +/*-------------------------------------------------------------------*/
5592 +#if !defined (DPTSQO)
5593 + #if defined (_DPT_SOLARIS)
5599 + #endif /* solaris */
5600 +#endif /* DPTSQO */
5603 +/*---------------------- */
5604 +/* OS dependent typedefs */
5605 +/*---------------------- */
5607 +#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
5608 + #define BYTE unsigned char
5609 + #define WORD unsigned short
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;
5626 +#if !defined (NULL)
5631 +/*Prototypes - function ----------------------------------------------------- */
5634 + extern "C" { /* Declare all these functions as "C" functions */
5637 +/*------------------------ */
5638 +/* Byte reversal functions */
5639 +/*------------------------ */
5641 + /* Reverses the byte ordering of a 2 byte variable */
5642 +#if (!defined(osdSwap2))
5643 + uSHORT osdSwap2(DPT_UNALIGNED uSHORT *);
5644 +#endif // !osdSwap2
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
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);
5660 + #define osdSwap4(inLong) DPT_Bswapl(inLong)
5661 + #endif // cplusplus
5663 + /* Reverses the byte ordering of a 4 byte variable */
5664 +# if (!defined(osdSwap4))
5665 + uLONG osdSwap4(DPT_UNALIGNED uLONG *);
5666 +# endif // !osdSwap4
5668 + /* The following functions ALWAYS swap regardless of the *
5669 + * presence of DPT_BIG_ENDIAN */
5671 + uSHORT trueSwap2(DPT_UNALIGNED uSHORT *);
5672 + uLONG trueSwap4(DPT_UNALIGNED uLONG *);
5677 +/*-------------------------------------*
5678 + * Network order swap functions *
5680 + * These functions/macros will be used *
5681 + * by the structure insert()/extract() *
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);
5692 +#if defined (_DPT_BIG_ENDIAN)
5694 +// for big-endian we need to swap
5697 +#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
5698 +#endif // NET_SWAP_2
5701 +#define NET_SWAP_4(x) netSwap4((x))
5702 +#endif // NET_SWAP_4
5706 +// for little-endian we don't need to do anything
5709 +#define NET_SWAP_2(x) (x)
5710 +#endif // NET_SWAP_2
5713 +#define NET_SWAP_4(x) (x)
5714 +#endif // NET_SWAP_4
5716 +#endif // big endian
5720 +/*----------------------------------- */
5721 +/* Run-time loadable module functions */
5722 +/*----------------------------------- */
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 *);
5731 +/*--------------------------------------- */
5732 +/* Mutually exclusive semaphore functions */
5733 +/*--------------------------------------- */
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 *);
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);
5757 +/*----------------- */
5758 +/* Thread functions */
5759 +/*----------------- */
5761 + /* Releases control to the task switcher in non-preemptive */
5762 + /* multitasking operating systems. */
5763 +void osdSwitchThreads(void);
5765 + /* Starts a thread function */
5766 +uLONG osdStartThread(void *,void *);
5768 +/* what is my thread id */
5769 +uLONG osdGetThreadID(void);
5771 +/* wakes up the specifed thread */
5772 +void osdWakeThread(uLONG);
5774 +/* osd sleep for x miliseconds */
5775 +void osdSleep(uLONG);
5777 +#define DPT_THREAD_PRIORITY_LOWEST 0x00
5778 +#define DPT_THREAD_PRIORITY_NORMAL 0x01
5779 +#define DPT_THREAD_PRIORITY_HIGHEST 0x02
5781 +uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
5784 + } /* end the xtern "C" declaration */
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
5791 +/* BSDI osd_defs.h,v 1.4 1998/06/03 19:14:58 karels Exp */
5793 + * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
5794 + * All rights reserved.
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.
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.
5814 +#ifndef _OSD_DEFS_H
5815 +#define _OSD_DEFS_H
5817 +/*File - OSD_DEFS.H
5818 + ****************************************************************************
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.
5825 + *Copyright Distributed Processing Technology, Corp.
5827 + * Maitland, Fl. 32751 USA
5828 + * Phone: (407) 830-5522 Fax: (407) 260-5366
5829 + * All Rights Reserved
5831 + *Author: Doug Anderson
5839 + *****************************************************************************/
5842 +/*Definitions - Defines & Constants ----------------------------------------- */
5844 + /* Define the operating system */
5845 +#if (defined(__linux__))
5846 +# define _DPT_LINUX
5847 +#elif (defined(__bsdi__))
5849 +#elif (defined(__FreeBSD__))
5850 +# define _DPT_FREE_BSD
5855 +#if defined (ZIL_CURSES)
5856 +#define _DPT_CURSES
5861 + /* Redefine 'far' to nothing - no far pointer type required in UNIX */
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 *
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
5874 + * I2O user space accessible structures/APIs
5876 + * (c) Copyright 1999, 2000 Red Hat Software
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.
5883 + *************************************************************************
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.
5895 +/* How many controllers are we allowing */
5896 +#define MAX_I2O_CONTROLLERS 32
5898 +#include <linux/ioctl.h>
5901 + * I2O Control IOCTLs and structures
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)
5917 +struct i2o_cmd_hrtlct
5919 + unsigned int iop; /* IOP unit number */
5920 + void *resbuf; /* Buffer for result */
5921 + unsigned int *reslen; /* Buffer length in bytes */
5924 +struct i2o_cmd_psetget
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 */
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 */
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 */
5957 +#define I2O_EVT_Q_LEN 32
5963 + unsigned int evt_mask;
5966 +/* Event data size = frame size - message header + evt indicator */
5967 +#define I2O_EVT_DATA_SIZE 88
5969 +struct i2o_evt_info
5971 + struct i2o_evt_id id;
5972 + unsigned char evt_data[I2O_EVT_DATA_SIZE];
5973 + unsigned int data_size;
5978 + struct i2o_evt_info info;
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
5999 +typedef unsigned char u8;
6000 +typedef unsigned short u16;
6001 +typedef unsigned int u32;
6003 +#endif /* __KERNEL__ */
6005 +typedef struct _i2o_pci_bus {
6006 + u8 PciFunctionNumber;
6007 + u8 PciDeviceNumber;
6014 +typedef struct _i2o_local_bus {
6017 + u32 LbBaseMemoryAddress;
6020 +typedef struct _i2o_isa_bus {
6021 + u16 IsaBaseIOPort;
6024 + u32 IsaBaseMemoryAddress;
6027 +typedef struct _i2o_eisa_bus_info {
6028 + u16 EisaBaseIOPort;
6030 + u8 EisaSlotNumber;
6031 + u32 EisaBaseMemoryAddress;
6034 +typedef struct _i2o_mca_bus {
6035 + u16 McaBaseIOPort;
6038 + u32 McaBaseMemoryAddress;
6041 +typedef struct _i2o_other_bus {
6044 + u32 BaseMemoryAddress;
6047 +typedef struct _i2o_hrt_entry {
6049 + u32 parent_tid:12;
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;
6063 +typedef struct _i2o_hrt {
6068 + i2o_hrt_entry hrt_entry[1];
6071 +typedef struct _i2o_lct_entry {
6072 + u32 entry_size:16;
6082 + u32 parent_tid:12;
6084 + u8 identity_tag[8];
6085 + u32 event_capabilities;
6088 +typedef struct _i2o_lct {
6089 + u32 table_size:16;
6094 + i2o_lct_entry lct_entry[1];
6097 +typedef struct _i2o_status_block {
6103 + u16 segment_number:12;
6104 + u16 i2o_version:4;
6107 + u16 inbound_frame_size;
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;
6124 +} i2o_status_block;
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
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
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
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
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
6172 +#define I2O_EVT_CAPABILITY_OTHER 0x01
6173 +#define I2O_EVT_CAPABILITY_CHANGED 0x02
6175 +#define I2O_EVT_SENSOR_STATE_CHANGED 0x01
6178 + * I2O classes / subclasses
6181 +/* Class ID and Code Assignments
6182 + * (LCT.ClassID.Version field)
6184 +#define I2O_CLASS_VERSION_10 0x00
6185 +#define I2O_CLASS_VERSION_11 0x01
6187 +/* Class code names
6188 + * (from v1.5 Table 6-1 Class Code Assignments.)
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
6209 + * Rest of 0x092 - 0x09f reserved for peer-to-peer classes
6212 +#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff
6218 +#define I2O_SUBCLASS_i960 0x001
6219 +#define I2O_SUBCLASS_HDM 0x020
6220 +#define I2O_SUBCLASS_ISM 0x021
6222 +/* Operation functions */
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
6236 + * I2O serial number conventions / formats
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
6248 + * Plus new in v2.0 (Yellowstone pdf doc)
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
6258 + * I2O Get Status State values
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
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
6275 +/* I2O kernel space accessible structures/APIs
6277 + * (c) Copyright 1999, 2000 Red Hat Software
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.
6284 + *************************************************************************
6286 + * This header file defined the I2O APIs/structures for use by
6287 + * the I2O kernel modules.
6291 +#ifdef __KERNEL__ /* This file to be included by kernel only */
6293 +#include "dpti_i2o-dev.h"
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>
6302 + * Tunable parameters first
6305 +/* How many different OSM's are we allowing */
6306 +#define MAX_I2O_MODULES 64
6308 +#define I2O_EVT_CAPABILITY_OTHER 0x01
6309 +#define I2O_EVT_CAPABILITY_CHANGED 0x02
6311 +#define I2O_EVT_SENSOR_STATE_CHANGED 0x01
6313 +//#ifdef __KERNEL__ /* ioctl stuff only thing exported to users */
6315 +#define I2O_MAX_MANAGERS 4
6317 +#include <asm/semaphore.h> /* Needed for MUTEX init macros */
6320 + * I2O Interface Objects
6323 +#include <linux/config.h>
6324 +#include <linux/notifier.h>
6325 +#include <asm/atomic.h>
6327 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
6329 +#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
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;
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;
6343 + * message structures
6348 + u8 version_offset;
6351 + u32 target_tid:12;
6354 + u32 initiator_context;
6355 + /* List follows */
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.
6365 + i2o_lct_entry lct_data;/* Device LCT information */
6367 + int i2oversion; /* I2O version supported. Actually there
6368 + * should be high and low version */
6370 + struct proc_dir_entry* proc_entry; /* /proc dir */
6372 + /* Primary user */
6373 + struct i2o_handler *owner;
6375 + /* Management users */
6376 + struct i2o_handler *managers[I2O_MAX_MANAGERS];
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 */
6386 + * Resource data for each PCI I2O controller
6399 + * Each I2O controller has one of these objects
6402 +struct i2o_controller
6409 +#define I2O_TYPE_PCI 0x01 /* PCI I2O controller */
6411 + struct notifier_block *event_notifer; /* Events */
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 */
6419 + /* Dynamic LCT related data */
6420 + struct semaphore lct_sem;
6424 + i2o_status_block *status_block; /* IOP status block */
6425 + i2o_lct *lct; /* Logical Config Table */
6426 + i2o_lct *dlct; /* Temp LCT */
6429 + u32 mem_offset; /* MFA offset */
6430 + u32 mem_phys; /* MFA physical */
6433 + u32 priv_mem_size;
6437 + struct proc_dir_entry* proc_entry; /* /proc dir */
6440 + { /* Bus information */
6441 + struct i2o_pci pci;
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);
6453 + void *page_frame; /* Message buffers */
6454 + int inbound_size; /* Inbound queue size */
6459 + /* Message reply handler */
6461 + void (*reply)(struct i2o_handler *, struct i2o_controller *, struct i2o_message *);
6463 + /* New device notification handler */
6464 + void (*new_dev_notify)(struct i2o_controller *, struct i2o_device *);
6466 + /* Device deltion handler */
6467 + void (*dev_del_notify)(struct i2o_controller *, struct i2o_device *);
6469 + /* Reboot notification handler */
6470 + void (*reboot_notify)(void);
6473 + int context; /* Low 8 bits of the transaction info */
6474 + u32 class; /* I2O classes that this driver handles */
6475 + /* User data follows */
6480 + * Used by bus specific modules to communicate with the core
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 :)
6489 +struct i2o_core_func_table
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 *);
6501 + * I2O System table entry
6503 +struct i2o_sys_tbl_entry
6510 + u16 i2o_version:4;
6516 + u32 iop_capabilities;
6529 + struct i2o_sys_tbl_entry iops[0];
6533 + * Messenger inlines
6535 +extern inline u32 I2O_POST_READ32(struct i2o_controller *c)
6537 + return *c->post_port;
6540 +extern inline void I2O_POST_WRITE32(struct i2o_controller *c, u32 Val)
6542 + *c->post_port = Val;
6546 +extern inline u32 I2O_REPLY_READ32(struct i2o_controller *c)
6548 + return *c->reply_port;
6551 +extern inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 Val)
6553 + *c->reply_port= Val;
6557 +extern inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
6559 + return *c->irq_mask;
6562 +extern inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 Val)
6564 + *c->irq_mask = Val;
6568 +extern inline void i2o_post_message(struct i2o_controller *c, u32 m)
6570 + /* The second line isnt spurious - thats forcing PCI posting */
6571 + I2O_POST_WRITE32(c,m);
6572 + (void) I2O_IRQ_READ32(c);
6575 +extern inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
6577 + I2O_REPLY_WRITE32(c,m);
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;
6587 +extern int i2o_install_handler(struct i2o_handler *);
6588 +extern int i2o_remove_handler(struct i2o_handler *);
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 *);
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);
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);
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 *,
6608 +extern int i2o_row_delete_table(struct i2o_controller *, int, int, int, void *, int);
6610 +extern int i2o_event_register(struct i2o_controller *, u32, u32,u32, u32);
6611 +extern int i2o_event_ack(struct i2o_controller *, u32 *);
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 *);
6617 +extern const char *i2o_get_class_name(int);
6621 + * I2O classes / subclasses
6624 +/* Class ID and Code Assignments
6625 + * (LCT.ClassID.Version field)
6627 +#define I2O_CLASS_VERSION_10 0x00
6628 +#define I2O_CLASS_VERSION_11 0x01
6630 +/* Class code names
6631 + * (from v1.5 Table 6-1 Class Code Assignments.)
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
6651 +/* Rest of 0x092 - 0x09f reserved for peer-to-peer classes
6654 +#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff
6659 +#define I2O_SUBCLASS_i960 0x001
6660 +#define I2O_SUBCLASS_HDM 0x020
6661 +#define I2O_SUBCLASS_ISM 0x021
6663 +/* Operation functions */
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
6677 + * I2O serial number conventions / formats
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
6688 +/* Plus new in v2.0 (Yellowstone pdf doc)
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
6697 +/* Transaction Reply Lists (TRL) Control Word structure */
6699 +#define TRL_SINGLE_FIXED_LENGTH 0x00
6700 +#define TRL_SINGLE_VARIABLE_LENGTH 0x40
6701 +#define TRL_MULTIPLE_FIXED_LENGTH 0x80
6704 + * Messaging API values
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
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
6756 +#define I2O_CMD_SCSI_EXEC 0x81
6757 +#define I2O_CMD_SCSI_ABORT 0x83
6758 +#define I2O_CMD_SCSI_BUSRESET 0x27
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
6768 +#define I2O_PRIVATE_MSG 0xFF
6771 + * Init Outbound Q status
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
6780 + * I2O Get Status State values
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
6791 +/* I2O API function return values */
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
6806 +/* Reply message status defines for all messages */
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
6821 +/* Status codes and Error Information for Parameter functions */
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
6841 +/* DetailedStatusCode defines for Executive, DDM, Util and Transaction error
6842 + * messages: Table 3-2 Detailed Status Codes.*/
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
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
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)
6893 +#define TRL_OFFSET_5 (0x0050 | I2OVERSION)
6894 +#define TRL_OFFSET_6 (0x0060 | I2OVERSION)
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
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)
6916 +/* Special TID Assignments */
6918 +#define ADAPTER_TID 0
6921 +#define MSG_FRAME_SIZE 128
6922 +#define NMBR_MSG_FRAMES 128
6924 +#define MSG_POOL_SIZE 16384
6926 +#define I2O_POST_WAIT_OK 0
6927 +#define I2O_POST_WAIT_TIMEOUT -ETIMEDOUT
6930 +#endif /* __KERNEL__ */
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 @@
6939 +ifeq ($(CONFIG_SCSI_DPT_I2O),y)
6940 +L_OBJS += dpt_i2o.o
6942 + ifeq ($(CONFIG_SCSI_DPT_I2O),m)
6943 + M_OBJS += dpt_i2o.o
6947 ifeq ($(CONFIG_SCSI_EATA_DMA),y)
6948 L_OBJS += eata_dma.o
6952 sd_mod.o: sd.o sd_ioctl.o
6953 $(LD) $(LD_RFLAG) -r -o $@ sd.o sd_ioctl.o
6956 + $(CC) $(CFLAGS) -c dpti.c -o dpt_i2o.o
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
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
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"
6974 +#ifdef CONFIG_SCSI_DPT_I2O
6978 #ifdef CONFIG_SCSI_EATA_DMA
6979 #include "eata_dma.h"
6983 #ifdef CONFIG_SCSI_NCR53C8XX
6986 +#ifdef CONFIG_SCSI_DPT_I2O
6989 #ifdef CONFIG_SCSI_EATA_DMA