1 /**************************************************************************
2 * Initio A100 device driver for Linux.
4 * Copyright (c) 1994-1998 Initio Corporation
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 * --------------------------------------------------------------------------
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
26 * 1. Redistributions of source code must retain the above copyright
27 * notice, this list of conditions, and the following disclaimer,
28 * without modification, immediately at the beginning of the file.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
32 * 3. The name of the author may not be used to endorse or promote products
33 * derived from this software without specific prior written permission.
35 * Where this Software is combined with software released under the terms of
36 * the GNU General Public License ("GPL") and the terms of the GPL would require the
37 * combined work to also be released under the terms of the GPL, the terms
38 * and conditions of this License will apply in addition to those of the
39 * GPL with the exception of any terms or conditions of this License that
40 * conflict with, or are expressly prohibited by, the GPL.
42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
43 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
46 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 *************************************************************************
58 * This is the Linux low-level SCSI driver for Initio INIA100 SCSI host
61 * 07/02/98 hl - v.91n Initial drivers.
62 * 09/14/98 hl - v1.01 Support new Kernel.
63 * 09/22/98 hl - v1.01a Support reset.
64 * 09/24/98 hl - v1.01b Fixed reset.
65 * 10/05/98 hl - v1.02 split the source code and release.
66 * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up
67 * 01/31/99 bv - v1.02b Use mdelay instead of waitForPause
68 * 08/08/99 bv - v1.02c Use waitForPause again.
69 **************************************************************************/
71 #include <linux/version.h>
72 #include <linux/sched.h>
76 #define JIFFIES_TO_MS(t) ((t) * 1000 / HZ)
77 #define MS_TO_JIFFIES(j) ((j * HZ) / 1000)
79 /* ---- INTERNAL FUNCTIONS ---- */
80 static UCHAR waitChipReady(ORC_HCS * hcsp);
81 static UCHAR waitFWReady(ORC_HCS * hcsp);
82 static UCHAR waitFWReady(ORC_HCS * hcsp);
83 static UCHAR waitSCSIRSTdone(ORC_HCS * hcsp);
84 static UCHAR waitHDOoff(ORC_HCS * hcsp);
85 static UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData);
86 static unsigned short get_FW_version(ORC_HCS * hcsp);
87 static UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value);
88 static UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn);
89 static int se2_rd_all(ORC_HCS * hcsp);
90 static void se2_update_all(ORC_HCS * hcsp); /* setup default pattern */
91 static void read_eeprom(ORC_HCS * hcsp);
92 static UCHAR load_FW(ORC_HCS * hcsp);
93 static void setup_SCBs(ORC_HCS * hcsp);
94 static void initAFlag(ORC_HCS * hcsp);
95 ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp);
97 /* ---- EXTERNAL FUNCTIONS ---- */
98 extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb);
100 /* ---- INTERNAL VARIABLES ---- */
101 ORC_HCS orc_hcs[MAX_SUPPORTED_ADAPTERS];
102 static INIA100_ADPT_STRUCT inia100_adpt[MAX_SUPPORTED_ADAPTERS];
103 /* set by inia100_setup according to the command line */
106 NVRAM nvram, *nvramp = &nvram;
107 static UCHAR dftNvRam[64] =
109 /*----------header -------------*/
110 0x01, /* 0x00: Sub System Vendor ID 0 */
111 0x11, /* 0x01: Sub System Vendor ID 1 */
112 0x60, /* 0x02: Sub System ID 0 */
113 0x10, /* 0x03: Sub System ID 1 */
114 0x00, /* 0x04: SubClass */
115 0x01, /* 0x05: Vendor ID 0 */
116 0x11, /* 0x06: Vendor ID 1 */
117 0x60, /* 0x07: Device ID 0 */
118 0x10, /* 0x08: Device ID 1 */
119 0x00, /* 0x09: Reserved */
120 0x00, /* 0x0A: Reserved */
121 0x01, /* 0x0B: Revision of Data Structure */
122 /* -- Host Adapter Structure --- */
123 0x01, /* 0x0C: Number Of SCSI Channel */
124 0x01, /* 0x0D: BIOS Configuration 1 */
125 0x00, /* 0x0E: BIOS Configuration 2 */
126 0x00, /* 0x0F: BIOS Configuration 3 */
127 /* --- SCSI Channel 0 Configuration --- */
128 0x07, /* 0x10: H/A ID */
129 0x83, /* 0x11: Channel Configuration */
130 0x20, /* 0x12: MAX TAG per target */
131 0x0A, /* 0x13: SCSI Reset Recovering time */
132 0x00, /* 0x14: Channel Configuration4 */
133 0x00, /* 0x15: Channel Configuration5 */
134 /* SCSI Channel 0 Target Configuration */
136 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
137 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
138 /* --- SCSI Channel 1 Configuration --- */
139 0x07, /* 0x26: H/A ID */
140 0x83, /* 0x27: Channel Configuration */
141 0x20, /* 0x28: MAX TAG per target */
142 0x0A, /* 0x29: SCSI Reset Recovering time */
143 0x00, /* 0x2A: Channel Configuration4 */
144 0x00, /* 0x2B: Channel Configuration5 */
145 /* SCSI Channel 1 Target Configuration */
147 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
148 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
149 0x00, /* 0x3C: Reserved */
150 0x00, /* 0x3D: Reserved */
151 0x00, /* 0x3E: Reserved */
152 0x00 /* 0x3F: Checksum */
156 /***************************************************************************/
157 static void waitForPause(unsigned amount)
159 ULONG the_time = jiffies + MS_TO_JIFFIES(amount);
160 while (time_before_eq(jiffies, the_time))
164 /***************************************************************************/
165 UCHAR waitChipReady(ORC_HCS * hcsp)
169 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
170 if (ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HOSTSTOP) /* Wait HOSTSTOP set */
172 waitForPause(100); /* wait 100ms before try again */
177 /***************************************************************************/
178 UCHAR waitFWReady(ORC_HCS * hcsp)
182 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
183 if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) /* Wait READY set */
185 waitForPause(100); /* wait 100ms before try again */
190 /***************************************************************************/
191 UCHAR waitSCSIRSTdone(ORC_HCS * hcsp)
195 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
196 if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & SCSIRST)) /* Wait SCSIRST done */
198 waitForPause(100); /* wait 100ms before try again */
203 /***************************************************************************/
204 UCHAR waitHDOoff(ORC_HCS * hcsp)
208 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
209 if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HDO)) /* Wait HDO off */
211 waitForPause(100); /* wait 100ms before try again */
216 /***************************************************************************/
217 UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData)
221 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
222 if ((*pData = ORC_RD(hcsp->HCS_Base, ORC_HSTUS)) & HDI)
223 return (TRUE); /* Wait HDI set */
224 waitForPause(100); /* wait 100ms before try again */
229 /***************************************************************************/
230 unsigned short get_FW_version(ORC_HCS * hcsp)
234 unsigned short sVersion;
235 unsigned char cVersion[2];
238 ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_VERSION);
239 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
240 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
243 if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */
245 Version.cVersion[0] = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
246 ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */
248 if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */
250 Version.cVersion[1] = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
251 ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */
253 return (Version.sVersion);
256 /***************************************************************************/
257 UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value)
259 ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_SET_NVM); /* Write command */
260 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
261 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
264 ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */
265 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
266 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
269 ORC_WR(hcsp->HCS_Base + ORC_HDATA, value); /* Write value */
270 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
271 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
277 /***************************************************************************/
278 UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn)
282 ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_GET_NVM); /* Write command */
283 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
284 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
287 ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */
288 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
289 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
292 if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */
294 *pDataIn = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
295 ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */
300 /***************************************************************************/
301 void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
303 scbp->SCB_Status = SCB_POST;
304 ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx);
309 /***********************************************************************
310 Read SCSI H/A configuration parameters from serial EEPROM
311 ************************************************************************/
312 int se2_rd_all(ORC_HCS * hcsp)
315 UCHAR *np, chksum = 0;
317 np = (UCHAR *) nvramp;
318 for (i = 0; i < 64; i++, np++) { /* <01> */
319 if (get_NVRAM(hcsp, (unsigned char) i, np) == FALSE)
321 // *np++ = get_NVRAM(hcsp, (unsigned char ) i);
324 /*------ Is ckecksum ok ? ------*/
325 np = (UCHAR *) nvramp;
326 for (i = 0; i < 63; i++)
329 if (nvramp->CheckSum != (UCHAR) chksum)
334 /************************************************************************
335 Update SCSI H/A configuration parameters from serial EEPROM
336 *************************************************************************/
337 void se2_update_all(ORC_HCS * hcsp)
338 { /* setup default pattern */
340 UCHAR *np, *np1, chksum = 0;
342 /* Calculate checksum first */
343 np = (UCHAR *) dftNvRam;
344 for (i = 0; i < 63; i++)
348 np = (UCHAR *) dftNvRam;
349 np1 = (UCHAR *) nvramp;
350 for (i = 0; i < 64; i++, np++, np1++) {
352 set_NVRAM(hcsp, (unsigned char) i, *np);
358 /*************************************************************************
359 Function name : read_eeprom
360 **************************************************************************/
361 void read_eeprom(ORC_HCS * hcsp)
363 if (se2_rd_all(hcsp) != 1) {
364 se2_update_all(hcsp); /* setup default pattern */
365 se2_rd_all(hcsp); /* load again */
370 /***************************************************************************/
371 UCHAR load_FW(ORC_HCS * hcsp)
379 bData = ORC_RD(hcsp->HCS_Base, ORC_GCFG);
380 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData | EEPRG); /* Enable EEPROM programming */
381 ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, 0x00);
382 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x00);
383 if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0x55) {
384 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */
387 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x01);
388 if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0xAA) {
389 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */
392 ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Enable SRAM programming */
393 pData = (UCHAR *) & dData;
394 dData = 0; /* Initial FW address to 0 */
395 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x10);
396 *pData = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
397 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x11);
398 *(pData + 1) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
399 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x12);
400 *(pData + 2) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
401 ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, *(pData + 2));
402 ORC_WRLONG(hcsp->HCS_Base + ORC_FWBASEADR, dData); /* Write FW address */
404 wBIOSAddress = (USHORT) dData; /* FW code locate at BIOS address + ? */
405 for (i = 0, pData = (UCHAR *) & dData; /* Download the code */
406 i < 0x1000; /* Firmware code size = 4K */
407 i++, wBIOSAddress++) {
408 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress);
409 *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
411 ORC_WRLONG(hcsp->HCS_Base + ORC_RISCRAM, dData); /* Write every 4 bytes */
412 pData = (UCHAR *) & dData;
416 ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Reset program count 0 */
417 wBIOSAddress -= 0x1000; /* Reset the BIOS adddress */
418 for (i = 0, pData = (UCHAR *) & dData; /* Check the code */
419 i < 0x1000; /* Firmware code size = 4K */
420 i++, wBIOSAddress++) {
421 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress);
422 *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
424 if (ORC_RDLONG(hcsp->HCS_Base, ORC_RISCRAM) != dData) {
425 ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */
426 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /*Disable EEPROM programming */
429 pData = (UCHAR *) & dData;
432 ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */
433 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */
437 /***************************************************************************/
438 void setup_SCBs(ORC_HCS * hcsp)
449 tPhysEscb = (PVOID) NULL;
450 pPhysEscb = (PVOID) NULL;
451 /* Setup SCB HCS_Base and SCB Size registers */
452 ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, orc_num_scb); /* Total number of SCBs */
453 /* SCB HCS_Base address 0 */
454 ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray);
455 /* SCB HCS_Base address 1 */
456 ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE1, hcsp->HCS_physScbArray);
458 /* setup scatter list address with one buffer */
459 pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
460 pVirEscb = (ESCB *) hcsp->HCS_virEscbArray;
462 for (i = 0; i < orc_num_scb; i++) {
463 pPhysEscb = (PVOID) (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i));
464 pVirScb->SCB_SGPAddr = (U32) pPhysEscb;
465 pVirScb->SCB_SensePAddr = (U32) pPhysEscb;
466 pVirScb->SCB_EScb = pVirEscb;
467 pVirScb->SCB_ScbIdx = i;
475 /***************************************************************************/
476 static void initAFlag(ORC_HCS * hcsp)
480 for (i = 0; i < MAX_CHANNELS; i++) {
481 for (j = 0; j < 8; j++) {
482 hcsp->BitAllocFlag[i][j] = 0xffffffff;
487 /***************************************************************************/
488 int init_orchid(ORC_HCS * hcsp)
495 ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFF); /* Disable all interrupt */
496 if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) { /* Orchid is ready */
497 revision = get_FW_version(hcsp);
498 if (revision == 0xFFFF) {
499 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */
500 if (waitChipReady(hcsp) == FALSE)
502 load_FW(hcsp); /* Download FW */
503 setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */
504 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, 0); /* clear HOSTSTOP */
505 if (waitFWReady(hcsp) == FALSE)
507 /* Wait for firmware ready */
509 setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */
511 } else { /* Orchid is not Ready */
512 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */
513 if (waitChipReady(hcsp) == FALSE)
515 load_FW(hcsp); /* Download FW */
516 setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */
517 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); /* Do Hardware Reset & */
520 if (waitFWReady(hcsp) == FALSE) /* Wait for firmware ready */
524 /*------------- get serial EEProm settting -------*/
528 if (nvramp->Revision != 1)
531 hcsp->HCS_SCSI_ID = nvramp->SCSI0Id;
532 hcsp->HCS_BIOS = nvramp->BIOSConfig1;
533 hcsp->HCS_MaxTar = MAX_TARGETS;
534 readBytep = (UCHAR *) & (nvramp->Target00Config);
535 for (i = 0; i < 16; readBytep++, i++) {
536 hcsp->TargetFlag[i] = *readBytep;
537 hcsp->MaximumTags[i] = orc_num_scb;
540 if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */
541 hcsp->HCS_Flags |= HCF_SCSI_RESET;
543 ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFB); /* enable RP FIFO interrupt */
547 /*****************************************************************************
548 Function name : orc_reset_scsi_bus
549 Description : Reset registers, reset a hanging bus and
550 kill active and disconnected commands for target w/o soft reset
551 Input : pHCB - Pointer to host adapter structure
553 Return : pSRB - Pointer to SCSI request block.
554 *****************************************************************************/
555 int orc_reset_scsi_bus(ORC_HCS * pHCB)
556 { /* I need Host Control Block Information */
559 spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags);
563 ORC_WR(pHCB->HCS_Base + ORC_HCTRL, SCSIRST);
564 if (waitSCSIRSTdone(pHCB) == FALSE) {
565 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
566 return (SCSI_RESET_ERROR);
568 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
569 return (SCSI_RESET_SUCCESS);
573 /*****************************************************************************
574 Function name : orc_device_reset
575 Description : Reset registers, reset a hanging bus and
576 kill active and disconnected commands for target w/o soft reset
577 Input : pHCB - Pointer to host adapter structure
579 Return : pSRB - Pointer to SCSI request block.
580 *****************************************************************************/
581 int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned int ResetFlags)
582 { /* I need Host Control Block Information */
589 spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags);
590 pScb = (ORC_SCB *) NULL;
591 pVirEscb = (ESCB *) NULL;
593 /* setup scatter list address with one buffer */
594 pVirScb = (ORC_SCB *) pHCB->HCS_virScbArray;
598 for (i = 0; i < orc_num_scb; i++) {
599 pVirEscb = pVirScb->SCB_EScb;
600 if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt))
605 if (i == orc_num_scb) {
606 printk("Unable to Reset - No SCB Found\n");
607 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
608 return (SCSI_RESET_NOT_RUNNING);
610 if ((pScb = orc_alloc_scb(pHCB)) == NULL) {
611 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
612 return (SCSI_RESET_NOT_RUNNING);
614 pScb->SCB_Opcode = ORC_BUSDEVRST;
615 pScb->SCB_Target = target;
616 pScb->SCB_HaStat = 0;
617 pScb->SCB_TaStat = 0;
618 pScb->SCB_Status = 0x0;
619 pScb->SCB_Link = 0xFF;
620 pScb->SCB_Reserved0 = 0;
621 pScb->SCB_Reserved1 = 0;
622 pScb->SCB_XferLen = 0;
625 pVirEscb->SCB_Srb = 0;
626 if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
627 pVirEscb->SCB_Srb = (unsigned char *) SCpnt;
629 orc_exec_scb(pHCB, pScb); /* Start execute SCB */
630 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
631 return SCSI_RESET_PENDING;
635 /***************************************************************************/
636 ORC_SCB *__orc_alloc_scb(ORC_HCS * hcsp)
644 Ch = hcsp->HCS_Index;
645 for (i = 0; i < 8; i++) {
646 for (index = 0; index < 32; index++) {
647 if ((hcsp->BitAllocFlag[Ch][i] >> index) & 0x01) {
648 hcsp->BitAllocFlag[Ch][i] &= ~(1 << index);
652 idx = index + 32 * i;
653 pTmpScb = (PVOID) ((ULONG) hcsp->HCS_virScbArray + (idx * sizeof(ORC_SCB)));
659 ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp)
664 spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
665 pTmpScb = __orc_alloc_scb(hcsp);
666 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
671 /***************************************************************************/
672 void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
679 spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
680 Ch = hcsp->HCS_Index;
681 Index = scbp->SCB_ScbIdx;
684 hcsp->BitAllocFlag[Ch][i] |= (1 << Index);
685 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
689 /*****************************************************************************
690 Function name : Addinia100_into_Adapter_table
691 Description : This function will scan PCI bus to get all Orchid card
694 Return : SUCCESSFUL - Successful scan
695 ohterwise - No drives founded
696 *****************************************************************************/
697 int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
698 BYTE bBus, BYTE bDevice)
702 for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {
703 if (inia100_adpt[i].ADPT_BIOS < wBIOS)
705 if (inia100_adpt[i].ADPT_BIOS == wBIOS) {
706 if (inia100_adpt[i].ADPT_BASE == wBASE) {
707 if (inia100_adpt[i].ADPT_Bus != 0xFF)
709 } else if (inia100_adpt[i].ADPT_BASE < wBASE)
712 for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) {
713 inia100_adpt[j].ADPT_BASE = inia100_adpt[j - 1].ADPT_BASE;
714 inia100_adpt[j].ADPT_INTR = inia100_adpt[j - 1].ADPT_INTR;
715 inia100_adpt[j].ADPT_BIOS = inia100_adpt[j - 1].ADPT_BIOS;
716 inia100_adpt[j].ADPT_Bus = inia100_adpt[j - 1].ADPT_Bus;
717 inia100_adpt[j].ADPT_Device = inia100_adpt[j - 1].ADPT_Device;
719 inia100_adpt[i].ADPT_BASE = wBASE;
720 inia100_adpt[i].ADPT_INTR = bInterrupt;
721 inia100_adpt[i].ADPT_BIOS = wBIOS;
722 inia100_adpt[i].ADPT_Bus = bBus;
723 inia100_adpt[i].ADPT_Device = bDevice;
730 /*****************************************************************************
731 Function name : init_inia100Adapter_table
732 Description : This function will scan PCI bus to get all Orchid card
735 Return : SUCCESSFUL - Successful scan
736 ohterwise - No drives founded
737 *****************************************************************************/
738 void init_inia100Adapter_table(void)
742 for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { /* Initialize adapter structure */
743 inia100_adpt[i].ADPT_BIOS = 0xffff;
744 inia100_adpt[i].ADPT_BASE = 0xffff;
745 inia100_adpt[i].ADPT_INTR = 0xff;
746 inia100_adpt[i].ADPT_Bus = 0xff;
747 inia100_adpt[i].ADPT_Device = 0xff;
751 /*****************************************************************************
752 Function name : get_orcPCIConfig
754 Input : pHCB - Pointer to host adapter structure
756 Return : pSRB - Pointer to SCSI request block.
757 *****************************************************************************/
758 void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx)
760 pCurHcb->HCS_Base = inia100_adpt[ch_idx].ADPT_BASE; /* Supply base address */
761 pCurHcb->HCS_BIOS = inia100_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */
762 pCurHcb->HCS_Intr = inia100_adpt[ch_idx].ADPT_INTR; /* Supply interrupt line */
767 /*****************************************************************************
768 Function name : abort_SCB
769 Description : Abort a queued command.
770 (commands that are on the bus can't be aborted easily)
771 Input : pHCB - Pointer to host adapter structure
773 Return : pSRB - Pointer to SCSI request block.
774 *****************************************************************************/
775 int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb)
777 unsigned char bData, bStatus;
779 ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_ABORT_SCB); /* Write command */
780 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
781 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
784 ORC_WR(hcsp->HCS_Base + ORC_HDATA, pScb->SCB_ScbIdx); /* Write address */
785 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
786 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
789 if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */
791 bStatus = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
792 ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */
794 if (bStatus == 1) /* 0 - Successfully */
795 return (FALSE); /* 1 - Fail */
799 /*****************************************************************************
800 Function name : inia100_abort
801 Description : Abort a queued command.
802 (commands that are on the bus can't be aborted easily)
803 Input : pHCB - Pointer to host adapter structure
805 Return : pSRB - Pointer to SCSI request block.
806 *****************************************************************************/
807 int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt)
814 spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
816 pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
818 for (i = 0; i < orc_num_scb; i++, pVirScb++) {
819 pVirEscb = pVirScb->SCB_EScb;
820 if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) {
821 if (pVirScb->SCB_TagMsg == 0) {
822 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
823 return (SCSI_ABORT_BUSY);
825 if (abort_SCB(hcsp, pVirScb)) {
826 pVirEscb->SCB_Srb = NULL;
827 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
828 return (SCSI_ABORT_SUCCESS);
830 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
831 return (SCSI_ABORT_NOT_RUNNING);
836 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
837 return (SCSI_ABORT_NOT_RUNNING);
840 /***********************************************************************
842 This is the interrupt service routine for the Orchid SCSI adapter.
843 It reads the interrupt register to determine if the adapter is indeed
844 the source of the interrupt and clears the interrupt at the device.
846 HwDeviceExtension - HBA miniport driver's adapter data storage
848 ***********************************************************************/
856 if (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT) == 0) {
861 bScbIdx = ORC_RD(hcsp->HCS_Base, ORC_RQUEUE);
863 pScb = (ORC_SCB *) ((ULONG) hcsp->HCS_virScbArray + (ULONG) (sizeof(ORC_SCB) * bScbIdx));
864 pScb->SCB_Status = 0x0;
866 inia100SCBPost((BYTE *) hcsp, (BYTE *) pScb);
867 } while (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT));
870 } /* End of I1060Interrupt() */