152e26a6428e3f174d22ee53abbbc7eb3c608f84
[linux-flexiantxendom0-3.2.10.git] / drivers / scsi / ini9100u.c
1 /**************************************************************************
2  * Initio 9100 device driver for Linux.
3  *
4  * Copyright (c) 1994-1998 Initio Corporation
5  * Copyright (c) 1998 Bas Vermeulen <bvermeul@blackstar.xs4all.nl>
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; see the file COPYING.  If not, write to
20  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * --------------------------------------------------------------------------
23  *
24  * Redistribution and use in source and binary forms, with or without
25  * modification, are permitted provided that the following conditions
26  * are met:
27  * 1. Redistributions of source code must retain the above copyright
28  *    notice, this list of conditions, and the following disclaimer,
29  *    without modification, immediately at the beginning of the file.
30  * 2. Redistributions in binary form must reproduce the above copyright
31  *    notice, this list of conditions and the following disclaimer in the
32  *    documentation and/or other materials provided with the distribution.
33  * 3. The name of the author may not be used to endorse or promote products
34  *    derived from this software without specific prior written permission.
35  *
36  * Where this Software is combined with software released under the terms of 
37  * the GNU General Public License ("GPL") and the terms of the GPL would require the 
38  * combined work to also be released under the terms of the GPL, the terms
39  * and conditions of this License will apply in addition to those of the
40  * GPL with the exception of any terms or conditions of this License that
41  * conflict with, or are expressly prohibited by, the GPL.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
44  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
47  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53  * SUCH DAMAGE.
54  *
55  *************************************************************************
56  *
57  * DESCRIPTION:
58  *
59  * This is the Linux low-level SCSI driver for Initio INI-9X00U/UW SCSI host
60  * adapters
61  *
62  * 08/06/97 hc  - v1.01h
63  *              - Support inic-940 and inic-935
64  * 09/26/97 hc  - v1.01i
65  *              - Make correction from J.W. Schultz suggestion
66  * 10/13/97 hc  - Support reset function
67  * 10/21/97 hc  - v1.01j
68  *              - Support 32 LUN (SCSI 3)
69  * 01/14/98 hc  - v1.01k
70  *              - Fix memory allocation problem
71  * 03/04/98 hc  - v1.01l
72  *              - Fix tape rewind which will hang the system problem
73  *              - Set can_queue to tul_num_scb
74  * 06/25/98 hc  - v1.01m
75  *              - Get it work for kernel version >= 2.1.75
76  *              - Dynamic assign SCSI bus reset holding time in init_tulip()
77  * 07/02/98 hc  - v1.01n
78  *              - Support 0002134A
79  * 08/07/98 hc  - v1.01o
80  *              - Change the tul_abort_srb routine to use scsi_done. <01>
81  * 09/07/98 hl  - v1.02
82  *              - Change the INI9100U define and proc_dir_entry to
83  *                reflect the newer Kernel 2.1.118, but the v1.o1o
84  *                should work with Kernel 2.1.118.
85  * 09/20/98 wh  - v1.02a
86  *              - Support Abort command.
87  *              - Handle reset routine.
88  * 09/21/98 hl  - v1.03
89  *              - remove comments.
90  * 12/09/98 bv  - v1.03a
91  *              - Removed unused code
92  * 12/13/98 bv  - v1.03b
93  *              - Remove cli() locking for kernels >= 2.1.95. This uses
94  *                spinlocks to serialize access to the pSRB_head and
95  *                pSRB_tail members of the HCS structure.
96  * 09/01/99 bv  - v1.03d
97  *              - Fixed a deadlock problem in SMP.
98  * 21/01/99 bv  - v1.03e
99  *              - Add support for the Domex 3192U PCI SCSI
100  *                This is a slightly modified patch by
101  *                Brian Macy <bmacy@sunshinecomputing.com>
102  * 22/02/99 bv  - v1.03f
103  *              - Didn't detect the INIC-950 in 2.0.x correctly.
104  *                Now fixed.
105  * 05/07/99 bv  - v1.03g
106  *              - Changed the assumption that HZ = 100
107  **************************************************************************/
108
109 #define CVT_LINUX_VERSION(V,P,S)        (V * 65536 + P * 256 + S)
110
111 #error Please convert me to Documentation/DMA-mapping.txt
112
113 #ifndef LINUX_VERSION_CODE
114 #include <linux/version.h>
115 #endif
116
117 #include <linux/module.h>
118 #include <linux/errno.h>
119 #include <linux/delay.h>
120 #include <linux/pci.h>
121 #include <linux/init.h>
122 #include <linux/blkdev.h>
123 #include <linux/spinlock.h>
124 #include <linux/stat.h>
125 #include <linux/config.h>
126 #include <linux/kernel.h>
127 #include <linux/proc_fs.h>
128 #include <linux/string.h>
129 #include <linux/interrupt.h>
130 #include <linux/ioport.h>
131 #include <linux/sched.h>
132 #include <linux/slab.h>
133
134 #include <asm/io.h>
135
136 #include "scsi.h"
137 #include "hosts.h"
138 #include "ini9100u.h"
139
140 #ifdef DEBUG_i91u
141 unsigned int i91u_debug = DEBUG_DEFAULT;
142 #endif
143
144 static Scsi_Host_Template driver_template = {
145         .proc_name      = "INI9100U",
146         .proc_info      = "INI9100U",
147         .name           = i91u_REVID,
148         .detect         = i91u_detect,
149         .release        = i91u_release,
150         .queuecommand   = i91u_queue,
151         .abort          = i91u_abort,
152         .reset          = i91u_reset,
153         .bios_param     = i91u_biosparam,
154         .can_queue      = 1,
155         .this_id        = 1,
156         .sg_tablesize   = SG_ALL,
157         .cmd_per_lun    = 1,
158         .use_clustering = ENABLE_CLUSTERING,
159 };
160 #include "scsi_module.c"
161
162 char *i91uCopyright = "Copyright (C) 1996-98";
163 char *i91uInitioName = "by Initio Corporation";
164 char *i91uProductName = "INI-9X00U/UW";
165 char *i91uVersion = "v1.03g";
166
167 #define TULSZ(sz)     (sizeof(sz) / sizeof(sz[0]))
168 #define TUL_RDWORD(x,y)         (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
169
170 /* set by i91_setup according to the command line */
171 static int setup_called = 0;
172
173 static int tul_num_ch = 4;      /* Maximum 4 adapters           */
174 static int tul_num_scb;
175 static int tul_tag_enable = 1;
176 static SCB *tul_scb;
177
178 #ifdef DEBUG_i91u
179 static int setup_debug = 0;
180 #endif
181
182 static char *setup_str = (char *) NULL;
183
184 static irqreturn_t i91u_intr0(int irq, void *dev_id, struct pt_regs *);
185 static irqreturn_t i91u_intr1(int irq, void *dev_id, struct pt_regs *);
186 static irqreturn_t i91u_intr2(int irq, void *dev_id, struct pt_regs *);
187 static irqreturn_t i91u_intr3(int irq, void *dev_id, struct pt_regs *);
188 static irqreturn_t i91u_intr4(int irq, void *dev_id, struct pt_regs *);
189 static irqreturn_t i91u_intr5(int irq, void *dev_id, struct pt_regs *);
190 static irqreturn_t i91u_intr6(int irq, void *dev_id, struct pt_regs *);
191 static irqreturn_t i91u_intr7(int irq, void *dev_id, struct pt_regs *);
192
193 static void i91u_panic(char *msg);
194
195 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb);
196
197                                 /* ---- EXTERNAL FUNCTIONS ---- */
198                                         /* Get total number of adapters */
199 extern void init_i91uAdapter_table(void);
200 extern int Addi91u_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE);
201 extern int tul_ReturnNumberOfAdapters(void);
202 extern void get_tulipPCIConfig(HCS * pHCB, int iChannel_index);
203 extern int init_tulip(HCS * pHCB, SCB * pSCB, int tul_num_scb, BYTE * pbBiosAdr, int reset_time);
204 extern SCB *tul_alloc_scb(HCS * pHCB);
205 extern int tul_abort_srb(HCS * pHCB, Scsi_Cmnd * pSRB);
206 extern void tul_exec_scb(HCS * pHCB, SCB * pSCB);
207 extern void tul_release_scb(HCS * pHCB, SCB * pSCB);
208 extern void tul_stop_bm(HCS * pHCB);
209 extern int tul_reset_scsi(HCS * pCurHcb, int seconds);
210 extern int tul_isr(HCS * pHCB);
211 extern int tul_reset(HCS * pHCB, Scsi_Cmnd * pSRB, unsigned char target);
212 extern int tul_reset_scsi_bus(HCS * pCurHcb);
213 extern int tul_device_reset(HCS * pCurHcb, ULONG pSrb, unsigned int target, unsigned int ResetFlags);
214                                 /* ---- EXTERNAL VARIABLES ---- */
215 extern HCS tul_hcs[];
216
217 const PCI_ID i91u_pci_devices[] = {
218         { INI_VENDOR_ID, I950_DEVICE_ID },
219         { INI_VENDOR_ID, I940_DEVICE_ID },
220         { INI_VENDOR_ID, I935_DEVICE_ID },
221         { INI_VENDOR_ID, I920_DEVICE_ID },
222         { DMX_VENDOR_ID, I920_DEVICE_ID },
223 };
224
225 /*
226  *  queue services:
227  */
228 /*****************************************************************************
229  Function name  : i91uAppendSRBToQueue
230  Description    : This function will push current request into save list
231  Input          : pSRB  -       Pointer to SCSI request block.
232                   pHCB  -       Pointer to host adapter structure
233  Output         : None.
234  Return         : None.
235 *****************************************************************************/
236 static void i91uAppendSRBToQueue(HCS * pHCB, Scsi_Cmnd * pSRB)
237 {
238         ULONG flags;
239         spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
240
241         pSRB->next = NULL;      /* Pointer to next              */
242
243         if (pHCB->pSRB_head == NULL)
244                 pHCB->pSRB_head = pSRB;
245         else
246                 pHCB->pSRB_tail->next = pSRB;   /* Pointer to next              */
247         pHCB->pSRB_tail = pSRB;
248
249         spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
250         return;
251 }
252
253 /*****************************************************************************
254  Function name  : i91uPopSRBFromQueue
255  Description    : This function will pop current request from save list
256  Input          : pHCB  -       Pointer to host adapter structure
257  Output         : None.
258  Return         : pSRB  -       Pointer to SCSI request block.
259 *****************************************************************************/
260 static Scsi_Cmnd *i91uPopSRBFromQueue(HCS * pHCB)
261 {
262         Scsi_Cmnd *pSRB;
263         ULONG flags;
264
265         spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
266
267         if ((pSRB = pHCB->pSRB_head) != NULL) {
268                 pHCB->pSRB_head = pHCB->pSRB_head->next;
269                 pSRB->next = NULL;
270         }
271         spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
272
273         return (pSRB);
274 }
275
276 /* called from init/main.c */
277
278 void i91u_setup(char *str, int *ints)
279 {
280         if (setup_called)
281                 i91u_panic("i91u: i91u_setup called twice.\n");
282
283         setup_called = ints[0];
284         setup_str = str;
285
286 #ifdef DEBUG_i91u
287         setup_debug = ints[0] >= 1 ? ints[1] : DEBUG_DEFAULT;
288 #endif
289 }
290
291 int tul_NewReturnNumberOfAdapters(void)
292 {
293         struct pci_dev *pDev = NULL;    /* Start from none              */
294         int iAdapters = 0;
295         long dRegValue;
296         WORD wBIOS;
297         int i = 0;
298
299         init_i91uAdapter_table();
300
301         for (i = 0; i < TULSZ(i91u_pci_devices); i++)
302         {
303                 while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) {
304                         if (pci_enable_device(pDev))
305                                 continue;
306                         pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
307                         wBIOS = (UWORD) (dRegValue & 0xFF);
308                         if (((dRegValue & 0xFF00) >> 8) == 0xFF)
309                                 dRegValue = 0;
310                         wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
311                         if (Addi91u_into_Adapter_table(wBIOS,
312                                                         (pDev->resource[0].start),
313                                                         pDev->irq,
314                                                         pDev->bus->number,
315                                                         (pDev->devfn >> 3)
316                                 ) == 0)
317                                 iAdapters++;
318                 }
319         }
320
321         return (iAdapters);
322 }
323
324 int i91u_detect(Scsi_Host_Template * tpnt)
325 {
326         SCB *pSCB;
327         HCS *pHCB;
328         struct Scsi_Host *hreg;
329         unsigned long i;        /* 01/14/98                     */
330         int ok = 0, iAdapters;
331         ULONG dBiosAdr;
332         BYTE *pbBiosAdr;
333
334         tpnt->proc_name = "INI9100U";
335
336         if (setup_called) {     /* Setup by i91u_setup          */
337                 printk("i91u: processing commandline: ");
338
339 #ifdef DEBUG_i91u
340                 if (setup_called > 1) {
341                         printk("\ni91u: %s\n", setup_str);
342                         printk("i91u: usage: i91u[=<DEBUG>]\n");
343                         i91u_panic("i91u panics in line %d", __LINE__);
344                 }
345                 i91u_debug = setup_debug;
346 #endif
347         }
348         /* Get total number of adapters in the motherboard */
349 #ifdef CONFIG_PCI
350         iAdapters = tul_NewReturnNumberOfAdapters();
351 #else
352         iAdapters = tul_ReturnNumberOfAdapters();
353 #endif
354
355         if (iAdapters == 0)     /* If no tulip founded, return */
356                 return (0);
357
358         tul_num_ch = (iAdapters > tul_num_ch) ? tul_num_ch : iAdapters;
359         /* Update actually channel number */
360         if (tul_tag_enable) {   /* 1.01i                  */
361                 tul_num_scb = MAX_TARGETS * i91u_MAXQUEUE;
362         } else {
363                 tul_num_scb = MAX_TARGETS + 3;  /* 1-tape, 1-CD_ROM, 1- extra */
364         }                       /* Update actually SCBs per adapter */
365
366         /* Get total memory needed for HCS */
367         i = tul_num_ch * sizeof(HCS);
368         memset((unsigned char *) &tul_hcs[0], 0, i);    /* Initialize tul_hcs 0 */
369         /* Get total memory needed for SCB */
370
371         for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) {
372                 i = tul_num_ch * tul_num_scb * sizeof(SCB);
373                 if ((tul_scb = (SCB *) kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL)
374                         break;
375         }
376         if (tul_scb == NULL) {
377                 printk("i91u: SCB memory allocation error\n");
378                 return (0);
379         }
380         memset((unsigned char *) tul_scb, 0, i);
381
382         pSCB = tul_scb;
383         for (i = 0; i < tul_num_ch * tul_num_scb; i++, pSCB++) {
384                 pSCB->SCB_SGPAddr = (U32) VIRT_TO_BUS(&pSCB->SCB_SGList[0]);
385         }
386
387         for (i = 0, pHCB = &tul_hcs[0];         /* Get pointer for control block */
388              i < tul_num_ch;
389              i++, pHCB++) {
390                 pHCB->pSRB_head = NULL;         /* Initial SRB save queue       */
391                 pHCB->pSRB_tail = NULL;         /* Initial SRB save queue       */
392                 pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED;   /* SRB save queue lock */
393                 get_tulipPCIConfig(pHCB, i);
394
395                 dBiosAdr = pHCB->HCS_BIOS;
396                 dBiosAdr = (dBiosAdr << 4);
397
398                 pbBiosAdr = phys_to_virt(dBiosAdr);
399
400                 init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10);
401                 request_region(pHCB->HCS_Base, 256, "i91u"); /* Register */ 
402
403                 pHCB->HCS_Index = i;    /* 7/29/98 */
404                 hreg = scsi_register(tpnt, sizeof(HCS));
405                 if(hreg == NULL)
406                 {
407                         release_region(pHCB->HCS_Base, 256);
408                         return 0;
409                 }
410                 hreg->io_port = pHCB->HCS_Base;
411                 hreg->n_io_port = 0xff;
412                 hreg->can_queue = tul_num_scb;  /* 03/05/98                      */
413                 hreg->unique_id = pHCB->HCS_Base;
414                 hreg->max_id = pHCB->HCS_MaxTar;
415                 hreg->max_lun = 32;     /* 10/21/97                     */
416                 hreg->irq = pHCB->HCS_Intr;
417                 hreg->this_id = pHCB->HCS_SCSI_ID;      /* Assign HCS index           */
418                 hreg->base = (unsigned long)pHCB;
419                 hreg->sg_tablesize = TOTAL_SG_ENTRY;    /* Maximun support is 32 */
420
421                 /* Initial tulip chip           */
422                 switch (i) {
423                 case 0:
424                         ok = request_irq(pHCB->HCS_Intr, i91u_intr0, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);
425                         break;
426                 case 1:
427                         ok = request_irq(pHCB->HCS_Intr, i91u_intr1, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);
428                         break;
429                 case 2:
430                         ok = request_irq(pHCB->HCS_Intr, i91u_intr2, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);
431                         break;
432                 case 3:
433                         ok = request_irq(pHCB->HCS_Intr, i91u_intr3, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);
434                         break;
435                 case 4:
436                         ok = request_irq(pHCB->HCS_Intr, i91u_intr4, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);
437                         break;
438                 case 5:
439                         ok = request_irq(pHCB->HCS_Intr, i91u_intr5, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);
440                         break;
441                 case 6:
442                         ok = request_irq(pHCB->HCS_Intr, i91u_intr6, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);
443                         break;
444                 case 7:
445                         ok = request_irq(pHCB->HCS_Intr, i91u_intr7, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);
446                         break;
447                 default:
448                         i91u_panic("i91u: Too many host adapters\n");
449                         break;
450                 }
451                 if (ok < 0) {
452                         if (ok == -EINVAL) {
453                                 printk("i91u: bad IRQ %d.\n", pHCB->HCS_Intr);
454                                 printk("         Contact author.\n");
455                         } else if (ok == -EBUSY)
456                                 printk("i91u: IRQ %d already in use. Configure another.\n",
457                                        pHCB->HCS_Intr);
458                         else {
459                                 printk("\ni91u: Unexpected error code on requesting IRQ %d.\n",
460                                        pHCB->HCS_Intr);
461                                 printk("         Contact author.\n");
462                         }
463                         i91u_panic("i91u: driver needs an IRQ.\n");
464                 }
465         }
466
467         tpnt->this_id = -1;
468         tpnt->can_queue = 1;
469
470         return 1;
471 }
472
473 static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, Scsi_Cmnd * SCpnt)
474 {                               /* Create corresponding SCB     */
475         struct scatterlist *pSrbSG;
476         SG *pSG;                /* Pointer to SG list           */
477         int i;
478         long TotalLen;
479
480         pSCB->SCB_Post = i91uSCBPost;   /* i91u's callback routine      */
481         pSCB->SCB_Srb = SCpnt;
482         pSCB->SCB_Opcode = ExecSCSI;
483         pSCB->SCB_Flags = SCF_POST;     /* After SCSI done, call post routine */
484         pSCB->SCB_Target = SCpnt->device->id;
485         pSCB->SCB_Lun = SCpnt->device->lun;
486         pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW;
487         pSCB->SCB_Flags |= SCF_SENSE;   /* Turn on auto request sense   */
488
489         pSCB->SCB_SensePtr = (U32) VIRT_TO_BUS(SCpnt->sense_buffer);
490
491         pSCB->SCB_SenseLen = SENSE_SIZE;
492
493         pSCB->SCB_CDBLen = SCpnt->cmd_len;
494         pSCB->SCB_HaStat = 0;
495         pSCB->SCB_TaStat = 0;
496         memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, SCpnt->cmd_len);
497
498         if (SCpnt->device->tagged_supported) {  /* Tag Support                  */
499                 pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG;    /* Do simple tag only   */
500         } else {
501                 pSCB->SCB_TagMsg = 0;   /* No tag support               */
502         }
503
504         if (SCpnt->use_sg) {
505                 pSrbSG = (struct scatterlist *) SCpnt->request_buffer;
506                 if (SCpnt->use_sg == 1) {       /* If only one entry in the list *//*      treat it as regular I/O */
507                         pSCB->SCB_BufPtr = (U32) VIRT_TO_BUS(pSrbSG->address);
508                         TotalLen = pSrbSG->length;
509                         pSCB->SCB_SGLen = 0;
510                 } else {        /* Assign SG physical address   */
511                         pSCB->SCB_BufPtr = pSCB->SCB_SGPAddr;
512                         pSCB->SCB_Flags |= SCF_SG;      /* Turn on SG list flag       */
513                         for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0];   /* 1.01g */
514                              i < SCpnt->use_sg;
515                              i++, pSG++, pSrbSG++) {
516                                 pSG->SG_Ptr = (U32) VIRT_TO_BUS(pSrbSG->address);
517                                 TotalLen += pSG->SG_Len = pSrbSG->length;
518                         }
519                         pSCB->SCB_SGLen = i;
520                 }
521                 pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ?
522                     TotalLen : SCpnt->request_bufflen;
523         } else {                /* Non SG                       */
524                 pSCB->SCB_BufPtr = (U32) VIRT_TO_BUS(SCpnt->request_buffer);
525                 pSCB->SCB_BufLen = SCpnt->request_bufflen;
526                 pSCB->SCB_SGLen = 0;
527         }
528
529         return;
530 }
531
532 /* 
533  *  Queue a command and setup interrupts for a free bus.
534  */
535 int i91u_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
536 {
537         register SCB *pSCB;
538         HCS *pHCB;              /* Point to Host adapter control block */
539
540         if (SCpnt->device->lun > 16) {  /* 07/22/98 */
541
542                 SCpnt->result = (DID_TIME_OUT << 16);
543                 done(SCpnt);    /* Notify system DONE           */
544                 return (0);
545         }
546         pHCB = (HCS *) SCpnt->device->host->base;
547
548         SCpnt->scsi_done = done;
549         /* Get free SCSI control block  */
550         if ((pSCB = tul_alloc_scb(pHCB)) == NULL) {
551                 i91uAppendSRBToQueue(pHCB, SCpnt);      /* Buffer this request  */
552                 return (0);
553         }
554         i91uBuildSCB(pHCB, pSCB, SCpnt);
555         tul_exec_scb(pHCB, pSCB);       /* Start execute SCB            */
556         return (0);
557 }
558
559 /*
560  *  Abort a queued command
561  *  (commands that are on the bus can't be aborted easily)
562  */
563 int i91u_abort(Scsi_Cmnd * SCpnt)
564 {
565         HCS *pHCB;
566
567         pHCB = (HCS *) SCpnt->device->host->base;
568         return tul_abort_srb(pHCB, SCpnt);
569 }
570
571 /*
572  *  Reset registers, reset a hanging bus and
573  *  kill active and disconnected commands for target w/o soft reset
574  */
575 int i91u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
576 {                               /* I need Host Control Block Information */
577         HCS *pHCB;
578
579         pHCB = (HCS *) SCpnt->device->host->base;
580
581         if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))
582                 return tul_reset_scsi_bus(pHCB);
583         else
584                 return tul_device_reset(pHCB, (ULONG) SCpnt, SCpnt->device->id, reset_flags);
585 }
586
587 /*
588  * Return the "logical geometry"
589  */
590 int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev,
591                 sector_t capacity, int *info_array)
592 {
593         HCS *pHcb;              /* Point to Host adapter control block */
594         TCS *pTcb;
595
596         pHcb = (HCS *) sdev->host->base;
597         pTcb = &pHcb->HCS_Tcs[sdev->id];
598
599         if (pTcb->TCS_DrvHead) {
600                 info_array[0] = pTcb->TCS_DrvHead;
601                 info_array[1] = pTcb->TCS_DrvSector;
602                 info_array[2] = (unsigned long)capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector;
603         } else {
604                 if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) {
605                         info_array[0] = 255;
606                         info_array[1] = 63;
607                         info_array[2] = (unsigned long)capacity / 255 / 63;
608                 } else {
609                         info_array[0] = 64;
610                         info_array[1] = 32;
611                         info_array[2] = (unsigned long)capacity >> 11;
612                 }
613         }
614
615 #if defined(DEBUG_BIOSPARAM)
616         if (i91u_debug & debug_biosparam) {
617                 printk("bios geometry: head=%d, sec=%d, cyl=%d\n",
618                        info_array[0], info_array[1], info_array[2]);
619                 printk("WARNING: check, if the bios geometry is correct.\n");
620         }
621 #endif
622
623         return 0;
624 }
625
626 /*****************************************************************************
627  Function name  : i91uSCBPost
628  Description    : This is callback routine be called when tulip finish one
629                         SCSI command.
630  Input          : pHCB  -       Pointer to host adapter control block.
631                   pSCB  -       Pointer to SCSI control block.
632  Output         : None.
633  Return         : None.
634 *****************************************************************************/
635 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb)
636 {
637         Scsi_Cmnd *pSRB;        /* Pointer to SCSI request block */
638         HCS *pHCB;
639         SCB *pSCB;
640
641         pHCB = (HCS *) pHcb;
642         pSCB = (SCB *) pScb;
643         if ((pSRB = pSCB->SCB_Srb) == 0) {
644                 printk("i91uSCBPost: SRB pointer is empty\n");
645
646                 tul_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
647                 return;
648         }
649         switch (pSCB->SCB_HaStat) {
650         case 0x0:
651         case 0xa:               /* Linked command complete without error and linked normally */
652         case 0xb:               /* Linked command complete without error interrupt generated */
653                 pSCB->SCB_HaStat = 0;
654                 break;
655
656         case 0x11:              /* Selection time out-The initiator selection or target
657                                    reselection was not complete within the SCSI Time out period */
658                 pSCB->SCB_HaStat = DID_TIME_OUT;
659                 break;
660
661         case 0x14:              /* Target bus phase sequence failure-An invalid bus phase or bus
662                                    phase sequence was requested by the target. The host adapter
663                                    will generate a SCSI Reset Condition, notifying the host with
664                                    a SCRD interrupt */
665                 pSCB->SCB_HaStat = DID_RESET;
666                 break;
667
668         case 0x1a:              /* SCB Aborted. 07/21/98 */
669                 pSCB->SCB_HaStat = DID_ABORT;
670                 break;
671
672         case 0x12:              /* Data overrun/underrun-The target attempted to transfer more data
673                                    than was allocated by the Data Length field or the sum of the
674                                    Scatter / Gather Data Length fields. */
675         case 0x13:              /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
676         case 0x16:              /* Invalid SCB Operation Code. */
677
678         default:
679                 printk("ini9100u: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat);
680                 pSCB->SCB_HaStat = DID_ERROR;   /* Couldn't find any better */
681                 break;
682         }
683
684         pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);
685
686         if (pSRB == NULL) {
687                 printk("pSRB is NULL\n");
688         }
689         pSRB->scsi_done(pSRB);  /* Notify system DONE           */
690         if ((pSRB = i91uPopSRBFromQueue(pHCB)) != NULL)
691                 /* Find the next pending SRB    */
692         {                       /* Assume resend will success   */
693                 /* Reuse old SCB                */
694                 i91uBuildSCB(pHCB, pSCB, pSRB);         /* Create corresponding SCB     */
695
696                 tul_exec_scb(pHCB, pSCB);       /* Start execute SCB            */
697         } else {                /* No Pending SRB               */
698                 tul_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
699         }
700         return;
701 }
702
703 /*
704  * Interrupts handler (main routine of the driver)
705  */
706 static irqreturn_t i91u_intr0(int irqno, void *dev_id, struct pt_regs *regs)
707 {
708         unsigned long flags;
709         struct Scsi_Host *dev = dev_id;
710         
711         if (tul_hcs[0].HCS_Intr != irqno)
712                 return IRQ_NONE;
713
714         spin_lock_irqsave(dev->host_lock, flags);
715
716         tul_isr(&tul_hcs[0]);
717
718         spin_unlock_irqrestore(dev->host_lock, flags);
719         return IRQ_HANDLED;
720 }
721
722 static irqreturn_t i91u_intr1(int irqno, void *dev_id, struct pt_regs *regs)
723 {
724         unsigned long flags;
725         struct Scsi_Host *dev = dev_id;
726         
727         if (tul_hcs[1].HCS_Intr != irqno)
728                 return IRQ_NONE;
729
730         spin_lock_irqsave(dev->host_lock, flags);
731
732         tul_isr(&tul_hcs[1]);
733
734         spin_unlock_irqrestore(dev->host_lock, flags);
735         return IRQ_HANDLED;
736 }
737
738 static irqreturn_t i91u_intr2(int irqno, void *dev_id, struct pt_regs *regs)
739 {
740         unsigned long flags;
741         struct Scsi_Host *dev = dev_id;
742         
743         if (tul_hcs[2].HCS_Intr != irqno)
744                 return IRQ_NONE;
745
746         spin_lock_irqsave(dev->host_lock, flags);
747
748         tul_isr(&tul_hcs[2]);
749
750         spin_unlock_irqrestore(dev->host_lock, flags);
751         return IRQ_HANDLED;
752 }
753
754 static irqreturn_t i91u_intr3(int irqno, void *dev_id, struct pt_regs *regs)
755 {
756         unsigned long flags;
757         struct Scsi_Host *dev = dev_id;
758         
759         if (tul_hcs[3].HCS_Intr != irqno)
760                 return IRQ_NONE;
761
762         spin_lock_irqsave(dev->host_lock, flags);
763
764         tul_isr(&tul_hcs[3]);
765
766         spin_unlock_irqrestore(dev->host_lock, flags);
767         return IRQ_HANDLED;
768 }
769
770 static irqreturn_t i91u_intr4(int irqno, void *dev_id, struct pt_regs *regs)
771 {
772         unsigned long flags;
773         struct Scsi_Host *dev = dev_id;
774         
775         if (tul_hcs[4].HCS_Intr != irqno)
776                 return IRQ_NONE;
777
778         spin_lock_irqsave(dev->host_lock, flags);
779
780         tul_isr(&tul_hcs[4]);
781
782         spin_unlock_irqrestore(dev->host_lock, flags);
783         return IRQ_HANDLED;
784 }
785
786 static irqreturn_t i91u_intr5(int irqno, void *dev_id, struct pt_regs *regs)
787 {
788         unsigned long flags;
789         struct Scsi_Host *dev = dev_id;
790         
791         if (tul_hcs[5].HCS_Intr != irqno)
792                 return IRQ_NONE;
793
794         spin_lock_irqsave(dev->host_lock, flags);
795
796         tul_isr(&tul_hcs[5]);
797
798         spin_unlock_irqrestore(dev->host_lock, flags);
799         return IRQ_HANDLED;
800 }
801         
802 static irqreturn_t i91u_intr6(int irqno, void *dev_id, struct pt_regs *regs)
803 {
804         unsigned long flags;
805         struct Scsi_Host *dev = dev_id;
806         
807         if (tul_hcs[6].HCS_Intr != irqno)
808                 return IRQ_NONE;
809
810         spin_lock_irqsave(dev->host_lock, flags);
811
812         tul_isr(&tul_hcs[6]);
813
814         spin_unlock_irqrestore(dev->host_lock, flags);
815         return IRQ_HANDLED;
816 }
817
818 static irqreturn_t i91u_intr7(int irqno, void *dev_id, struct pt_regs *regs)
819 {
820         unsigned long flags;
821         struct Scsi_Host *dev = dev_id;
822         
823         if (tul_hcs[7].HCS_Intr != irqno)
824                 return IRQ_NONE;
825
826         spin_lock_irqsave(dev->host_lock, flags);
827
828         tul_isr(&tul_hcs[7]);
829
830         spin_unlock_irqrestore(dev->host_lock, flags);
831         return IRQ_HANDLED;
832 }
833
834 /* 
835  * Dump the current driver status and panic...
836  */
837 static void i91u_panic(char *msg)
838 {
839         printk("\ni91u_panic: %s\n", msg);
840         panic("i91u panic");
841 }
842
843 /*
844  * Release ressources
845  */
846 int i91u_release(struct Scsi_Host *hreg)
847 {
848         free_irq(hreg->irq, hreg);
849         release_region(hreg->io_port, 256);
850         return 0;
851 }
852 MODULE_LICENSE("Dual BSD/GPL");