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 * 06/25/02 Doug Ledford <dledford@redhat.com> - v1.02d
70 * - Remove limit on number of controllers
71 * - Port to DMA mapping API
72 * - Clean up interrupt handler registration
74 * - Fix allocation of scsi host structs and private data
75 **************************************************************************/
77 #include <linux/module.h>
79 #include <linux/pci.h>
80 #include <linux/delay.h>
82 #include <linux/blkdev.h>
84 #include <scsi/scsi_host.h>
87 #define JIFFIES_TO_MS(t) ((t) * 1000 / HZ)
88 #define MS_TO_JIFFIES(j) ((j * HZ) / 1000)
90 /* ---- INTERNAL FUNCTIONS ---- */
91 static UCHAR waitChipReady(ORC_HCS * hcsp);
92 static UCHAR waitFWReady(ORC_HCS * hcsp);
93 static UCHAR waitFWReady(ORC_HCS * hcsp);
94 static UCHAR waitSCSIRSTdone(ORC_HCS * hcsp);
95 static UCHAR waitHDOoff(ORC_HCS * hcsp);
96 static UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData);
97 static unsigned short get_FW_version(ORC_HCS * hcsp);
98 static UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value);
99 static UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn);
100 static int se2_rd_all(ORC_HCS * hcsp);
101 static void se2_update_all(ORC_HCS * hcsp); /* setup default pattern */
102 static void read_eeprom(ORC_HCS * hcsp);
103 static UCHAR load_FW(ORC_HCS * hcsp);
104 static void setup_SCBs(ORC_HCS * hcsp);
105 static void initAFlag(ORC_HCS * hcsp);
106 ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp);
108 /* ---- EXTERNAL FUNCTIONS ---- */
109 extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb);
111 NVRAM nvram, *nvramp = &nvram;
112 static UCHAR dftNvRam[64] =
114 /*----------header -------------*/
115 0x01, /* 0x00: Sub System Vendor ID 0 */
116 0x11, /* 0x01: Sub System Vendor ID 1 */
117 0x60, /* 0x02: Sub System ID 0 */
118 0x10, /* 0x03: Sub System ID 1 */
119 0x00, /* 0x04: SubClass */
120 0x01, /* 0x05: Vendor ID 0 */
121 0x11, /* 0x06: Vendor ID 1 */
122 0x60, /* 0x07: Device ID 0 */
123 0x10, /* 0x08: Device ID 1 */
124 0x00, /* 0x09: Reserved */
125 0x00, /* 0x0A: Reserved */
126 0x01, /* 0x0B: Revision of Data Structure */
127 /* -- Host Adapter Structure --- */
128 0x01, /* 0x0C: Number Of SCSI Channel */
129 0x01, /* 0x0D: BIOS Configuration 1 */
130 0x00, /* 0x0E: BIOS Configuration 2 */
131 0x00, /* 0x0F: BIOS Configuration 3 */
132 /* --- SCSI Channel 0 Configuration --- */
133 0x07, /* 0x10: H/A ID */
134 0x83, /* 0x11: Channel Configuration */
135 0x20, /* 0x12: MAX TAG per target */
136 0x0A, /* 0x13: SCSI Reset Recovering time */
137 0x00, /* 0x14: Channel Configuration4 */
138 0x00, /* 0x15: Channel Configuration5 */
139 /* SCSI Channel 0 Target Configuration */
141 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
142 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
143 /* --- SCSI Channel 1 Configuration --- */
144 0x07, /* 0x26: H/A ID */
145 0x83, /* 0x27: Channel Configuration */
146 0x20, /* 0x28: MAX TAG per target */
147 0x0A, /* 0x29: SCSI Reset Recovering time */
148 0x00, /* 0x2A: Channel Configuration4 */
149 0x00, /* 0x2B: Channel Configuration5 */
150 /* SCSI Channel 1 Target Configuration */
152 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
153 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8,
154 0x00, /* 0x3C: Reserved */
155 0x00, /* 0x3D: Reserved */
156 0x00, /* 0x3E: Reserved */
157 0x00 /* 0x3F: Checksum */
161 /***************************************************************************/
162 static void waitForPause(unsigned amount)
164 ULONG the_time = jiffies + MS_TO_JIFFIES(amount);
165 while (time_before_eq(jiffies, the_time))
169 /***************************************************************************/
170 UCHAR waitChipReady(ORC_HCS * hcsp)
174 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
175 if (ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HOSTSTOP) /* Wait HOSTSTOP set */
177 waitForPause(100); /* wait 100ms before try again */
182 /***************************************************************************/
183 UCHAR waitFWReady(ORC_HCS * hcsp)
187 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
188 if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) /* Wait READY set */
190 waitForPause(100); /* wait 100ms before try again */
195 /***************************************************************************/
196 UCHAR waitSCSIRSTdone(ORC_HCS * hcsp)
200 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
201 if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & SCSIRST)) /* Wait SCSIRST done */
203 waitForPause(100); /* wait 100ms before try again */
208 /***************************************************************************/
209 UCHAR waitHDOoff(ORC_HCS * hcsp)
213 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
214 if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HDO)) /* Wait HDO off */
216 waitForPause(100); /* wait 100ms before try again */
221 /***************************************************************************/
222 UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData)
226 for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */
227 if ((*pData = ORC_RD(hcsp->HCS_Base, ORC_HSTUS)) & HDI)
228 return (TRUE); /* Wait HDI set */
229 waitForPause(100); /* wait 100ms before try again */
234 /***************************************************************************/
235 unsigned short get_FW_version(ORC_HCS * hcsp)
239 unsigned short sVersion;
240 unsigned char cVersion[2];
243 ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_VERSION);
244 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
245 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
248 if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */
250 Version.cVersion[0] = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
251 ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */
253 if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */
255 Version.cVersion[1] = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
256 ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */
258 return (Version.sVersion);
261 /***************************************************************************/
262 UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value)
264 ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_SET_NVM); /* Write command */
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, address); /* Write address */
270 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
271 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
274 ORC_WR(hcsp->HCS_Base + ORC_HDATA, value); /* Write value */
275 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
276 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
282 /***************************************************************************/
283 UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn)
287 ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_GET_NVM); /* Write command */
288 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
289 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
292 ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */
293 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
294 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
297 if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */
299 *pDataIn = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
300 ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */
305 /***************************************************************************/
306 void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
308 scbp->SCB_Status = ORCSCB_POST;
309 ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx);
314 /***********************************************************************
315 Read SCSI H/A configuration parameters from serial EEPROM
316 ************************************************************************/
317 int se2_rd_all(ORC_HCS * hcsp)
320 UCHAR *np, chksum = 0;
322 np = (UCHAR *) nvramp;
323 for (i = 0; i < 64; i++, np++) { /* <01> */
324 if (get_NVRAM(hcsp, (unsigned char) i, np) == FALSE)
326 // *np++ = get_NVRAM(hcsp, (unsigned char ) i);
329 /*------ Is ckecksum ok ? ------*/
330 np = (UCHAR *) nvramp;
331 for (i = 0; i < 63; i++)
334 if (nvramp->CheckSum != (UCHAR) chksum)
339 /************************************************************************
340 Update SCSI H/A configuration parameters from serial EEPROM
341 *************************************************************************/
342 void se2_update_all(ORC_HCS * hcsp)
343 { /* setup default pattern */
345 UCHAR *np, *np1, chksum = 0;
347 /* Calculate checksum first */
348 np = (UCHAR *) dftNvRam;
349 for (i = 0; i < 63; i++)
353 np = (UCHAR *) dftNvRam;
354 np1 = (UCHAR *) nvramp;
355 for (i = 0; i < 64; i++, np++, np1++) {
357 set_NVRAM(hcsp, (unsigned char) i, *np);
363 /*************************************************************************
364 Function name : read_eeprom
365 **************************************************************************/
366 void read_eeprom(ORC_HCS * hcsp)
368 if (se2_rd_all(hcsp) != 1) {
369 se2_update_all(hcsp); /* setup default pattern */
370 se2_rd_all(hcsp); /* load again */
375 /***************************************************************************/
376 UCHAR load_FW(ORC_HCS * hcsp)
384 bData = ORC_RD(hcsp->HCS_Base, ORC_GCFG);
385 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData | EEPRG); /* Enable EEPROM programming */
386 ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, 0x00);
387 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x00);
388 if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0x55) {
389 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */
392 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x01);
393 if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0xAA) {
394 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */
397 ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Enable SRAM programming */
398 pData = (UCHAR *) & dData;
399 dData = 0; /* Initial FW address to 0 */
400 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x10);
401 *pData = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
402 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x11);
403 *(pData + 1) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
404 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x12);
405 *(pData + 2) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
406 ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, *(pData + 2));
407 ORC_WRLONG(hcsp->HCS_Base + ORC_FWBASEADR, dData); /* Write FW address */
409 wBIOSAddress = (USHORT) dData; /* FW code locate at BIOS address + ? */
410 for (i = 0, pData = (UCHAR *) & dData; /* Download the code */
411 i < 0x1000; /* Firmware code size = 4K */
412 i++, wBIOSAddress++) {
413 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress);
414 *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
416 ORC_WRLONG(hcsp->HCS_Base + ORC_RISCRAM, dData); /* Write every 4 bytes */
417 pData = (UCHAR *) & dData;
421 ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Reset program count 0 */
422 wBIOSAddress -= 0x1000; /* Reset the BIOS adddress */
423 for (i = 0, pData = (UCHAR *) & dData; /* Check the code */
424 i < 0x1000; /* Firmware code size = 4K */
425 i++, wBIOSAddress++) {
426 ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress);
427 *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */
429 if (ORC_RDLONG(hcsp->HCS_Base, ORC_RISCRAM) != dData) {
430 ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */
431 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /*Disable EEPROM programming */
434 pData = (UCHAR *) & dData;
437 ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */
438 ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */
442 /***************************************************************************/
443 void setup_SCBs(ORC_HCS * hcsp)
448 dma_addr_t pPhysEscb;
450 /* Setup SCB HCS_Base and SCB Size registers */
451 ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, ORC_MAXQUEUE); /* Total number of SCBs */
452 /* SCB HCS_Base address 0 */
453 ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray);
454 /* SCB HCS_Base address 1 */
455 ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE1, hcsp->HCS_physScbArray);
457 /* setup scatter list address with one buffer */
458 pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
459 pVirEscb = (ESCB *) hcsp->HCS_virEscbArray;
461 for (i = 0; i < ORC_MAXQUEUE; i++) {
462 pPhysEscb = (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i));
463 pVirScb->SCB_SGPAddr = (U32) pPhysEscb;
464 pVirScb->SCB_SensePAddr = (U32) pPhysEscb;
465 pVirScb->SCB_EScb = pVirEscb;
466 pVirScb->SCB_ScbIdx = i;
474 /***************************************************************************/
475 static void initAFlag(ORC_HCS * hcsp)
479 for (i = 0; i < MAX_CHANNELS; i++) {
480 for (j = 0; j < 8; j++) {
481 hcsp->BitAllocFlag[i][j] = 0xffffffff;
486 /***************************************************************************/
487 int init_orchid(ORC_HCS * hcsp)
494 ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFF); /* Disable all interrupt */
495 if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) { /* Orchid is ready */
496 revision = get_FW_version(hcsp);
497 if (revision == 0xFFFF) {
498 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */
499 if (waitChipReady(hcsp) == FALSE)
501 load_FW(hcsp); /* Download FW */
502 setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */
503 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, 0); /* clear HOSTSTOP */
504 if (waitFWReady(hcsp) == FALSE)
506 /* Wait for firmware ready */
508 setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */
510 } else { /* Orchid is not Ready */
511 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */
512 if (waitChipReady(hcsp) == FALSE)
514 load_FW(hcsp); /* Download FW */
515 setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */
516 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); /* Do Hardware Reset & */
519 if (waitFWReady(hcsp) == FALSE) /* Wait for firmware ready */
523 /*------------- get serial EEProm settting -------*/
527 if (nvramp->Revision != 1)
530 hcsp->HCS_SCSI_ID = nvramp->SCSI0Id;
531 hcsp->HCS_BIOS = nvramp->BIOSConfig1;
532 hcsp->HCS_MaxTar = MAX_TARGETS;
533 readBytep = (UCHAR *) & (nvramp->Target00Config);
534 for (i = 0; i < 16; readBytep++, i++) {
535 hcsp->TargetFlag[i] = *readBytep;
536 hcsp->MaximumTags[i] = ORC_MAXTAGS;
539 if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */
540 hcsp->HCS_Flags |= HCF_SCSI_RESET;
542 ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFB); /* enable RP FIFO interrupt */
546 /*****************************************************************************
547 Function name : orc_reset_scsi_bus
548 Description : Reset registers, reset a hanging bus and
549 kill active and disconnected commands for target w/o soft reset
550 Input : pHCB - Pointer to host adapter structure
552 Return : pSRB - Pointer to SCSI request block.
553 *****************************************************************************/
554 int orc_reset_scsi_bus(ORC_HCS * pHCB)
555 { /* I need Host Control Block Information */
558 spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags);
562 ORC_WR(pHCB->HCS_Base + ORC_HCTRL, SCSIRST);
563 if (waitSCSIRSTdone(pHCB) == FALSE) {
564 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
567 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
572 /*****************************************************************************
573 Function name : orc_device_reset
574 Description : Reset registers, reset a hanging bus and
575 kill active and disconnected commands for target w/o soft reset
576 Input : pHCB - Pointer to host adapter structure
578 Return : pSRB - Pointer to SCSI request block.
579 *****************************************************************************/
580 int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target)
581 { /* I need Host Control Block Information */
588 spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags);
589 pScb = (ORC_SCB *) NULL;
590 pVirEscb = (ESCB *) NULL;
592 /* setup scatter list address with one buffer */
593 pVirScb = (ORC_SCB *) pHCB->HCS_virScbArray;
597 for (i = 0; i < ORC_MAXQUEUE; i++) {
598 pVirEscb = pVirScb->SCB_EScb;
599 if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt))
604 if (i == ORC_MAXQUEUE) {
605 printk("Unable to Reset - No SCB Found\n");
606 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
609 if ((pScb = orc_alloc_scb(pHCB)) == NULL) {
610 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
613 pScb->SCB_Opcode = ORC_BUSDEVRST;
614 pScb->SCB_Target = target;
615 pScb->SCB_HaStat = 0;
616 pScb->SCB_TaStat = 0;
617 pScb->SCB_Status = 0x0;
618 pScb->SCB_Link = 0xFF;
619 pScb->SCB_Reserved0 = 0;
620 pScb->SCB_Reserved1 = 0;
621 pScb->SCB_XferLen = 0;
624 pVirEscb->SCB_Srb = NULL;
625 pVirEscb->SCB_Srb = SCpnt;
626 orc_exec_scb(pHCB, pScb); /* Start execute SCB */
627 spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
632 /***************************************************************************/
633 ORC_SCB *__orc_alloc_scb(ORC_HCS * hcsp)
641 Ch = hcsp->HCS_Index;
642 for (i = 0; i < 8; i++) {
643 for (index = 0; index < 32; index++) {
644 if ((hcsp->BitAllocFlag[Ch][i] >> index) & 0x01) {
645 hcsp->BitAllocFlag[Ch][i] &= ~(1 << index);
649 idx = index + 32 * i;
650 pTmpScb = (PVOID) ((ULONG) hcsp->HCS_virScbArray + (idx * sizeof(ORC_SCB)));
656 ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp)
661 spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
662 pTmpScb = __orc_alloc_scb(hcsp);
663 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
668 /***************************************************************************/
669 void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
676 spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
677 Ch = hcsp->HCS_Index;
678 Index = scbp->SCB_ScbIdx;
681 hcsp->BitAllocFlag[Ch][i] |= (1 << Index);
682 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
686 /***************************************************************************/
687 void orc_release_dma(ORC_HCS * hcsp, Scsi_Cmnd * SCpnt)
689 struct scatterlist *pSrbSG;
692 pSrbSG = (struct scatterlist *)SCpnt->request_buffer;
693 pci_unmap_sg(hcsp->pdev, pSrbSG, SCpnt->use_sg,
694 scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
695 } else if (SCpnt->request_bufflen != 0) {
696 pci_unmap_single(hcsp->pdev, (U32)SCpnt->host_scribble,
697 SCpnt->request_bufflen,
698 scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
702 /*****************************************************************************
703 Function name : abort_SCB
704 Description : Abort a queued command.
705 (commands that are on the bus can't be aborted easily)
706 Input : pHCB - Pointer to host adapter structure
708 Return : pSRB - Pointer to SCSI request block.
709 *****************************************************************************/
710 int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb)
712 unsigned char bData, bStatus;
714 ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_ABORT_SCB); /* Write command */
715 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
716 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
719 ORC_WR(hcsp->HCS_Base + ORC_HDATA, pScb->SCB_ScbIdx); /* Write address */
720 ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO);
721 if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */
724 if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */
726 bStatus = ORC_RD(hcsp->HCS_Base, ORC_HDATA);
727 ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */
729 if (bStatus == 1) /* 0 - Successfully */
730 return (FALSE); /* 1 - Fail */
734 /*****************************************************************************
735 Function name : inia100_abort
736 Description : Abort a queued command.
737 (commands that are on the bus can't be aborted easily)
738 Input : pHCB - Pointer to host adapter structure
740 Return : pSRB - Pointer to SCSI request block.
741 *****************************************************************************/
742 int orc_abort_srb(ORC_HCS * hcsp, Scsi_Cmnd *SCpnt)
749 spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags);
751 pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
753 for (i = 0; i < ORC_MAXQUEUE; i++, pVirScb++) {
754 pVirEscb = pVirScb->SCB_EScb;
755 if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt)) {
756 if (pVirScb->SCB_TagMsg == 0) {
757 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
760 if (abort_SCB(hcsp, pVirScb)) {
761 pVirEscb->SCB_Srb = NULL;
762 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
765 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
771 spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
775 /***********************************************************************
777 This is the interrupt service routine for the Orchid SCSI adapter.
778 It reads the interrupt register to determine if the adapter is indeed
779 the source of the interrupt and clears the interrupt at the device.
781 HwDeviceExtension - HBA miniport driver's adapter data storage
783 ***********************************************************************/
791 if (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT) == 0) {
796 bScbIdx = ORC_RD(hcsp->HCS_Base, ORC_RQUEUE);
798 pScb = (ORC_SCB *) ((ULONG) hcsp->HCS_virScbArray + (ULONG) (sizeof(ORC_SCB) * bScbIdx));
799 pScb->SCB_Status = 0x0;
801 inia100SCBPost((BYTE *) hcsp, (BYTE *) pScb);
802 } while (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT));
805 } /* End of I1060Interrupt() */