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