diff options
author | Thomas Bushnell <thomas@gnu.org> | 1999-04-26 05:35:47 +0000 |
---|---|---|
committer | Thomas Bushnell <thomas@gnu.org> | 1999-04-26 05:35:47 +0000 |
commit | 3a4e8f5c1c60f87e1c9e0878ddb6cf7dac8c59c0 (patch) | |
tree | 50b56b8570e175dbcff43b5f0d61103b6fea5906 /i386/i386at/gpl/linux/scsi/qlogic.c | |
parent | 002b9c7d51f7fdb0fe222d4a6023655687c6e501 (diff) | |
download | gnumach-3a4e8f5c1c60f87e1c9e0878ddb6cf7dac8c59c0.tar.gz gnumach-3a4e8f5c1c60f87e1c9e0878ddb6cf7dac8c59c0.tar.bz2 gnumach-3a4e8f5c1c60f87e1c9e0878ddb6cf7dac8c59c0.zip |
1998-11-06 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* i386/i386at/gpl/linux: Moved to ...
* linuxdev: ... here.
* i386/Makefrag: Linux drivers specific code moved to ...
* linuxdev/Makefrag: ... here.
* i386/Files: Recreated.
* i386/Subdirs: Likewise.
* linuxdev/drivers: New directory.
* linuxdev/arch: Likewise.
* linuxdev/arch/i386: Likewise.
* linuxdev/{block,scsi,net,pci}: Moved to ...
* linuxdev/drivers/{block,scsi,net,pci}: ... here.
* i386/{Drivers.in,device-drivers.h.in,driverlist.in}: Moved to ...
* linuxdev/{Drivers.in,device-drivers.h.in,driverlist.in}: ... here.
* linuxdev/{linux_emul.h,linux_*.c}: Moved to ...
* linuxdev/arch/i386/{linux_emul.h,linux_*.c}: ... here.
* linuxdev/arch/i386/linux_block.c: Include <linux_emul.h>, instead
of <i386at/gpl/linux/linux_emul.h>.
* linuxdev/arch/i386/linux_init.c: Likewise.
* linuxdev/arch/i386/linux_kmem.c: Likewise.
* linuxdev/arch/i386/linux_misc.c: Likewise.
* linuxdev/arch/i386/linux_net.c: Likewise.
* linuxdev/arch/i386/linux_sched.c: Likewise.
* device/ds_routines.c: Include <linuxdev/device-drivers.h>, instead
of <i386/device-drivers.h>.
* linuxdev/arch/i386/linux_init.c: Likewise.
* linuxdev/include/linux/autoconf.h: Likewise.
* Makefile.in: Include $(srcdir)/linuxdev/Makefrag.
* linuxdev/Drivers.in (AC_INIT): Use include/linux/autoconf.h,
instead of i386/i386asm.sym.
Diffstat (limited to 'i386/i386at/gpl/linux/scsi/qlogic.c')
-rw-r--r-- | i386/i386at/gpl/linux/scsi/qlogic.c | 678 |
1 files changed, 0 insertions, 678 deletions
diff --git a/i386/i386at/gpl/linux/scsi/qlogic.c b/i386/i386at/gpl/linux/scsi/qlogic.c deleted file mode 100644 index 8333275b..00000000 --- a/i386/i386at/gpl/linux/scsi/qlogic.c +++ /dev/null @@ -1,678 +0,0 @@ -/*----------------------------------------------------------------*/ -/* - Qlogic linux driver - work in progress. No Warranty express or implied. - Use at your own risk. Support Tort Reform so you won't have to read all - these silly disclaimers. - - Copyright 1994, Tom Zerucha. - zerucha@shell.portal.com - - Additional Code, and much appreciated help by - Michael A. Griffith - grif@cs.ucr.edu - - Thanks to Eric Youngdale and Dave Hinds for loadable module and PCMCIA - help respectively, and for suffering through my foolishness during the - debugging process. - - Reference Qlogic FAS408 Technical Manual, 53408-510-00A, May 10, 1994 - (you can reference it, but it is incomplete and inaccurate in places) - - Version 0.43 4/6/95 - kernel 1.2.0+, pcmcia 2.5.4+ - - Functions as standalone, loadable, and PCMCIA driver, the latter from - Dave Hind's PCMCIA package. - - Redistributable under terms of the GNU Public License - -*/ -/*----------------------------------------------------------------*/ -/* Configuration */ - -/* Set the following to 2 to use normal interrupt (active high/totempole- - tristate), otherwise use 0 (REQUIRED FOR PCMCIA) for active low, open - drain */ -#define QL_INT_ACTIVE_HIGH 2 - -/* Set the following to 1 to enable the use of interrupts. Note that 0 tends - to be more stable, but slower (or ties up the system more) */ -#define QL_USE_IRQ 1 - -/* Set the following to max out the speed of the PIO PseudoDMA transfers, - again, 0 tends to be slower, but more stable. */ -#define QL_TURBO_PDMA 1 - -/* This should be 1 to enable parity detection */ -#define QL_ENABLE_PARITY 1 - -/* This will reset all devices when the driver is initialized (during bootup). - The other linux drivers don't do this, but the DOS drivers do, and after - using DOS or some kind of crash or lockup this will bring things back - without requiring a cold boot. It does take some time to recover from a - reset, so it is slower, and I have seen timeouts so that devices weren't - recognized when this was set. */ -#define QL_RESET_AT_START 0 - -/* crystal frequency in megahertz (for offset 5 and 9) - Please set this for your card. Most Qlogic cards are 40 Mhz. The - Control Concepts ISA (not VLB) is 24 Mhz */ -#define XTALFREQ 40 - -/**********/ -/* DANGER! modify these at your own risk */ -/* SLOWCABLE can usually be reset to zero if you have a clean setup and - proper termination. The rest are for synchronous transfers and other - advanced features if your device can transfer faster than 5Mb/sec. - If you are really curious, email me for a quick howto until I have - something official */ -/**********/ - -/*****/ -/* config register 1 (offset 8) options */ -/* This needs to be set to 1 if your cabling is long or noisy */ -#define SLOWCABLE 1 - -/*****/ -/* offset 0xc */ -/* This will set fast (10Mhz) synchronous timing when set to 1 - For this to have an effect, FASTCLK must also be 1 */ -#define FASTSCSI 0 - -/* This when set to 1 will set a faster sync transfer rate */ -#define FASTCLK 0 -/*(XTALFREQ>25?1:0)*/ - -/*****/ -/* offset 6 */ -/* This is the sync transfer divisor, XTALFREQ/X will be the maximum - achievable data rate (assuming the rest of the system is capable - and set properly) */ -#define SYNCXFRPD 5 -/*(XTALFREQ/5)*/ - -/*****/ -/* offset 7 */ -/* This is the count of how many synchronous transfers can take place - i.e. how many reqs can occur before an ack is given. - The maximum value for this is 15, the upper bits can modify - REQ/ACK assertion and deassertion during synchronous transfers - If this is 0, the bus will only transfer asynchronously */ -#define SYNCOFFST 0 -/* for the curious, bits 7&6 control the deassertion delay in 1/2 cycles - of the 40Mhz clock. If FASTCLK is 1, specifying 01 (1/2) will - cause the deassertion to be early by 1/2 clock. Bits 5&4 control - the assertion delay, also in 1/2 clocks (FASTCLK is ignored here). */ - -/*----------------------------------------------------------------*/ -#ifdef PCMCIA -#undef QL_INT_ACTIVE_HIGH -#define QL_INT_ACTIVE_HIGH 0 -#define MODULE -#endif - -#include <linux/module.h> - -#ifdef PCMCIA -#undef MODULE -#endif - -#include <linux/blk.h> /* to get disk capacity */ -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/proc_fs.h> -#include <linux/unistd.h> -#include <asm/io.h> -#include <asm/irq.h> -#include "sd.h" -#include "hosts.h" -#include "qlogic.h" -#include<linux/stat.h> - -struct proc_dir_entry proc_scsi_qlogic = { - PROC_SCSI_QLOGIC, 6, "qlogic", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - -/*----------------------------------------------------------------*/ -/* driver state info, local to driver */ -static int qbase = 0; /* Port */ -static int qinitid; /* initiator ID */ -static int qabort; /* Flag to cause an abort */ -static int qlirq = -1; /* IRQ being used */ -static char qinfo[80]; /* description */ -static Scsi_Cmnd *qlcmd; /* current command being processed */ - -static int qlcfg5 = ( XTALFREQ << 5 ); /* 15625/512 */ -static int qlcfg6 = SYNCXFRPD; -static int qlcfg7 = SYNCOFFST; -static int qlcfg8 = ( SLOWCABLE << 7 ) | ( QL_ENABLE_PARITY << 4 ); -static int qlcfg9 = ( ( XTALFREQ + 4 ) / 5 ); -static int qlcfgc = ( FASTCLK << 3 ) | ( FASTSCSI << 4 ); - -/*----------------------------------------------------------------*/ -/* The qlogic card uses two register maps - These macros select which one */ -#define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd )) -#define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd )) - -/* following is watchdog timeout in microseconds */ -#define WATCHDOG 5000000 - -/*----------------------------------------------------------------*/ -/* the following will set the monitor border color (useful to find - where something crashed or gets stuck at and as a simple profiler) */ - -#if 0 -#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);} -#else -#define rtrc(i) {} -#endif - -/*----------------------------------------------------------------*/ -/* local functions */ -/*----------------------------------------------------------------*/ -static void ql_zap(void); -/* error recovery - reset everything */ -void ql_zap() -{ -int x; -unsigned long flags; - save_flags( flags ); - cli(); - x = inb(qbase + 0xd); - REG0; - outb(3, qbase + 3); /* reset SCSI */ - outb(2, qbase + 3); /* reset chip */ - if (x & 0x80) - REG1; - restore_flags( flags ); -} - -/*----------------------------------------------------------------*/ -/* do pseudo-dma */ -static int ql_pdma(int phase, char *request, int reqlen) -{ -int j; - j = 0; - if (phase & 1) { /* in */ -#if QL_TURBO_PDMA -rtrc(4) - /* empty fifo in large chunks */ - if( reqlen >= 128 && (inb( qbase + 8 ) & 2) ) { /* full */ - insl( qbase + 4, request, 32 ); - reqlen -= 128; - request += 128; - } - while( reqlen >= 84 && !( j & 0xc0 ) ) /* 2/3 */ - if( (j=inb( qbase + 8 )) & 4 ) { - insl( qbase + 4, request, 21 ); - reqlen -= 84; - request += 84; - } - if( reqlen >= 44 && (inb( qbase + 8 ) & 8) ) { /* 1/3 */ - insl( qbase + 4, request, 11 ); - reqlen -= 44; - request += 44; - } -#endif - /* until both empty and int (or until reclen is 0) */ -rtrc(7) - j = 0; - while( reqlen && !( (j & 0x10) && (j & 0xc0) ) ) { - /* while bytes to receive and not empty */ - j &= 0xc0; - while ( reqlen && !( (j=inb(qbase + 8)) & 0x10 ) ) { - *request++ = inb(qbase + 4); - reqlen--; - } - if( j & 0x10 ) - j = inb(qbase+8); - - } - } - else { /* out */ -#if QL_TURBO_PDMA -rtrc(4) - if( reqlen >= 128 && inb( qbase + 8 ) & 0x10 ) { /* empty */ - outsl(qbase + 4, request, 32 ); - reqlen -= 128; - request += 128; - } - while( reqlen >= 84 && !( j & 0xc0 ) ) /* 1/3 */ - if( !((j=inb( qbase + 8 )) & 8) ) { - outsl( qbase + 4, request, 21 ); - reqlen -= 84; - request += 84; - } - if( reqlen >= 40 && !(inb( qbase + 8 ) & 4 ) ) { /* 2/3 */ - outsl( qbase + 4, request, 10 ); - reqlen -= 40; - request += 40; - } -#endif - /* until full and int (or until reclen is 0) */ -rtrc(7) - j = 0; - while( reqlen && !( (j & 2) && (j & 0xc0) ) ) { - /* while bytes to send and not full */ - while ( reqlen && !( (j=inb(qbase + 8)) & 2 ) ) { - outb(*request++, qbase + 4); - reqlen--; - } - if( j & 2 ) - j = inb(qbase+8); - } - } -/* maybe return reqlen */ - return inb( qbase + 8 ) & 0xc0; -} - -/*----------------------------------------------------------------*/ -/* wait for interrupt flag (polled - not real hardware interrupt) */ -static int ql_wai(void) -{ -int i,k; - k = 0; - i = jiffies + WATCHDOG; - while ( i > jiffies && !qabort && !((k = inb(qbase + 4)) & 0xe0)) - barrier(); - if (i <= jiffies) - return (DID_TIME_OUT); - if (qabort) - return (qabort == 1 ? DID_ABORT : DID_RESET); - if (k & 0x60) - ql_zap(); - if (k & 0x20) - return (DID_PARITY); - if (k & 0x40) - return (DID_ERROR); - return 0; -} - -/*----------------------------------------------------------------*/ -/* initiate scsi command - queueing handler */ -static void ql_icmd(Scsi_Cmnd * cmd) -{ -unsigned int i; -unsigned long flags; - - qabort = 0; - - save_flags( flags ); - cli(); - REG0; -/* clearing of interrupts and the fifo is needed */ - inb(qbase + 5); /* clear interrupts */ - if (inb(qbase + 5)) /* if still interrupting */ - outb(2, qbase + 3); /* reset chip */ - else if (inb(qbase + 7) & 0x1f) - outb(1, qbase + 3); /* clear fifo */ - while (inb(qbase + 5)); /* clear ints */ - REG1; - outb(1, qbase + 8); /* set for PIO pseudo DMA */ - outb(0, qbase + 0xb); /* disable ints */ - inb(qbase + 8); /* clear int bits */ - REG0; - outb(0x40, qbase + 0xb); /* enable features */ - -/* configurables */ - outb( qlcfgc , qbase + 0xc); -/* config: no reset interrupt, (initiator) bus id */ - outb( 0x40 | qlcfg8 | qinitid, qbase + 8); - outb( qlcfg7 , qbase + 7 ); - outb( qlcfg6 , qbase + 6 ); -/**/ - outb(qlcfg5, qbase + 5); /* select timer */ - outb(qlcfg9 & 7, qbase + 9); /* prescaler */ -/* outb(0x99, qbase + 5); */ - outb(cmd->target, qbase + 4); - - for (i = 0; i < cmd->cmd_len; i++) - outb(cmd->cmnd[i], qbase + 2); - qlcmd = cmd; - outb(0x41, qbase + 3); /* select and send command */ - restore_flags( flags ); -} -/*----------------------------------------------------------------*/ -/* process scsi command - usually after interrupt */ -static unsigned int ql_pcmd(Scsi_Cmnd * cmd) -{ -unsigned int i, j, k; -unsigned int result; /* ultimate return result */ -unsigned int status; /* scsi returned status */ -unsigned int message; /* scsi returned message */ -unsigned int phase; /* recorded scsi phase */ -unsigned int reqlen; /* total length of transfer */ -struct scatterlist *sglist; /* scatter-gather list pointer */ -unsigned int sgcount; /* sg counter */ - -rtrc(1) - j = inb(qbase + 6); - i = inb(qbase + 5); - if (i == 0x20) { - return (DID_NO_CONNECT << 16); - } - i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */ - if (i != 0x18) { - printk("Ql:Bad Interrupt status:%02x\n", i); - ql_zap(); - return (DID_BAD_INTR << 16); - } - j &= 7; /* j = inb( qbase + 7 ) >> 5; */ -/* correct status is supposed to be step 4 */ -/* it sometimes returns step 3 but with 0 bytes left to send */ -/* We can try stuffing the FIFO with the max each time, but we will get a - sequence of 3 if any bytes are left (but we do flush the FIFO anyway */ - if(j != 3 && j != 4) { - printk("Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n", j, i, inb( qbase+7 ) & 0x1f ); - ql_zap(); - return (DID_ERROR << 16); - } - result = DID_OK; - if (inb(qbase + 7) & 0x1f) /* if some bytes in fifo */ - outb(1, qbase + 3); /* clear fifo */ -/* note that request_bufflen is the total xfer size when sg is used */ - reqlen = cmd->request_bufflen; -/* note that it won't work if transfers > 16M are requested */ - if (reqlen && !((phase = inb(qbase + 4)) & 6)) { /* data phase */ -rtrc(2) - outb(reqlen, qbase); /* low-mid xfer cnt */ - outb(reqlen >> 8, qbase+1); /* low-mid xfer cnt */ - outb(reqlen >> 16, qbase + 0xe); /* high xfer cnt */ - outb(0x90, qbase + 3); /* command do xfer */ -/* PIO pseudo DMA to buffer or sglist */ - REG1; - if (!cmd->use_sg) - ql_pdma(phase, cmd->request_buffer, cmd->request_bufflen); - else { - sgcount = cmd->use_sg; - sglist = cmd->request_buffer; - while (sgcount--) { - if (qabort) { - REG0; - return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16); - } - if (ql_pdma(phase, sglist->address, sglist->length)) - break; - sglist++; - } - } - REG0; -rtrc(2) -/* wait for irq (split into second state of irq handler if this can take time) */ - if ((k = ql_wai())) - return (k << 16); - k = inb(qbase + 5); /* should be 0x10, bus service */ - } -/*** Enter Status (and Message In) Phase ***/ - k = jiffies + WATCHDOG; - while ( k > jiffies && !qabort && !(inb(qbase + 4) & 6)); /* wait for status phase */ - if ( k <= jiffies ) { - ql_zap(); - return (DID_TIME_OUT << 16); - } - while (inb(qbase + 5)); /* clear pending ints */ - if (qabort) - return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16); - outb(0x11, qbase + 3); /* get status and message */ - if ((k = ql_wai())) - return (k << 16); - i = inb(qbase + 5); /* get chip irq stat */ - j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */ - status = inb(qbase + 2); - message = inb(qbase + 2); -/* should get function complete int if Status and message, else bus serv if only status */ - if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) { - printk("Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j); - result = DID_ERROR; - } - outb(0x12, qbase + 3); /* done, disconnect */ -rtrc(1) - if ((k = ql_wai())) - return (k << 16); -/* should get bus service interrupt and disconnect interrupt */ - i = inb(qbase + 5); /* should be bus service */ - while (!qabort && ((i & 0x20) != 0x20)) { - barrier(); - i |= inb(qbase + 5); - } -rtrc(0) - if (qabort) - return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16); - return (result << 16) | (message << 8) | (status & STATUS_MASK); -} - -#if QL_USE_IRQ -/*----------------------------------------------------------------*/ -/* interrupt handler */ -static void ql_ihandl(int irq, struct pt_regs * regs) -{ -Scsi_Cmnd *icmd; - REG0; - if (!(inb(qbase + 4) & 0x80)) /* false alarm? */ - return; - if (qlcmd == NULL) { /* no command to process? */ - int i; - i = 16; - while (i-- && inb(qbase + 5)); /* maybe also ql_zap() */ - return; - } - icmd = qlcmd; - icmd->result = ql_pcmd(icmd); - qlcmd = NULL; -/* if result is CHECK CONDITION done calls qcommand to request sense */ - (icmd->scsi_done) (icmd); -} -#endif - -/*----------------------------------------------------------------*/ -/* global functions */ -/*----------------------------------------------------------------*/ -/* non queued command */ -#if QL_USE_IRQ -static void qlidone(Scsi_Cmnd * cmd) {}; /* null function */ -#endif - -/* command process */ -int qlogic_command(Scsi_Cmnd * cmd) -{ -int k; -#if QL_USE_IRQ - if (qlirq >= 0) { - qlogic_queuecommand(cmd, qlidone); - while (qlcmd != NULL); - return cmd->result; - } -#endif -/* non-irq version */ - if (cmd->target == qinitid) - return (DID_BAD_TARGET << 16); - ql_icmd(cmd); - if ((k = ql_wai())) - return (k << 16); - return ql_pcmd(cmd); - -} - -#if QL_USE_IRQ -/*----------------------------------------------------------------*/ -/* queued command */ -int qlogic_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) -{ - if(cmd->target == qinitid) { - cmd->result = DID_BAD_TARGET << 16; - done(cmd); - return 0; - } - - cmd->scsi_done = done; -/* wait for the last command's interrupt to finish */ - while (qlcmd != NULL) - barrier(); - ql_icmd(cmd); - return 0; -} -#else -int qlogic_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) -{ - return 1; -} -#endif - -#ifdef PCMCIA -/*----------------------------------------------------------------*/ -/* allow PCMCIA code to preset the port */ -/* port should be 0 and irq to -1 respectively for autoprobing */ -void qlogic_preset(int port, int irq) -{ - qbase=port; - qlirq=irq; -} -#endif - -/*----------------------------------------------------------------*/ -/* look for qlogic card and init if found */ -int qlogic_detect(Scsi_Host_Template * host) -{ -int i, j; /* these are only used by IRQ detect */ -int qltyp; /* type of chip */ -struct Scsi_Host *hreg; /* registered host structure */ -unsigned long flags; - -host->proc_dir = &proc_scsi_qlogic; - -/* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself decodes the - address - I check 230 first since MIDI cards are typically at 330 - - Theoretically, two Qlogic cards can coexist in the same system. This - should work by simply using this as a loadable module for the second - card, but I haven't tested this. -*/ - - if( !qbase ) { - for (qbase = 0x230; qbase < 0x430; qbase += 0x100) { - if( check_region( qbase , 0x10 ) ) - continue; - REG1; - if ( ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 ) - && ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 ) ) - break; - } - if (qbase == 0x430) - return 0; - } - else - printk( "Ql: Using preset base address of %03x\n", qbase ); - - qltyp = inb(qbase + 0xe) & 0xf8; - qinitid = host->this_id; - if (qinitid < 0) - qinitid = 7; /* if no ID, use 7 */ - outb(1, qbase + 8); /* set for PIO pseudo DMA */ - REG0; - outb(0x40 | qlcfg8 | qinitid, qbase + 8); /* (ini) bus id, disable scsi rst */ - outb(qlcfg5, qbase + 5); /* select timer */ - outb(qlcfg9, qbase + 9); /* prescaler */ -#if QL_RESET_AT_START - outb( 3 , qbase + 3 ); - REG1; - while( inb( qbase + 0xf ) & 4 ); - REG0; -#endif -#if QL_USE_IRQ -/* IRQ probe - toggle pin and check request pending */ - - if( qlirq == -1 ) { - save_flags( flags ); - cli(); - i = 0xffff; - j = 3; - outb(0x90, qbase + 3); /* illegal command - cause interrupt */ - REG1; - outb(10, 0x20); /* access pending interrupt map */ - outb(10, 0xa0); - while (j--) { - outb(0xb0 | QL_INT_ACTIVE_HIGH , qbase + 0xd); /* int pin off */ - i &= ~(inb(0x20) | (inb(0xa0) << 8)); /* find IRQ off */ - outb(0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd); /* int pin on */ - i &= inb(0x20) | (inb(0xa0) << 8); /* find IRQ on */ - } - REG0; - while (inb(qbase + 5)); /* purge int */ - j = -1; - while (i) /* find on bit */ - i >>= 1, j++; /* should check for exactly 1 on */ - qlirq = j; - restore_flags( flags ); - } - else - printk( "Ql: Using preset IRQ %d\n", qlirq ); - - if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogic")) - host->can_queue = 1; -#endif - request_region( qbase , 0x10 ,"qlogic"); - hreg = scsi_register( host , 0 ); /* no host data */ - hreg->io_port = qbase; - hreg->n_io_port = 16; - hreg->dma_channel = -1; - if( qlirq != -1 ) - hreg->irq = qlirq; - - sprintf(qinfo, "Qlogic Driver version 0.43, chip %02X at %03X, IRQ %d, TPdma:%d", - qltyp, qbase, qlirq, QL_TURBO_PDMA ); - host->name = qinfo; - - return 1; -} - -/*----------------------------------------------------------------*/ -/* return bios parameters */ -int qlogic_biosparam(Disk * disk, kdev_t dev, int ip[]) -{ -/* This should mimic the DOS Qlogic driver's behavior exactly */ - ip[0] = 0x40; - ip[1] = 0x20; - ip[2] = disk->capacity / (ip[0] * ip[1]); - if (ip[2] > 1024) { - ip[0] = 0xff; - ip[1] = 0x3f; - ip[2] = disk->capacity / (ip[0] * ip[1]); - if (ip[2] > 1023) - ip[2] = 1023; - } - return 0; -} - -/*----------------------------------------------------------------*/ -/* abort command in progress */ -int qlogic_abort(Scsi_Cmnd * cmd) -{ - qabort = 1; - ql_zap(); - return 0; -} - -/*----------------------------------------------------------------*/ -/* reset SCSI bus */ -int qlogic_reset(Scsi_Cmnd * cmd) -{ - qabort = 2; - ql_zap(); - return 1; -} - -/*----------------------------------------------------------------*/ -/* return info string */ -const char *qlogic_info(struct Scsi_Host * host) -{ - return qinfo; -} - -#ifdef MODULE -/* Eventually this will go into an include file, but this will be later */ -Scsi_Host_Template driver_template = QLOGIC; - -#include "scsi_module.c" -#endif |